]> git.donarmstrong.com Git - lilypond.git/commitdiff
improve initial estimate of beamed-rest position; issue 472
authorKeith OHara <k-ohara5a5a@oco.net>
Mon, 17 Nov 2014 06:13:24 +0000 (22:13 -0800)
committerKeith OHara <k-ohara5a5a@oco.net>
Thu, 27 Nov 2014 07:06:28 +0000 (23:06 -0800)
input/regression/beam-rest-extreme.ly
lily/beam.cc

index 9c7d5df3b99d6684bd477aa6b90b2159393709ad..4dccd6b394d5f4a929b11028e5c8b83d3b62074b 100644 (file)
@@ -10,5 +10,5 @@ that gets their spacing correct in the majority of circumstances.
   <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>]
+  <f, b c f>16[ r <f bes c f> <f b c f>]
 }
index 3d9db725016778fb6e906bb35e2fe68f9395ec7c..548daf612e9fdafae2194c7cd773e170b8cac2e3 100644 (file)
@@ -1301,7 +1301,7 @@ Beam::rest_collision_callback (SCM smob, SCM prev_offset)
 
 /*
   Estimate the position of a rest under a beam,
-  as the average position of its neighboring heads.
+  using the average position of its neighboring heads.
 */
 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, pure_rest_collision_callback, 4, 1, "");
 SCM
@@ -1324,15 +1324,6 @@ Beam::pure_rest_collision_callback (SCM smob,
 
   Real ss = Staff_symbol_referencer::staff_space (me);
 
-  /*
-    This gives the extrema of rest positions.
-    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 (2);
-
   extract_grob_set (beam, "stems", stems);
   vector<Grob *> my_stems;
 
@@ -1363,24 +1354,26 @@ Beam::pure_rest_collision_callback (SCM smob,
       right = my_stems[idx + 1];
     }
 
-  /* In stems with several heads, use the one closest to the beam. */
+  /* Estimate the closest beam to be four positions away from the heads, */
   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;
-
-  // So that ceil below kicks in for rests that would otherwise brush
-  // up against a beam quanted to a ledger line, add a bit of space
-  // between the beam and the rest.
-  shift += (0.01 * beamdir);
-
-  /* Always move by a whole number of staff spaces */
-  shift = ceil (fabs (shift / ss)) * ss * sign (shift);
-
-  return scm_from_double (previous + shift);
+  Real beam_pos = (Stem::head_positions (left)[beamdir]
+                   + Stem::head_positions (right)[beamdir]) / 2.0
+                  + 4.0 * beamdir; // four staff-positions
+  /* and that the closest beam never crosses staff center by more than two positions */
+  beam_pos = max (-2.0, beam_pos * beamdir) * beamdir;
+
+  Real minimum_distance
+    = ss * (robust_scm2double (stem->get_property ("stemlet-length"), 0.0)
+            + robust_scm2double (me->get_property ("minimum-distance"), 0.0));
+  Real offset = beam_pos * ss / 2.0
+                - minimum_distance * beamdir
+                - me->extent (me, Y_AXIS)[beamdir];
+
+  /* Always move by a whole number of staff spaces, always away from the beam */
+  offset = floor (min (0.0, (offset - previous) / ss * beamdir))
+           * ss * beamdir + previous;
+
+  return scm_from_double (offset);
 }
 
 bool