From: Mike Solomon Date: Sun, 21 Aug 2011 15:16:20 +0000 (+0200) Subject: Provides a pure height conversion for Beam::rest_collision_callback. X-Git-Tag: release/2.15.9-1~9^2~32 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=49ef4f0ee42f1e1e8078aefa30bed9712fa482c6;p=lilypond.git Provides a pure height conversion for Beam::rest_collision_callback. This prevents horizontal collisions between beamed rests and their beamed neighbors. --- diff --git a/input/regression/beam-rest-extreme.ly b/input/regression/beam-rest-extreme.ly new file mode 100644 index 0000000000..770bd78939 --- /dev/null +++ b/input/regression/beam-rest-extreme.ly @@ -0,0 +1,14 @@ +\version "2.15.9" + +\header { + texidoc = "Beamed rests are given a pure height approximation +that gets their spacing correct in the majority of circumstances. +" +} + +\relative c'' { + 16[ r ] + 16[ r ] + 16[ r ] + 16[ r ] +} diff --git a/lily/beam.cc b/lily/beam.cc index 2d973246cf..9fd5347462 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -54,6 +54,7 @@ #include "pointer-group-interface.hh" #include "rhythmic-head.hh" #include "spanner.hh" +#include "staff-symbol.hh" #include "staff-symbol-referencer.hh" #include "stem.hh" #include "warn.hh" @@ -1731,6 +1732,77 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset) return scm_from_double (offset + staff_space * shift); } +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 */) +{ + Real amount = 0.0; + + Grob *me = unsmob_grob (smob); + Grob *stem = unsmob_grob (me->get_object ("stem")); + if (!stem) + return scm_from_double (amount); + Grob *beam = unsmob_grob (stem->get_object ("beam")); + if (!beam + || !Beam::normal_stem_count (beam)) + return scm_from_double (amount); + + 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. + */ + 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; + + extract_grob_set (beam, "stems", stems); + vector my_stems; + + for (vsize i = 0; i < stems.size (); i++) + if (Stem::head_count (stems[i]) || stems[i] == stem) + my_stems.push_back (stems[i]); + + vsize idx = -1; + + for (vsize i = 0; i < my_stems.size (); i++) + if (my_stems[i] == stem) + { + idx = i; + break; + } + Grob *left; + Grob *right; + + if (idx == -1 || my_stems.size () == 1) + return scm_from_double (amount); + else if (idx == 0) + left = right = my_stems[1]; + else if (idx == my_stems.size () - 1) + left = right = my_stems[idx - 1]; + else + { + 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); +} + + bool Beam::is_knee (Grob *me) { diff --git a/lily/include/beam.hh b/lily/include/beam.hh index d89c35d6b2..f99fbf8028 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -71,6 +71,7 @@ public: static Interval no_visible_stem_positions (Grob *me, Interval default_value); 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 (print, (SCM)); DECLARE_SCHEME_CALLBACK (calc_beaming, (SCM)); DECLARE_SCHEME_CALLBACK (calc_stem_shorten, (SCM)); diff --git a/lily/rest.cc b/lily/rest.cc index 97deba3f8f..0115e5176f 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -52,7 +52,8 @@ Rest::y_offset_callback (SCM smob) amount += ss / 2; if (!position_override) - amount += 2 * ss * get_grob_direction (me);; + amount += 2 * ss * get_grob_direction (me); + return scm_from_double (amount); } diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index bfe0323b8f..6a482d102d 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -2615,6 +2615,7 @@ (,ly:accidental-interface::height . ,ly:accidental-interface::pure-height) (,ly:axis-group-interface::calc-staff-staff-spacing . ,ly:axis-group-interface::calc-pure-staff-staff-spacing) (,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height) + (,ly:beam::rest-collision-callback . ,ly:beam::pure-rest-collision-callback) (,ly:grob::stencil-height . ,pure-stencil-height) (,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height) (,ly:rest-collision::force-shift-callback-rest . ,pure-chain-offset-callback)