]> git.donarmstrong.com Git - lilypond.git/commitdiff
Stopes nested tuplets from colliding (issue 1855).
authorMike Solomon <mike@apollinemike.com>
Fri, 30 Sep 2011 00:48:49 +0000 (02:48 +0200)
committerMike Solomon <mike@apollinemike.com>
Fri, 30 Sep 2011 00:48:49 +0000 (02:48 +0200)
Currently uses the `padding' property to space out nested tuplets.
This is the same property used to space tuplets from other objects
they encompass.

input/regression/tuplet-nest-broken.ly [new file with mode: 0644]
input/regression/tuplet-nest.ly
lily/include/tuplet-bracket.hh
lily/tuplet-bracket.cc
lily/tuplet-number.cc
scm/define-grob-properties.scm
scm/define-grobs.scm

diff --git a/input/regression/tuplet-nest-broken.ly b/input/regression/tuplet-nest-broken.ly
new file mode 100644 (file)
index 0000000..06e105c
--- /dev/null
@@ -0,0 +1,53 @@
+
+\version "2.15.9"
+
+\header {
+    texidoc = "Broken nested tuplets avoid each other correctly.
+"
+}
+
+\paper {
+  ragged-right = ##t
+  indent = 0.0
+}
+
+\score {
+  \new Staff
+  <<
+    \relative c'' {
+      \override Score . Beam #'breakable = ##t
+
+      r2
+
+      \times 4/3 {
+        \times 2/3 { c8[ c c] }
+        \times 2/3 { c8[ c c] }
+        \times 2/3 { c8[ c c] }
+      }
+
+      \times 4/3 {
+        \times 2/3 { a8[ a a] }
+        \times 2/3 { a8[ a a] }
+        \times 2/3 { a8[ a a] }
+      }
+
+      \override TupletNumber #'text = #tuplet-number::calc-fraction-text
+      \times 4/6 {
+        \times 2/3 {
+          a4 a a
+        }
+        \times 3/5 {
+          a4 a a a a
+        }
+        a4
+      }
+      r2
+    }
+    { \repeat unfold 3 { s1 \break } }
+  >>
+  \layout {
+    \context {
+      \Voice \remove Forbid_line_break_engraver
+    }
+  }
+}
index dfdd543450bf13c3793e3b29671dd2213db49f61..a0a1810398bf8a299b6ab3b6cb1ebeaa09aa34ae 100644 (file)
 }
 
 \relative c'' {
+  \times 4/3 {
+    \times 2/3 { c8[ c c] }
+    \times 2/3 { c8[ c c] }
+    \times 2/3 { c8[ c c] }
+  }
+
+  \times 4/3 {
+    \times 2/3 { a8[ a a] }
+    \times 2/3 { a8[ a a] }
+    \times 2/3 { a8[ a a] }
+  }
+
   \override TupletNumber #'text = #tuplet-number::calc-fraction-text
   \times 4/6 {
     \times 2/3 {
-      a a a
+      a4 a a
     }
     \times 3/5 {
-      a a a a a
+      a4 a a a a
     }
   }
 
index ceeb7f3440c15c883bdb1b9f6c41db2e51807fea..617758cc66944c16c8166db5f74249f6bb4826c2 100644 (file)
@@ -29,7 +29,7 @@ class Tuplet_bracket
 public:
   DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_positions, (SCM));
-  DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_x_positions, (SCM));
   DECLARE_SCHEME_CALLBACK (print, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_connect_to_neighbors, (SCM smob));
   DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM));
index 627d6fcfb04a961e531e7ee9aabd6bc3ae2afc34..b2c67cbb18d27d5df1b1288f90ced5c86621f057 100644 (file)
@@ -51,6 +51,7 @@
 #include "note-column.hh"
 #include "pointer-group-interface.hh"
 #include "directional-element-interface.hh"
+#include "skyline.hh"
 #include "spanner.hh"
 #include "staff-symbol-referencer.hh"
 #include "lookup.hh"
@@ -180,24 +181,13 @@ Tuplet_bracket::get_common_x (Spanner *me)
   return commonx;
 }
 
-MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_control_points, 1)
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_x_positions, 1)
 SCM
-Tuplet_bracket::calc_control_points (SCM smob)
+Tuplet_bracket::calc_x_positions (SCM smob)
 {
   Spanner *me = unsmob_spanner (smob);
-
   extract_grob_set (me, "note-columns", columns);
 
-  SCM scm_positions = me->get_property ("positions");
-  if (!me->is_live ())
-    return SCM_EOL;
-
-  if (!scm_is_pair (scm_positions))
-    programming_error ("Positions should be number pair");
-
-  Drul_array<Real> positions
-    = robust_scm2drul (scm_positions, Drul_array<Real> (0, 0));
-
   Grob *commonx = get_common_x (me);
   Direction dir = get_grob_direction (me);
 
@@ -254,9 +244,7 @@ Tuplet_bracket::calc_control_points (SCM smob)
     }
   while (flip (&d) != LEFT);
 
-  x_span -= me->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS);
-  return scm_list_2 (ly_offset2scm (Offset (x_span[LEFT], positions[LEFT])),
-                     ly_offset2scm (Offset (x_span[RIGHT], positions[RIGHT])));
+  return ly_interval2scm (x_span - me->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS));
 }
 
 /*
@@ -290,10 +278,11 @@ Tuplet_bracket::print (SCM smob)
 
   /*
     Don't print a tuplet bracket and number if
-    no control-points were calculated
+    no X or Y positions were calculated.
   */
-  SCM cpoints = me->get_property ("control-points");
-  if (scm_ilength (cpoints) < 2)
+  SCM scm_x_span = me->get_property ("X-positions");
+  SCM scm_positions = me->get_property ("positions");
+  if (!scm_is_pair (scm_x_span) || !scm_is_pair (scm_positions))
     {
       me->suicide ();
       return SCM_EOL;
@@ -307,12 +296,14 @@ Tuplet_bracket::print (SCM smob)
           == robust_scm2moment (me->get_bound (RIGHT)->get_column ()->get_property ("when"), Moment (0))))
     bracket_visibility = false;
 
-  Drul_array<Offset> points;
-  points[LEFT] = ly_scm2offset (scm_car (cpoints));
-  points[RIGHT] = ly_scm2offset (scm_cadr (cpoints));
+  Interval x_span = robust_scm2interval (scm_x_span, Interval (0.0, 0.0));
+  Interval positions = robust_scm2interval (scm_positions, Interval (0.0, 0.0));
 
-  Interval x_span (points[LEFT][X_AXIS], points[RIGHT][X_AXIS]);
-  Drul_array<Real> positions (points[LEFT][Y_AXIS], points[RIGHT][Y_AXIS]);
+  Drul_array<Offset> points;
+  Direction d = LEFT;
+  do
+    points[d] = Offset (x_span[d], positions[d]);
+  while (flip (&d) != LEFT);
 
   Output_def *pap = me->layout ();
 
@@ -657,6 +648,11 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
           points.push_back (Offset (tuplet_x[d] - x0, y));
         }
       while (flip (&d) != LEFT);
+      // Check for number-on-bracket collisions
+      Grob *number = unsmob_grob (tuplets[i]->get_object ("tuplet-number"));
+      if (number)
+        points.push_back (Offset (number->extent (commonx, X_AXIS).center () - x0,
+                                                  number->extent (commony, Y_AXIS)[dir]));
     }
 
   *offset = -dir * infinity_f;
@@ -820,7 +816,6 @@ ADD_INTERFACE (Tuplet_bracket,
                "bracket-visibility "
                "break-overshoot "
                "connect-to-neighbor "
-               "control-points "
                "direction "
                "edge-height "
                "edge-text "
@@ -835,4 +830,5 @@ ADD_INTERFACE (Tuplet_bracket,
                "staff-padding "
                "thickness "
                "tuplets "
+               "X-positions "
               );
index 2972942ee346169e681908f838fa31b618d4afd8..aaa862395d7163651e74918e45622b9e61e1820d 100644 (file)
 struct Tuplet_number
 {
   DECLARE_SCHEME_CALLBACK (print, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_x_offset, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_y_offset, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM));
   DECLARE_GROB_INTERFACE ();
+
+  static Real calc_offset (Spanner *me, Axis a);
 };
 
 MAKE_SCHEME_CALLBACK (Tuplet_number, print, 1);
@@ -51,20 +55,32 @@ Tuplet_number::print (SCM smob)
   stc->align_to (X_AXIS, CENTER);
   stc->align_to (Y_AXIS, CENTER);
 
-  SCM cpoints = tuplet->get_property ("control-points");
-  Drul_array<Offset> points;
-  if (scm_is_pair (cpoints))
-    {
-      points[LEFT] = ly_scm2offset (scm_car (cpoints));
-      points[RIGHT] = ly_scm2offset (scm_cadr (cpoints));
-    }
-  else
-    {
-      programming_error ("wrong type for control-points");
-    }
-  stc->translate ((points[RIGHT] + points[LEFT]) / 2);
+  return stc->smobbed_copy ();
+}
+
+MAKE_SCHEME_CALLBACK (Tuplet_number, calc_x_offset, 1);
+SCM
+Tuplet_number::calc_x_offset (SCM smob)
+{
+  Spanner *me = unsmob_spanner (smob);
+  Spanner *tuplet = unsmob_spanner (me->get_object ("bracket"));
+
+  Interval x_positions = robust_scm2interval (tuplet->get_property ("X-positions"), Interval (0.0, 0.0));
+
+  return scm_from_double (x_positions.center ());
+}
+
+MAKE_SCHEME_CALLBACK (Tuplet_number, calc_y_offset, 1);
+SCM
+Tuplet_number::calc_y_offset (SCM smob)
+{
+
+  Spanner *me = unsmob_spanner (smob);
+  Spanner *tuplet = unsmob_spanner (me->get_object ("bracket"));
+
+  Interval positions = robust_scm2interval (tuplet->get_property ("positions"), Interval (0.0, 0.0));
 
-  return stc_scm;
+  return scm_from_double (positions.center ());
 }
 
 MAKE_SCHEME_CALLBACK (Tuplet_number, calc_cross_staff, 1)
index a78ce0e9bb4d894d3ce8364e8ed4857bec1ae819..eea44eed4df130d569d3f38d8bd8a3f1b6e3f9b6 100644 (file)
@@ -939,6 +939,9 @@ texts.")
      (X-extent ,number-pair? "Hard coded extent in X@tie{}direction.")
      (X-offset ,number? "The horizontal amount that this object is
 moved relative to its X-parent.")
+     (X-positions ,number-pair? "Pair of X staff coordinates of a spanner
+in the form @code{(@var{left} . @var{right})}, where both @var{left} and
+@var{right} are in @code{staff-space} units of the current staff.")
 
 
 ;;
index c8764e15e07be47c8677dcdf6e98036fc94dd7c7..5e551acf8f3cdad946c128bf9b4bde6636009c0c 100644 (file)
        ;; a tuplet bracket.
 
        (connect-to-neighbor . ,ly:tuplet-bracket::calc-connect-to-neighbors)
-       (control-points . ,ly:tuplet-bracket::calc-control-points)
        (direction . ,UP)
        (edge-height . (0.7 . 0.7))
        (padding . 2.0)
        (staff-padding . 0.25)
        (stencil . ,ly:tuplet-bracket::print)
        (thickness . 1.6)
+       (X-positions . ,ly:tuplet-bracket::calc-x-positions)
        (meta . ((class . Spanner)
                 (interfaces . (line-interface
                                tuplet-bracket-interface))))))
     (TupletBracket
      . (
        (connect-to-neighbor . ,ly:tuplet-bracket::calc-connect-to-neighbors)
-       (control-points . ,ly:tuplet-bracket::calc-control-points)
        (cross-staff . ,ly:tuplet-bracket::calc-cross-staff)
        (direction  . ,ly:tuplet-bracket::calc-direction)
        (edge-height . (0.7 . 0.7))
        (staff-padding . 0.25)
        (stencil . ,ly:tuplet-bracket::print)
        (thickness . 1.6)
+       (X-positions . ,ly:tuplet-bracket::calc-x-positions)
 
        (meta . ((class . Spanner)
                 (interfaces . (line-interface
        (font-size . -2)
        (stencil . ,ly:tuplet-number::print)
        (text . ,tuplet-number::calc-denominator-text)
+       (X-offset . ,ly:tuplet-number::calc-x-offset)
+       (Y-offset . ,ly:tuplet-number::calc-y-offset)
        (meta . ((class . Spanner)
                 (interfaces . (font-interface
                                text-interface