From 2a872121379fffe7b1cd5d23048b7ea04b4d1f68 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Benk=C5=91=20P=C3=A1l?= Date: Sun, 13 May 2012 18:07:40 +0200 Subject: [PATCH] line_count fixes 1. implementation does not assume staff centred at zero 2. where used for determining whether something falls on a line, use Staff_symbol_referencer::on_line or on_staff_line 3. where used for determining whether something is within staff or not, use Staff_symbol_referencer::staff_span --- .../regression/ledger-lines-varying-staves.ly | 6 +- input/regression/non-centered-bar-lines.ly | 1 + input/regression/staff-ledger-positions.ly | 2 +- input/regression/staff-line-positions.ly | 4 +- input/regression/zero-staff-space.ly | 2 +- lily/bar-line.cc | 65 +++++++++++++++++-- lily/beam.cc | 12 ++-- lily/breathing-sign.cc | 34 +++++----- lily/custos.cc | 3 +- lily/rest-collision.cc | 13 ++-- lily/rest.cc | 3 +- lily/slur-scoring.cc | 3 +- lily/time-signature.cc | 32 ++++++++- lily/vaticana-ligature.cc | 3 +- 14 files changed, 124 insertions(+), 59 deletions(-) diff --git a/input/regression/ledger-lines-varying-staves.ly b/input/regression/ledger-lines-varying-staves.ly index e037de7f79..2f8db819a1 100644 --- a/input/regression/ledger-lines-varying-staves.ly +++ b/input/regression/ledger-lines-varying-staves.ly @@ -7,9 +7,9 @@ for a variety of staves using both @code{line-count} and notes = \relative c' { \time 3/4 - c2. | d | e | f - g2. | a | b | c - d2. | e | f | g + c2. | d | e | f \bar ":|" + g2. | a | b | c \bar "|:" + d2. | e | f | g \bar ":|:" a2. } diff --git a/input/regression/non-centered-bar-lines.ly b/input/regression/non-centered-bar-lines.ly index 429fc41915..f12fb98503 100644 --- a/input/regression/non-centered-bar-lines.ly +++ b/input/regression/non-centered-bar-lines.ly @@ -8,5 +8,6 @@ staves which are not centered around position@tie{}0. \override Staff.StaffSymbol #'line-positions = #'(1 3 5 7 9) c''1 \bar "||" c''1 \bar ":" + c''1 \bar ":|" c''1 \bar "|." } diff --git a/input/regression/staff-ledger-positions.ly b/input/regression/staff-ledger-positions.ly index 67233d1060..7cf8fb000d 100644 --- a/input/regression/staff-ledger-positions.ly +++ b/input/regression/staff-ledger-positions.ly @@ -13,5 +13,5 @@ later by setting the @code{ledger-extra} property." \override Staff.StaffSymbol #'line-positions = #'(-5 -2 -1 2 5 6) \override Staff.StaffSymbol #'ledger-positions = #'(-5 (-2 -1) 2) \override Staff.StaffSymbol #'ledger-extra = #1 - g,4 c e b' c'' e g + g,4 c e b' \bar ":|" c'' e g } diff --git a/input/regression/staff-line-positions.ly b/input/regression/staff-line-positions.ly index 0b801a8744..1e3ee81be1 100644 --- a/input/regression/staff-line-positions.ly +++ b/input/regression/staff-line-positions.ly @@ -11,7 +11,5 @@ \new Staff \relative c' { \override Staff.StaffSymbol #'line-positions = #'(-7 -2 0 3 9) - g c f b e a + g c f b \bar ":|" e a } - - diff --git a/input/regression/zero-staff-space.ly b/input/regression/zero-staff-space.ly index 62e2e16bc9..fc1c162c06 100644 --- a/input/regression/zero-staff-space.ly +++ b/input/regression/zero-staff-space.ly @@ -10,6 +10,6 @@ Setting staff-space to 0 does not cause a segmentation fault. \override StaffSymbol #'staff-space = #0 } { \relative c' { - c1 + c1 \bar ":|" } } diff --git a/lily/bar-line.cc b/lily/bar-line.cc index 0cd0339235..7da72ba321 100644 --- a/lily/bar-line.cc +++ b/lily/bar-line.cc @@ -25,8 +25,12 @@ #include "lookup.hh" #include "output-def.hh" #include "paper-column.hh" +#include "staff-symbol.hh" #include "staff-symbol-referencer.hh" +#include + + MAKE_SCHEME_CALLBACK (Bar_line, calc_bar_extent, 1) SCM Bar_line::calc_bar_extent (SCM smob) @@ -112,15 +116,62 @@ Bar_line::compound_barline (Grob *me, string str, Interval const &extent, Stencil thick = simple_barline (me, fatline, extent, rounded); Stencil dot = Font_interface::get_default_font (me)->find_by_name ("dots.dot"); - int lines = Staff_symbol_referencer::line_count (me); - Real dist - = ((lines & 1 || lines == 0) - ? 1 - : (staff_space < 2 ? 2 : .5)) * staff_space; + /* + the two dots of the repeat sign should be centred at the middle of + the staff and both should avoid staff lines + */ + Real centre = 0.0, dist = 1.0; + if (staff_space) + { + if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me)) + { + std::vector linepos = Staff_symbol::line_positions (staff); + if (!linepos.empty ()) + { + centre = Staff_symbol::line_span (staff).center (); + + /* + fold the staff into two at centre and find the first gap + big enough to hold a dot and some space below and above + */ + std::set half_staff; + half_staff.insert (0.0); + for (std::vector::const_iterator + i = linepos.begin (), e = linepos.end (); + i != e; + ++i) + half_staff.insert (fabs (*i - centre)); + + /* + gap is measured like line-positions; + 1.0 for dot diameter, twice the staffline width for the + gap above and below and one more staffline width for the + two half stafflines + */ + Real const gap_to_find = (1.0 + 3 * staffline) / staff_space; + dist = *half_staff.rbegin () * 2 + gap_to_find; + for (std::set::const_iterator + i0 = half_staff.begin (), i1 = i0, e = half_staff.end (); + ++i1 != e; + i0 = i1) + if (*i1 - *i0 > gap_to_find) + { + dist = *i0 + *i1; + break; + } + } + } + } + else + dist += 3 * staffline; + + if (staff_space == 0.0) + staff_space = 1.0; + Stencil colon (dot); - colon.translate_axis (dist, Y_AXIS); + colon.translate_axis (dist * staff_space / 2, Y_AXIS); colon.add_stencil (dot); - colon.translate_axis (-dist / 2, Y_AXIS); + colon.translate_axis ((centre - dist / 2) * staff_space / 2, Y_AXIS); Real const h = extent.length (); Stencil m; diff --git a/lily/beam.cc b/lily/beam.cc index 49253434c0..d73169a917 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -675,7 +675,7 @@ Beam::print (SCM grob) // we need two translations: the normal one and // the one of the lowest segment - int idx[] = {i, extreme}; + size_t idx[] = {i, extreme}; Real translations[2]; for (int j = 0; j < 2; j++) @@ -1274,16 +1274,16 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset) Real shift = d * min (d * (beam_y - d * minimum_distance - rest_dim), 0.0); shift /= staff_space; - Real rad = Staff_symbol_referencer::line_count (rest) * staff_space / 2; /* Always move discretely by half spaces */ shift = ceil (fabs (shift * 2.0)) / 2.0 * sign (shift); + Interval staff_span = Staff_symbol_referencer::staff_span (rest); + staff_span *= staff_space / 2; + /* Inside staff, move by whole spaces*/ - if ((rest_extent[d] + staff_space * shift) * d - < rad - || (rest_extent[-d] + staff_space * shift) * -d - < rad) + if (staff_span.contains (rest_extent[d] + staff_space * shift) + || staff_span.contains (rest_extent[-d] + staff_space * shift)) shift = ceil (fabs (shift)) * sign (shift); return scm_from_double (offset + staff_space * shift); diff --git a/lily/breathing-sign.cc b/lily/breathing-sign.cc index a3d9637bef..02b29858af 100644 --- a/lily/breathing-sign.cc +++ b/lily/breathing-sign.cc @@ -81,13 +81,19 @@ Breathing_sign::divisio_maior (SCM smob) * more than half the size of the staff, such that the endings of * the line are in the middle of a staff space. */ - int lines = Staff_symbol_referencer::line_count (me); - int height = lines / 2; // little more than half of staff size - if ((lines & 1) != (height & 1)) - height++; // ensure endings are centered in staff space + Interval ydim = Staff_symbol_referencer::staff_span (me); + ydim.widen (-0.25 * ydim.delta ()); + for (UP_and_DOWN (i)) + { + int const int_dim = (int) ydim[i]; + if (int_dim == ydim[i] + && Staff_symbol_referencer::on_staff_line (me, int_dim)) + ydim[i] += i; + } + + ydim *= 1.0 / Staff_symbol_referencer::staff_space (me); Interval xdim (0, thickness); - Interval ydim (-0.5 * height, +0.5 * height); Box b (xdim, ydim); Stencil out = Lookup::round_filled_box (b, blotdiameter); return out.smobbed_copy (); @@ -102,20 +108,15 @@ Breathing_sign::divisio_maxima (SCM smob) { Grob *me = unsmob_grob (smob); Real staff_space = Staff_symbol_referencer::staff_space (me); - Real staff_size; Real thickness = Staff_symbol_referencer::line_thickness (me); thickness *= robust_scm2double (me->get_property ("thickness"), 1.0); - if (Staff_symbol_referencer::get_staff_symbol (me)) - staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space; - else - staff_size = 0.0; - Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); // like a "|" type bar Interval xdim (0, thickness); - Interval ydim (-0.5 * staff_size, +0.5 * staff_size); + Interval ydim = Staff_symbol_referencer::staff_span (me); + ydim *= staff_space / 2; Box b (xdim, ydim); Stencil out = Lookup::round_filled_box (b, blotdiameter); return out.smobbed_copy (); @@ -130,20 +131,15 @@ Breathing_sign::finalis (SCM smob) { Grob *me = unsmob_grob (smob); Real staff_space = Staff_symbol_referencer::staff_space (me); - Real staff_size; Real thickness = Staff_symbol_referencer::line_thickness (me); thickness *= robust_scm2double (me->get_property ("thickness"), 1.0); - if (Staff_symbol_referencer::get_staff_symbol (me)) - staff_size = (Staff_symbol_referencer::line_count (me) - 1) * staff_space; - else - staff_size = 0.0; - Real blotdiameter = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); // like a "||" type bar Interval xdim (0, thickness); - Interval ydim (-0.5 * staff_size, +0.5 * staff_size); + Interval ydim = Staff_symbol_referencer::staff_span (me); + ydim *= staff_space / 2; Box b (xdim, ydim); Stencil line1 = Lookup::round_filled_box (b, blotdiameter); Stencil line2 (line1); diff --git a/lily/custos.cc b/lily/custos.cc index 00da1d53d1..1366202f72 100644 --- a/lily/custos.cc +++ b/lily/custos.cc @@ -62,7 +62,6 @@ Custos::print (SCM smob) = to_dir (me->get_property ("neutral-direction")); int pos = Staff_symbol_referencer::get_rounded_position (me); - int sz = Staff_symbol_referencer::line_count (me) - 1; string font_char = "custodes." + style + "."; if (pos < neutral_pos) @@ -77,7 +76,7 @@ Custos::print (SCM smob) font_char += "d"; if (adjust) - font_char += (((pos ^ sz) & 0x1) == 0) ? "1" : "0"; + font_char += Staff_symbol_referencer::on_line (me, pos) ? "1" : "0"; else font_char += "2"; diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index 8ba647e201..0e7a01c5a7 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -250,19 +250,14 @@ Rest_collision::calc_positioning_done (SCM smob) Real y = dir * max (0.0, -dir * restdim[-dir] + dir * notedim[dir] + minimum_dist); - int stafflines = Staff_symbol_referencer::line_count (me); - if (!stafflines) - { - programming_error ("no staff line count"); - stafflines = 5; - } - // move discretely by half spaces. int discrete_y = dir * int (ceil (y / (0.5 * dir * staff_space))); + Interval staff_span = Staff_symbol_referencer::staff_span (rest); + staff_span.widen (1); // move by whole spaces inside the staff. - if (fabs (Staff_symbol_referencer::get_position (rest) - + discrete_y) < stafflines + 1) + if (staff_span.contains + (Staff_symbol_referencer::get_position (rest) + discrete_y)) { discrete_y = dir * int (ceil (dir * discrete_y / 2.0) * 2.0); } diff --git a/lily/rest.cc b/lily/rest.cc index 9057e45af1..8e45405de2 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -37,7 +37,6 @@ Rest::y_offset_callback (SCM smob) { Grob *me = unsmob_grob (smob); int duration_log = scm_to_int (me->get_property ("duration-log")); - int line_count = Staff_symbol_referencer::line_count (me); Real ss = Staff_symbol_referencer::staff_space (me); bool position_override = scm_is_number (me->get_property ("staff-position")); @@ -69,7 +68,7 @@ Rest::y_offset_callback (SCM smob) make a semibreve rest hang from the next line, except for a single line staff */ - if (duration_log == 0 && line_count > 1) + if (duration_log == 0 && Staff_symbol_referencer::line_count (me) > 1) pos += 2; /* diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index eaadde5c58..9e50984243 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -590,8 +590,7 @@ Slur_score_state::move_away_from_staffline (Real y, * 2.0 / staff_space_; if (fabs (pos - my_round (pos)) < 0.2 - && Staff_symbol_referencer::on_line (on_staff, (int) rint (pos)) - && Staff_symbol_referencer::line_count (on_staff) - 1 >= rint (pos)) + && Staff_symbol_referencer::on_staff_line (on_staff, (int) rint (pos))) y += 1.5 * staff_space_ * dir_ / 10; return y; diff --git a/lily/time-signature.cc b/lily/time-signature.cc index ad553e4229..082b62a93c 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -23,6 +23,7 @@ #include "font-interface.hh" #include "international.hh" #include "output-def.hh" +#include "staff-symbol.hh" #include "staff-symbol-referencer.hh" #include "text-interface.hh" #include "warn.hh" @@ -57,8 +58,35 @@ Time_signature::print (SCM smob) else m = numbered_time_signature (me, n, d); - if (Staff_symbol_referencer::line_count (me) % 2 == 0) - m.translate_axis (Staff_symbol_referencer::staff_space (me) / 2, Y_AXIS); + /* + position the signature centred on the staff line + nearest to the middle of the staff + */ + if (Grob *staff = Staff_symbol_referencer::get_staff_symbol (me)) + { + std::vector const linepos = Staff_symbol::line_positions (staff); + if (!linepos.empty ()) + { + Interval const span = Staff_symbol::line_span (staff); + Real const mid = span.center (); + Real pos = linepos.front (); + Real dist = fabs (pos - mid); + for (std::vector::const_iterator + i = linepos.begin (), e = linepos.end (); + ++i != e;) + { + double const d = fabs (*i - mid); + if (d < dist) + { + pos = *i; + dist = d; + } + } + + m.translate_axis + (pos * Staff_symbol_referencer::staff_space (me) / 2, Y_AXIS); + } + } return m.smobbed_copy (); } diff --git a/lily/vaticana-ligature.cc b/lily/vaticana-ligature.cc index 7420db3ec1..deb0218bd0 100644 --- a/lily/vaticana-ligature.cc +++ b/lily/vaticana-ligature.cc @@ -37,8 +37,7 @@ vaticana_brew_cauda (Grob *me, Real blotdiameter) { bool on_staffline = Staff_symbol_referencer::on_line (me, pos); - int interspaces = Staff_symbol_referencer::line_count (me) - 1; - bool above_staff = pos > interspaces; + bool above_staff = pos > Staff_symbol_referencer::staff_span (me)[UP]; if (delta_pitch > -1) { -- 2.39.2