]> git.donarmstrong.com Git - lilypond.git/commitdiff
Provides a pure height conversion for Beam::rest_collision_callback.
authorMike Solomon <mike@apollinemike.com>
Sun, 21 Aug 2011 15:16:20 +0000 (17:16 +0200)
committerMike Solomon <mike@apollinemike.com>
Sun, 21 Aug 2011 15:16:20 +0000 (17:16 +0200)
This prevents horizontal collisions between beamed rests and their
beamed neighbors.

input/regression/beam-rest-extreme.ly [new file with mode: 0644]
lily/beam.cc
lily/include/beam.hh
lily/rest.cc
scm/define-grobs.scm

diff --git a/input/regression/beam-rest-extreme.ly b/input/regression/beam-rest-extreme.ly
new file mode 100644 (file)
index 0000000..770bd78
--- /dev/null
@@ -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'' {
+  <f b c f>16[ r <f bes c f> <f b c f>]
+  <f b c f>16[ r <f'' bes c f> <f b c f>]
+  <f b c f>16[ r <f,, bes c f> <f b c f>]
+  <f'' b c f>16[ r <f bes c f> <f b c f>]
+}
index 2d973246cf0ebf75a6c5147b09e7e32d261b6f25..9fd53474629389fdebd721e50103f5e3a3feed15 100644 (file)
@@ -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<Grob *> 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)
 {
index d89c35d6b2c98241dc884374f8b6fc222943e838..f99fbf8028e2ac3cb0f428dbb3394a9156a927c3 100644 (file)
@@ -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));
index 97deba3f8fc93b41cce9767f0a17b851bcafe301..0115e5176fbbf56921767051b0389b85ab84eee2 100644 (file)
@@ -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);
 }
index bfe0323b8fd5a2318dbda52cd5041919e447e482..6a482d102d18ce9634ffc03fc224689cc5f37706 100644 (file)
     (,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)