]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/tuplet-bracket.cc
* lily/rest.cc (y_offset_callback): merge function of 3 callbacks.
[lilypond.git] / lily / tuplet-bracket.cc
index 3709ac8b489abdf8acb5a3091435f81da0ff4e52..3e05c75a8a5d436280578c14e8b83fff1b3e9440 100644 (file)
@@ -29,7 +29,6 @@
   todo: handle breaking elegantly.
 */
 
-#include <math.h>
 
 #include "tuplet-bracket.hh"
 #include "line-interface.hh"
@@ -68,20 +67,24 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, Link_array<Grob> const &cols, bool
       || me->get_bound (RIGHT)->break_status_dir ())
     return 0;
 
-  Grob *s1 = Note_column::get_stem (cols[0]);
-  Grob *s2 = Note_column::get_stem (cols.top ());
+  Drul_array<Grob*> stems (Note_column::get_stem (cols[0]),
+                          Note_column::get_stem (cols.top ()));
 
-  if (s2 != me->get_bound (RIGHT))
+  if (dynamic_cast<Item*> (stems[RIGHT])->get_column ()
+      != me->get_bound (RIGHT)->get_column())
     return 0;
 
-  Grob *b1 = s1 ? Stem::get_beam (s1) : 0;
-  Grob *b2 = s2 ? Stem::get_beam (s2) : 0;
-
+  Drul_array<Grob*> beams;
+  Direction d = LEFT;
+  do {
+    beams[d] = stems[d] ? Stem::get_beam (stems[d]) : 0;
+  } while (flip (&d) != LEFT);
+  
   *equally_long = false;
-  if (! (b1 && (b1 == b2) && !me->is_broken ()))
+  if (! (beams[LEFT] && (beams[LEFT] == beams[RIGHT]) && !me->is_broken ()))
     return 0;
 
-  extract_grob_set (b1, "stems", beam_stems);
+  extract_grob_set (beams[LEFT], "stems", beam_stems);
   if (beam_stems.size () == 0)
     {
       programming_error ("beam under tuplet bracket has no stems");
@@ -89,8 +92,8 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, Link_array<Grob> const &cols, bool
       return 0;
     }
 
-  *equally_long = (beam_stems[0] == s1 && beam_stems.top () == s2);
-  return b1;
+  *equally_long = (beam_stems[0] == stems[LEFT] && beam_stems.top () == stems[RIGHT]);
+  return beams[LEFT];
 }
 
 /*
@@ -107,29 +110,10 @@ Tuplet_bracket::print (SCM smob)
   Stencil mol;
   extract_grob_set (me, "note-columns", columns);
 
-  {
-    SCM lp = me->get_property ("left-position");
-    SCM rp = me->get_property ("right-position");
-
-    if (!scm_is_number (rp) || !scm_is_number (lp))
-      {
-       /*
-         UGH. dependency tracking!
-       */
-       extract_grob_set (me, "tuplets", tuplets);
-       for (int i = 0; i < tuplets.size (); i++)
-         Tuplet_bracket::print (tuplets[i]->self_scm ());
-
-       after_line_breaking (smob);
-      }
-  }
-
-  Real ly = robust_scm2double (me->get_property ("left-position"), 0);
-  Real ry = robust_scm2double (me->get_property ("right-position"), 0);
-
+  Drul_array<Real> positions = ly_scm2realdrul (me->get_property ("positions"));
+  Real dy = positions[RIGHT] - positions[LEFT];
   bool equally_long = false;
   Grob *par_beam = parallel_beam (me, columns, &equally_long);
-
   Spanner *sp = dynamic_cast<Spanner *> (me);
 
   bool bracket_visibility = !(par_beam && equally_long);
@@ -168,9 +152,25 @@ Tuplet_bracket::print (SCM smob)
       x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[d];
       Direction break_dir = bounds[d]->break_status_dir ();
       Spanner *orig_spanner = dynamic_cast<Spanner *> (me->original_);
+
+      int neighbor_idx = me->get_break_index () - break_dir;
+
+      if (break_dir
+         && d == RIGHT
+         && neighbor_idx < orig_spanner->broken_intos_.size ())
+       {
+         Grob *neighbor = orig_spanner->broken_intos_[neighbor_idx];
+
+         /* trigger possible suicide*/
+         (void) neighbor->get_property ("positions");
+       }
+
       connect_to_other[d]
        = (break_dir
-          && (me->get_break_index () - break_dir < orig_spanner->broken_intos_.size ()));
+          && (neighbor_idx < orig_spanner->broken_intos_.size ()
+              && neighbor_idx >= 0)
+          && orig_spanner->broken_intos_[neighbor_idx]->is_live ());
+          
 
       if (connect_to_other[d])
        {
@@ -191,7 +191,12 @@ Tuplet_bracket::print (SCM smob)
          /*
            TODO: make padding tunable?
          */
-         x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT] - 1.0;
+         Real padding = 1.0;
+
+         if (bounds[d]->break_status_dir ())
+           padding = 0.0;
+         
+         x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT] - padding;
        }
     }
   while (flip (&d) != LEFT);
@@ -211,7 +216,7 @@ Tuplet_bracket::print (SCM smob)
       num.translate_axis (w / 2, X_AXIS);
       num.align_to (Y_AXIS, CENTER);
 
-      num.translate_axis ((ry - ly) / 2, Y_AXIS);
+      num.translate_axis (dy / 2, Y_AXIS);
 
       mol.add_stencil (num);
     }
@@ -261,7 +266,8 @@ Tuplet_bracket::print (SCM smob)
                  SCM text = index_get_cell (edge_text, d);
                  if (Text_interface::is_markup (text))
                    {
-                     SCM t = Text_interface::interpret_markup (pap->self_scm (), properties, text);
+                     SCM t = Text_interface::interpret_markup (pap->self_scm (),
+                                                               properties, text);
 
                      Stencil *edge_text = unsmob_stencil (t);
                      edge_text->translate_axis (x_span[d] - x_span[LEFT], X_AXIS);
@@ -273,7 +279,7 @@ Tuplet_bracket::print (SCM smob)
       while (flip (&d) != LEFT);
 
       Stencil brack = make_bracket (me, Y_AXIS,
-                                   Offset (w, ry - ly),
+                                   Offset (w, dy),
                                    height,
                                    /*
                                      0.1 = more space at right due to italics
@@ -292,7 +298,7 @@ Tuplet_bracket::print (SCM smob)
       mol.add_stencil (brack);
     }
 
-  mol.translate_axis (ly, Y_AXIS);
+  mol.translate_axis (positions[LEFT], Y_AXIS);
   mol.translate_axis (x_span[LEFT]
                      - sp->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS), X_AXIS);
   return mol.smobbed_copy ();
@@ -473,9 +479,10 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       Interval tuplet_y (tuplets[i]->extent (commony, Y_AXIS));
 
       Direction d = LEFT;
-      Real lp = scm_to_double (tuplets[i]->get_property ("left-position"));
-      Real rp = scm_to_double (tuplets[i]->get_property ("right-position"));
-      Real other_dy = rp - lp;
+      Drul_array<Real> positions = ly_scm2realdrul (tuplets[i]->get_property ("positions"));
+
+      
+      Real other_dy = positions[RIGHT] - positions[LEFT];
 
       do
        {
@@ -534,41 +541,31 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
     }
 }
 
-/*
-  We depend on the beams if there are any.
-*/
-MAKE_SCHEME_CALLBACK (Tuplet_bracket, before_line_breaking, 1);
+
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_direction, 1);
 SCM
-Tuplet_bracket::before_line_breaking (SCM smob)
+Tuplet_bracket::calc_direction (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
-  extract_grob_set (me, "note-columns", columns);
-
-  for (int i = columns.size (); i--;)
-    {
-      Grob *s = Note_column::get_stem (columns[i]);
-      Grob *b = s ? Stem::get_beam (s) : 0;
-      if (b)
-       me->add_dependency (b);
-    }
-  return SCM_UNSPECIFIED;
+  Direction dir = Tuplet_bracket::get_default_dir (me);
+  return scm_from_int (dir);
 }
 
-MAKE_SCHEME_CALLBACK (Tuplet_bracket, after_line_breaking, 1);
-
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_positions, 1);
 SCM
-Tuplet_bracket::after_line_breaking (SCM smob)
+Tuplet_bracket::calc_positions (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
   extract_grob_set (me, "note-columns", columns);
 
-  Direction dir = get_grob_direction (me);
-  if (!dir)
+  if (columns.is_empty())
     {
-      dir = Tuplet_bracket::get_default_dir (me);
-      set_grob_direction (me, dir);
+      me->suicide ();
+      return scm_cons (scm_from_double (0),
+                      scm_from_double (0));
     }
-
+  
+  Direction dir = get_grob_direction (me);
   bool equally_long = false;
   Grob *par_beam = parallel_beam (me, columns, &equally_long);
 
@@ -594,23 +591,11 @@ Tuplet_bracket::after_line_breaking (SCM smob)
       dy = rp - lp;
     }
 
-  SCM lp = me->get_property ("left-position");
-  SCM rp = me->get_property ("right-position");
-
-  if (scm_is_number (lp) && !scm_is_number (rp))
-    rp = scm_from_double (scm_to_double (lp) + dy);
-  else if (scm_is_number (rp) && !scm_is_number (lp))
-    lp = scm_from_double (scm_to_double (rp) - dy);
-  else if (!scm_is_number (rp) && !scm_is_number (lp))
-    {
-      lp = scm_from_double (offset);
-      rp = scm_from_double (offset + dy);
-    }
-
-  me->set_property ("left-position", lp);
-  me->set_property ("right-position", rp);
-
-  return SCM_UNSPECIFIED;
+  
+  SCM x = scm_cons (scm_from_double (offset),
+                   scm_from_double (offset + dy));
+  
+  return x;
 }
 
 /*
@@ -636,8 +621,6 @@ void
 Tuplet_bracket::add_column (Grob *me, Item *n)
 {
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
-  me->add_dependency (n);
-
   add_bound_item (dynamic_cast<Spanner *> (me), n);
 }
 
@@ -645,7 +628,6 @@ void
 Tuplet_bracket::add_tuplet_bracket (Grob *me, Grob *bracket)
 {
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("tuplets"), bracket);
-  me->add_dependency (bracket);
 }
 
 ADD_INTERFACE (Tuplet_bracket,
@@ -657,18 +639,18 @@ ADD_INTERFACE (Tuplet_bracket,
               "At a line break, the markups in the @code{edge-text} are printed "
               "at the edges. ",
 
-              
+
+              /* properties */
               "bracket-flare "
               "bracket-visibility "
               "break-overshoot "
-              "direction"
+              "direction "
               "edge-height "
               "edge-text "
-              "left-position "
+              "positions "
               "note-columns "
               "number-visibility "
               "padding "
-              "right-position "
               "shorten-pair "
               "staff-padding "
               "thickness "