]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix arpeggio overshoot for some chords which reach centre line.
authorNeil Puttock <n.puttock@gmail.com>
Tue, 7 Oct 2008 20:34:05 +0000 (21:34 +0100)
committerNeil Puttock <n.puttock@gmail.com>
Tue, 7 Oct 2008 20:34:05 +0000 (21:34 +0100)
This patch fixes a rounding error in Arpeggio::print () that occurs when a
chord reaches the centre line, resulting in an extra squiggle being added.

input/regression/arpeggio-no-overshoot.ly [new file with mode: 0644]
lily/arpeggio.cc

diff --git a/input/regression/arpeggio-no-overshoot.ly b/input/regression/arpeggio-no-overshoot.ly
new file mode 100644 (file)
index 0000000..ec47ee1
--- /dev/null
@@ -0,0 +1,15 @@
+\version "2.11.62"
+
+\header {
+  texidoc = "Arpeggios do not overshoot the highest note head.
+The first chord in this example simulates overshoot using
+@code{'positions} for comparison with the correct behaviour."
+}
+
+\relative c' {
+  % simulate overshoot for comparison
+  \once \override Arpeggio #'positions = #'(-3 . 1)
+  <c e g b>1\arpeggio
+  <c e g b>1\arpeggio
+  <f a c>2\arpeggio <g b d f>\arpeggio
+}
index 80858426bc6eb43bc7f12e2f77a83aec4351d8b3..22351d3b13f3d56a8d640dc730737d2b39d58b31 100644 (file)
@@ -97,6 +97,16 @@ Arpeggio::print (SCM smob)
   Font_metric *fm = Font_interface::get_default_font (me);
   Stencil squiggle = fm->find_by_name ("scripts.arpeggio");
 
+  /*
+    Compensate for rounding error which may occur when a chord
+    reaches the center line, resulting in an extra squiggle
+    being added to the arpeggio stencil.  This value is appreciably
+    larger than the rounding error, which is in the region of 1e-16
+    for a global-staff-size of 20, but small enough that it does not
+    interfere with smaller staff sizes.
+  */
+  const Real epsilon = 1e-3;
+
   Stencil arrow;
   if (dir)
     {
@@ -104,9 +114,10 @@ Arpeggio::print (SCM smob)
       heads[dir] -= dir * arrow.extent (Y_AXIS).length ();
     }
 
-  for (Real y = heads[LEFT]; y < heads[RIGHT];
-       y += squiggle.extent (Y_AXIS).length ())
-    mol.add_at_edge (Y_AXIS, UP, squiggle, 0.0);
+  while (mol.extent (Y_AXIS).length () + epsilon < heads.length ())
+    {
+      mol.add_at_edge (Y_AXIS, UP, squiggle, 0.0);
+    }
 
   mol.translate_axis (heads[LEFT], Y_AXIS);
   if (dir)