]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/tuplet-bracket.cc
Merge branch 'jneeman' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond into jneeman
[lilypond.git] / lily / tuplet-bracket.cc
index 8246f400f9400ef2a13a0e76505b7b0036e423ce..d13cf1c613e50d7103533c0f9c779334e73008cb 100644 (file)
@@ -44,6 +44,8 @@
 #include "spanner.hh"
 #include "staff-symbol-referencer.hh"
 #include "lookup.hh"
+#include "paper-column.hh"
+#include "moment.hh"
 
 static Item *
 get_x_bound_item (Grob *me_grob, Direction hdir, Direction my_dir)
@@ -64,15 +66,21 @@ flatten_number_pair_property (Grob *me,
                              Direction xdir,  SCM sym)
 {
   Drul_array<Real> zero (0, 0);
-  Drul_array<Real> pair = robust_scm2drul (me->internal_get_property (sym), zero);
+  Drul_array<Real> pair
+    = robust_scm2drul (me->internal_get_property (sym), zero);
   pair[xdir] = 0.0;
   
-  me->internal_set_property (sym, ly_interval2scm (pair));
+  me->set_property (sym, ly_interval2scm (pair));
 }
 
 
+/*
+  Return beam that encompasses the span of the tuplet bracket.
+*/
+
 Grob *
-Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols, bool *equally_long)
+Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols,
+                              bool *equally_long)
 {
   Spanner *me = dynamic_cast<Spanner *> (me_grob);
 
@@ -105,7 +113,9 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols, bool *e
       return 0;
     }
 
-  *equally_long = (beam_stems[0] == stems[LEFT] && beam_stems.back () == stems[RIGHT]);
+  *equally_long =
+    (beam_stems[0] == stems[LEFT]
+     && beam_stems.back () == stems[RIGHT]);
   return beams[LEFT];
 }
 
@@ -174,8 +184,15 @@ Tuplet_bracket::calc_control_points (SCM 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
-    = ly_scm2realdrul (me->get_property ("positions"));
+    = robust_scm2drul (scm_positions, Drul_array<Real> (0,0));
 
   Grob *commonx = get_common_x (me);
   Direction dir = get_grob_direction (me);
@@ -206,12 +223,16 @@ Tuplet_bracket::calc_control_points (SCM smob)
            x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[RIGHT]
              - overshoot[LEFT];
        }
+      
       else if (d == RIGHT
               && (columns.empty ()
                   || (bounds[d]->get_column ()
                       != dynamic_cast<Item *> (columns.back ())->get_column ())))
        {
          /*
+           We're connecting to a column, for the last bit of a broken
+           fullLength bracket.
+           
            TODO: make padding tunable?
          */
          Real padding = 1.0;
@@ -219,7 +240,9 @@ Tuplet_bracket::calc_control_points (SCM smob)
          if (bounds[d]->break_status_dir ())
            padding = 0.0;
          
-         x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT] - padding;
+         x_span[d]
+           = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT]
+           - padding;
        }
     }
   while (flip (&d) != LEFT);
@@ -397,15 +420,14 @@ Tuplet_bracket::make_bracket (Grob *me, // for line properties.
   Direction d = LEFT;
   do
     straight_corners[d] += -d * shorten[d] / length * dz;
-  while (flip (&d) != LEFT)
-    ;
+  while (flip (&d) != LEFT);
 
-  if (gap.is_empty ())
-    gap = Interval (0, 0);
-  do
-    gap_corners[d] = (dz * 0.5) + gap[d] / length * dz;
-  while (flip (&d) != LEFT)
-    ;
+  if (!gap.is_empty ())
+    {
+      do
+       gap_corners[d] = (dz * 0.5) + gap[d] / length * dz;
+      while (flip (&d) != LEFT);
+    }
 
   Drul_array<Offset> flare_corners = straight_corners;
   do
@@ -419,14 +441,20 @@ Tuplet_bracket::make_bracket (Grob *me, // for line properties.
   Stencil m;
   do
     {
-      m.add_stencil (Line_interface::line (me, straight_corners[d],
-                                          gap_corners[d]));
+      if (!gap.is_empty ())
+       m.add_stencil (Line_interface::line (me, straight_corners[d],
+                                            gap_corners[d]));
 
       m.add_stencil (Line_interface::line (me, straight_corners[d],
                                           flare_corners[d]));
     }
+
   while (flip (&d) != LEFT);
 
+  if (gap.is_empty ())
+    m.add_stencil (Line_interface::line (me, straight_corners[LEFT],
+                                        straight_corners[RIGHT]));
+  
   return m;
 }
 
@@ -438,16 +466,16 @@ Tuplet_bracket::get_bounds (Grob *me, Grob **left, Grob **right)
   while (l < columns.size () && Note_column::has_rests (columns[l]))
     l++;
 
-  vsize r = columns.size () - 1;
-  while (r >= l && Note_column::has_rests (columns[r]))
+  vsize r = columns.size ();
+  while (r > l && Note_column::has_rests (columns[r-1]))
     r--;
 
   *left = *right = 0;
 
-  if (l <= r)
+  if (l < r)
     {
       *left = columns[l];
-      *right = columns[r];
+      *right = columns[r-1];
     }
 }
 
@@ -545,8 +573,12 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       Interval tuplet_x (tuplets[i]->extent (commonx, X_AXIS));
       Interval tuplet_y (tuplets[i]->extent (commony, Y_AXIS));
 
+      if (!tuplets[i]->is_live ())
+       continue;
+      
       Direction d = LEFT;
-      Drul_array<Real> positions = ly_scm2realdrul (tuplets[i]->get_property ("positions"));
+      Drul_array<Real> positions = robust_scm2interval (tuplets[i]->get_property ("positions"),
+                                                       Interval (0,0));
 
       
       Real other_dy = positions[RIGHT] - positions[LEFT];
@@ -556,19 +588,11 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
          Real y
            = tuplet_y.linear_combination (d * sign (other_dy));
 
-#if 0
          /*
-           Let's not take padding into account for nested tuplets.
+           We don't take padding into account for nested tuplets.
            the edges can come very close to the stems, likewise for
            nested tuplets?
          */
-         Drul_array<Real> my_height
-           = robust_scm2drul (me->get_property ("edge-height"),
-                              Interval (0, 0));
-         if (dynamic_cast<Spanner *> (tuplets[i])->get_bound (d)
-             == me->get_bound (d))
-           y += dir * my_height[d];
-#endif
 
          points.push_back (Offset (tuplet_x[d] - x0, y));
        }
@@ -622,9 +646,20 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_positions, 1);
 SCM
 Tuplet_bracket::calc_positions (SCM smob)
 {
-  Grob *me = unsmob_grob (smob);
+  Spanner *me = unsmob_spanner (smob);
   extract_grob_set (me, "note-columns", columns);
 
+  /*
+    Don't print if it doesn't span time.
+   */
+  if (robust_scm2moment (me->get_bound (LEFT)->get_column ()->get_property ("when"), Moment (0))
+      == robust_scm2moment (me->get_bound (RIGHT)->get_column ()->get_property ("when"), Moment (0)))
+    {
+      me->suicide ();
+      return SCM_EOL;
+    }
+
+  
   Direction dir = get_grob_direction (me);
   bool equally_long = false;
   Grob *par_beam = parallel_beam (me, columns, &equally_long);
@@ -637,20 +672,29 @@ Tuplet_bracket::calc_positions (SCM smob)
   if (!par_beam
       || get_grob_direction (par_beam) != dir)
     calc_position_and_height (me, &offset, &dy);
-  else
+  else if  (columns.size ()
+           && Note_column::get_stem (columns[0])
+           && Note_column::get_stem (columns.back ()))
     {
-      SCM ps = par_beam->get_property ("positions");
+      /*
+       trigger set_stem_ends
+       */
+      (void) par_beam->get_property ("quantized-positions");
 
-      Real lp = scm_to_double (scm_car (ps));
-      Real rp = scm_to_double (scm_cdr (ps));
 
-      Real ss = Staff_symbol_referencer::staff_space (me);
+      Drul_array<Grob *> stems (Note_column::get_stem (columns[0]),
+                               Note_column::get_stem (columns.back ()));
+
+      
+      
+
+      Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
+      Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0);
+      Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0);
+
       
       offset = lp + dir * (0.5 + scm_to_double (me->get_property ("padding")));
       dy = (rp - lp);
-
-      dy *= ss;
-      offset *= ss;    
     }
 
   
@@ -693,7 +737,6 @@ Tuplet_bracket::add_tuplet_bracket (Grob *me, Grob *bracket)
 }
 
 ADD_INTERFACE (Tuplet_bracket,
-              "tuplet-bracket-interface",
               "A bracket with a number in the middle, used for tuplets. "
               "When the bracket spans  a line break, the value of "
               "@code{break-overshoot} determines how far it extends "