From ee3b120133df8db47f3c9bd1453cb1da6e1b87cb Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sat, 7 Jan 2006 02:34:56 +0000 Subject: [PATCH] * lily/bar-line.cc (calc_bar_size): inspect staff->extent (Y_AXIS) for determining bar size. * lily/staff-symbol.cc (print): place lines at distance line-positions * lily/staff-symbol.cc (height): new function. --- lily/bar-line.cc | 14 ++----- lily/include/staff-symbol.hh | 3 +- lily/ledger-line-spanner.cc | 53 ++++++++++++++++---------- lily/staff-symbol.cc | 74 +++++++++++++++++++++++++++++++----- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/lily/bar-line.cc b/lily/bar-line.cc index 3295c1d40e..ec91336621 100644 --- a/lily/bar-line.cc +++ b/lily/bar-line.cc @@ -158,18 +158,10 @@ SCM Bar_line::calc_bar_size (SCM smob) { Grob *me = unsmob_grob (smob); - Real ss = Staff_symbol_referencer::staff_space (me); - - if (Staff_symbol_referencer::get_staff_symbol (me)) + if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me)) { - /* - If there is no staff-symbol, we get -1 from the next - calculation. That's a nonsense value, which would collapse the - barline so we return 0.0 in the next alternative. - */ - Real ysize = (Staff_symbol_referencer::line_count (me) -1); - ysize = ysize * ss + Staff_symbol_referencer::line_thickness (me); - return scm_from_double (ysize); + Interval staff_y = staff->extent (staff, Y_AXIS); + return scm_from_double (staff_y.is_empty () ? 0.0 : staff_y.length ()); } return scm_from_int (0); } diff --git a/lily/include/staff-symbol.hh b/lily/include/staff-symbol.hh index 59232e19a7..edf3a0f532 100644 --- a/lily/include/staff-symbol.hh +++ b/lily/include/staff-symbol.hh @@ -21,10 +21,11 @@ public: static Real staff_space (Grob *); static Real get_line_thickness (Grob *); static Real get_ledger_line_thickness (Grob *); - + static int get_steps (Grob *); static int line_count (Grob *); DECLARE_SCHEME_CALLBACK (print, (SCM)); + DECLARE_SCHEME_CALLBACK (height, (SCM)); static bool has_interface (Grob *); }; #endif // STAFF_SYMBOL_HH diff --git a/lily/ledger-line-spanner.cc b/lily/ledger-line-spanner.cc index 1bca089b14..5076d303e5 100644 --- a/lily/ledger-line-spanner.cc +++ b/lily/ledger-line-spanner.cc @@ -24,7 +24,7 @@ struct Ledger_line_spanner DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM)); static Stencil brew_ledger_lines (Grob *me, int pos, - int interspaces, + Interval, Real, Real, Interval x_extent, Real left_shorten); @@ -35,15 +35,15 @@ struct Ledger_line_spanner Stencil Ledger_line_spanner::brew_ledger_lines (Grob *staff, int pos, - int interspaces, + Interval staff_extent, Real halfspace, Real ledgerlinethickness, Interval x_extent, Real left_shorten) { - int line_count = ((abs (pos) < interspaces) + int line_count = (staff_extent.contains (pos) ? 0 - : (abs (pos) - interspaces) / 2); + : sign (pos) * int (rint(pos - staff_extent[Direction (sign (pos))])) / 2); Stencil stencil; if (line_count) { @@ -129,8 +129,11 @@ Ledger_line_spanner::set_spacing_rods (SCM smob) Item *previous_column = 0; Item *current_column = 0; - int interspaces = Staff_symbol::line_count (staff) - 1; + Real halfspace = Staff_symbol::staff_space (staff) / 2; + Interval staff_extent = staff->extent (staff, Y_AXIS); + staff_extent *= 1 / halfspace; + /* Run through heads using a loop. Since Ledger_line_spanner can contain a lot of noteheads, superlinear performance is too slow. @@ -141,7 +144,7 @@ Ledger_line_spanner::set_spacing_rods (SCM smob) Item *h = heads[i]; int pos = Staff_symbol_referencer::get_rounded_position (h); - if (abs (pos) <= interspaces) + if (staff_extent.contains (pos)) continue; Item *column = h->get_column (); @@ -211,6 +214,11 @@ Ledger_line_spanner::print (SCM smob) if (!staff) return SCM_EOL; + Real halfspace = Staff_symbol::staff_space (staff) / 2; + + Interval staff_extent = staff->extent (staff, Y_AXIS); + staff_extent *= 1 / halfspace; + Real length_fraction = robust_scm2double (me->get_property ("length-fraction"), 0.25); @@ -228,15 +236,13 @@ Ledger_line_spanner::print (SCM smob) common[a] = common[a]->common_refpoint (g, a); } - int interspaces = Staff_symbol::line_count (staff) - 1; Ledger_requests reqs; for (int i = heads.size (); i--;) { Item *h = dynamic_cast (heads[i]); int pos = Staff_symbol_referencer::get_rounded_position (h); - if (pos - && abs (pos) > interspaces) + if (pos && !staff_extent.contains (pos)) { Interval head_extent = h->extent (common[X_AXIS], X_AXIS); Interval ledger_extent = head_extent; @@ -264,8 +270,8 @@ Ledger_line_spanner::print (SCM smob) Direction d = DOWN; do { - if (abs (last->second[d].position_) > interspaces - && abs (i->second[d].position_) > interspaces) + if (!staff_extent.contains (last->second[d].position_) + && !staff_extent.contains (i->second[d].position_)) { Real center = (last->second[d].head_extent_[RIGHT] @@ -277,10 +283,12 @@ Ledger_line_spanner::print (SCM smob) Ledger_request &lr = ((which == LEFT) ? * last : *i).second[d]; // due tilt of quarter note-heads + /* FIXME */ bool both - = (abs (last->second[d].position_) > interspaces + 1 - && abs (i->second[d].position_) > interspaces + 1); - + = (!staff_extent.contains (last->second[d].position_ + - sign (last->second[d].position_)) + && !staff_extent.contains (i->second[d].position_ + - sign (i->second[d].position_))); Real limit = (center + (both ? which * gap / 2 : 0)); lr.ledger_extent_.elem_ref (-which) = which * max (which * lr.ledger_extent_[-which], which * limit); @@ -291,22 +299,22 @@ Ledger_line_spanner::print (SCM smob) while (flip (&d) != DOWN); } - // create ledgers for note heads + // create ledgers for note heads Real ledgerlinethickness = Staff_symbol::get_ledger_line_thickness (staff); - Real halfspace = Staff_symbol::staff_space (staff) / 2; for (int i = heads.size (); i--;) { Item *h = dynamic_cast (heads[i]); int pos = Staff_symbol_referencer::get_rounded_position (h); - if (abs (pos) > interspaces + 1) + if (!staff_extent.contains (pos - sign (pos))) { Interval head_size = h->extent (common[X_AXIS], X_AXIS); Interval ledger_size = head_size; ledger_size.widen (ledger_size.length () * length_fraction); - Interval max_size = reqs[h->get_column ()->get_rank ()][Direction (sign (pos))].ledger_extent_; + Interval max_size = reqs[h->get_column ()->get_rank ()] + [Direction (sign (pos))].ledger_extent_; ledger_size.intersect (max_size); Real left_shorten = 0.0; @@ -326,7 +334,7 @@ Ledger_line_spanner::print (SCM smob) */ } - ledgers.add_stencil (brew_ledger_lines (staff, pos, interspaces, + ledgers.add_stencil (brew_ledger_lines (staff, pos, staff_extent, halfspace, ledgerlinethickness, ledger_size, @@ -347,7 +355,12 @@ ADD_INTERFACE (Ledger_line_spanner, "This is a separate grob because it has to process\n" "all potential collisions between all note heads.", - "note-heads thickness minimum-length-fraction length-fraction gap"); + /* properties */ + "note-heads " + "thickness " + "minimum-length-fraction " + "length-fraction " + "gap"); struct Ledgered_interface { diff --git a/lily/staff-symbol.cc b/lily/staff-symbol.cc index ddbf2829a6..aa9596bfdd 100644 --- a/lily/staff-symbol.cc +++ b/lily/staff-symbol.cc @@ -65,24 +65,41 @@ Staff_symbol::print (SCM smob) } while (flip (&d) != LEFT); - int l = Staff_symbol::line_count (me); + Stencil m; - Real height = (l - 1) * staff_space (me) / 2; - Stencil a + SCM line_positions = me->get_property ("line-positions"); + Stencil line = Lookup::horizontal_line (span_points -me->relative_coordinate (common, X_AXIS), t); - Stencil m; - for (int i = 0; i < l; i++) + Real space = staff_space (me); + if (scm_is_pair (line_positions)) + { + for (SCM s = line_positions; scm_is_pair (s); + s = scm_cdr (s)) + { + Stencil b (line); + b.translate_axis (scm_to_double (scm_car (s)) + * 0.5 * space, Y_AXIS); + m.add_stencil (b); + } + } + else { - Stencil b (a); - b.translate_axis (height - i * staff_space (me), Y_AXIS); - m.add_stencil (b); + int l = Staff_symbol::line_count (me); + Real height = (l - 1) * staff_space (me) / 2; + for (int i = 0; i < l; i++) + { + Stencil b (line); + b.translate_axis (height - i * space, Y_AXIS); + m.add_stencil (b); + } } return m.smobbed_copy (); } + int Staff_symbol::get_steps (Grob *me) { @@ -122,6 +139,37 @@ Staff_symbol::get_ledger_line_thickness (Grob *me) return z[X_AXIS] * get_line_thickness (me) + z[Y_AXIS] * staff_space (me); } +MAKE_SCHEME_CALLBACK(Staff_symbol,height,1); +SCM +Staff_symbol::height (SCM smob) +{ + Grob *me = unsmob_grob (smob); + Real t = me->layout ()->get_dimension (ly_symbol2scm ("linethickness")); + t *= robust_scm2double (me->get_property ("thickness"), 1.0); + + SCM line_positions = me->get_property ("line-positions"); + + Interval y_ext; + Real space = staff_space (me); + if (scm_is_pair (line_positions)) + { + for (SCM s = line_positions; scm_is_pair (s); + s = scm_cdr (s)) + y_ext.add_point (scm_to_double (scm_car (s)) * 0.5 * space); + } + else + { + int l = Staff_symbol::line_count (me); + Real height = (l - 1) * staff_space (me) / 2; + y_ext = Interval (-height, height); + } + y_ext.widen (t/2); + return ly_interval2scm (y_ext); +} + + + + ADD_INTERFACE (Staff_symbol, "staff-symbol-interface", "This spanner draws the lines of a staff. " "A staff symbol definines a vertical unit, the staff space. " @@ -130,4 +178,12 @@ ADD_INTERFACE (Staff_symbol, "staff-symbol-interface", "or space) is position 0. The length of the symbol may be set by hand " "through the @code{width} property. ", - "ledger-line-thickness width staff-space thickness line-count"); + + /* properties */ + "ledger-line-thickness " + "line-count " + "line-positions " + "staff-space " + "thickness " + "width " + ); -- 2.39.5