From 1a05e9cc253d99b49eefa25ef1021232da2b3862 Mon Sep 17 00:00:00 2001 From: Keith OHara Date: Sat, 21 Apr 2012 23:57:23 -0700 Subject: [PATCH] pure-rest-collision-callback: Remain on staff lines; issue 2468 Same as f5abf75fb0a62527ea1c6339861aee34b210cc24, but with correct argument-passing order. --- input/regression/dot-column-rest-collision.ly | 8 ++-- lily/beam.cc | 43 +++++++++++-------- lily/include/beam.hh | 2 +- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/input/regression/dot-column-rest-collision.ly b/input/regression/dot-column-rest-collision.ly index 3419f7304f..49f811ce37 100644 --- a/input/regression/dot-column-rest-collision.ly +++ b/input/regression/dot-column-rest-collision.ly @@ -1,10 +1,12 @@ \header { - texidoc = "Dot columns do not trigger beam slanting too early." + texidoc = "Dot columns do not trigger beam slanting too early. +This input should compile with no programming error message, +and the dots should be correctly placed on their rests." } \version "2.14.0" \paper{ ragged-right=##t } << - { e''8 e''8 g'' g''} \\ - { e8 r4. } + { e''8 e'' g'' g'' g''16[ r8. r8. g''16] } \\ + { e8 r4. c'16[ r8. 8. e'16] } >> diff --git a/lily/beam.cc b/lily/beam.cc index e2d1293187..49253434c0 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -1289,36 +1289,39 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset) return scm_from_double (offset + staff_space * shift); } +/* + Estimate the position of a rest under a beam, + as the average position of its neighboring heads. +*/ MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, pure_rest_collision_callback, 4, 1, ""); SCM Beam::pure_rest_collision_callback (SCM smob, - SCM, /* prev_offset */ SCM, /* start */ - SCM /* end */) + SCM, /* end */ + SCM prev_offset) { - Real amount = 0.0; + Real previous = robust_scm2double (prev_offset, 0.0); Grob *me = unsmob_grob (smob); Grob *stem = unsmob_grob (me->get_object ("stem")); if (!stem) - return scm_from_double (amount); + return scm_from_double (previous); Grob *beam = unsmob_grob (stem->get_object ("beam")); if (!beam || !Beam::normal_stem_count (beam) || !is_direction (beam->get_property_data ("direction"))) - return scm_from_double (amount); + return scm_from_double (previous); Real ss = Staff_symbol_referencer::staff_space (me); /* This gives the extrema of rest positions. - In general, beams are never typeset more than one staff space away - from the staff in either direction. + Even with noteheads on ledgers, beams typically remain within the staff, + and push rests at most one staff-space (2 positions) from the staff. */ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); Interval rest_max_pos = staff ? Staff_symbol::line_span (staff) : Interval (0.0, 0.0); - rest_max_pos.widen (1); - rest_max_pos *= ss / 2; + rest_max_pos.widen (2); extract_grob_set (beam, "stems", stems); vector my_stems; @@ -1339,7 +1342,7 @@ Beam::pure_rest_collision_callback (SCM smob, Grob *right; if (idx == (vsize) - 1 || my_stems.size () == 1) - return scm_from_double (amount); + return scm_from_double (previous); else if (idx == 0) left = right = my_stems[1]; else if (idx == my_stems.size () - 1) @@ -1349,15 +1352,19 @@ Beam::pure_rest_collision_callback (SCM smob, left = my_stems[idx - 1]; right = my_stems[idx + 1]; } - Direction beamdir = get_grob_direction (beam); - /* - Take the position between the two bounding head_positions, - then bound it by the minimum and maximum positions outside the staff. - 4.0 = 2.0 to get out of staff space * 2.0 for the average - */ - amount = min (max ((Stem::head_positions (left)[beamdir] + Stem::head_positions (right)[beamdir]) / 4.0, rest_max_pos[DOWN]), rest_max_pos[UP]); - return scm_from_double (amount); + /* In stems with several heads, use the one closest to the beam. */ + Direction beamdir = get_grob_direction (beam); + Real shift = min (max ( (Stem::head_positions (left)[beamdir] + + Stem::head_positions (right)[beamdir]) / 2.0, + rest_max_pos[DOWN]), + rest_max_pos[UP] + ) * ss / 2.0 + - previous; + /* Always move by a whole number of staff spaces */ + shift = ceil (fabs (shift / ss)) * ss * sign (shift); + + return scm_from_double (previous + shift); } bool diff --git a/lily/include/beam.hh b/lily/include/beam.hh index 5c60e14c80..116ae6aa57 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -70,7 +70,7 @@ public: static vector get_beam_segments (Grob *me_grob, Grob **common); DECLARE_SCHEME_CALLBACK (rest_collision_callback, (SCM element, SCM prev_off)); - DECLARE_SCHEME_CALLBACK (pure_rest_collision_callback, (SCM element, SCM prev_off, SCM, SCM)); + DECLARE_SCHEME_CALLBACK (pure_rest_collision_callback, (SCM element, SCM, SCM, SCM prev_off)); DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (calc_beaming, (SCM)); DECLARE_SCHEME_CALLBACK (calc_stem_shorten, (SCM)); -- 2.39.2