]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/tuplet-bracket.cc
Fix 352.
[lilypond.git] / lily / tuplet-bracket.cc
index 4d4fbe9acb9b858fff0f76974566ddc862a1a133..06411f72f2885a620fa85fad149dfd527820cf0f 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+  (c) 1997--2007 Jan Nieuwenhuizen <janneke@gnu.org>
   Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
   Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
@@ -92,7 +92,7 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols,
                           Note_column::get_stem (cols.back ()));
 
   if (dynamic_cast<Item*> (stems[RIGHT])->get_column ()
                           Note_column::get_stem (cols.back ()));
 
   if (dynamic_cast<Item*> (stems[RIGHT])->get_column ()
-      != me->get_bound (RIGHT)->get_column())
+      != me->get_bound (RIGHT)->get_column ())
     return 0;
 
   Drul_array<Grob*> beams;
     return 0;
 
   Drul_array<Grob*> beams;
@@ -120,7 +120,7 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols,
 }
 
 
 }
 
 
-MAKE_SCHEME_CALLBACK(Tuplet_bracket,calc_connect_to_neighbors,1);
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_connect_to_neighbors,1);
 SCM
 Tuplet_bracket::calc_connect_to_neighbors (SCM smob)
 {
 SCM
 Tuplet_bracket::calc_connect_to_neighbors (SCM smob)
 {
@@ -176,7 +176,7 @@ Tuplet_bracket::get_common_x (Spanner *me)
   return commonx;
 }
   
   return commonx;
 }
   
-MAKE_SCHEME_CALLBACK(Tuplet_bracket,calc_control_points,1)
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_control_points,1)
 SCM
 Tuplet_bracket::calc_control_points (SCM smob)
 {
 SCM
 Tuplet_bracket::calc_control_points (SCM smob)
 {
@@ -494,6 +494,7 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
   commony = common_refpoint_of_array (tuplets, commony, Y_AXIS);
   if (Grob *st = Staff_symbol_referencer::get_staff_symbol (me))
     commony = st->common_refpoint (commony, Y_AXIS);
   commony = common_refpoint_of_array (tuplets, commony, Y_AXIS);
   if (Grob *st = Staff_symbol_referencer::get_staff_symbol (me))
     commony = st->common_refpoint (commony, Y_AXIS);
+  Real my_offset = me->relative_coordinate (commony, Y_AXIS);
 
   Grob *commonx = get_common_x (me);
   commonx = common_refpoint_of_array (tuplets, commonx, Y_AXIS);
 
   Grob *commonx = get_common_x (me);
   commonx = common_refpoint_of_array (tuplets, commonx, Y_AXIS);
@@ -504,7 +505,7 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       Real pad = robust_scm2double (me->get_property ("staff-padding"), -1.0);
       if  (pad >= 0.0)
        {
       Real pad = robust_scm2double (me->get_property ("staff-padding"), -1.0);
       if  (pad >= 0.0)
        {
-         staff = st->extent (commony, Y_AXIS);
+         staff = st->extent (commony, Y_AXIS) - my_offset;
          staff.widen (pad);
        }
     }
          staff.widen (pad);
        }
     }
@@ -520,12 +521,13 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
   Item *rgr = get_x_bound_item (me, RIGHT, dir);
   Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
   Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
   Item *rgr = get_x_bound_item (me, RIGHT, dir);
   Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
   Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
+  bool follow_beam = par_beam
+    && ((get_grob_direction (par_beam) == dir) || to_boolean (par_beam->get_property ("knee")));
 
   vector<Offset> points;
 
   if (columns.size ()
 
   vector<Offset> points;
 
   if (columns.size ()
-      && par_beam
-      && get_grob_direction (par_beam) == dir 
+      && follow_beam
       && Note_column::get_stem (columns[0])
       && Note_column::get_stem (columns.back ()))
     {
       && Note_column::get_stem (columns[0])
       && Note_column::get_stem (columns.back ()))
     {
@@ -542,8 +544,10 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       
 
       Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
       
 
       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);
+      Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0)
+        + stems[LEFT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS) - my_offset;
+      Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0)
+        + stems[RIGHT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS) - my_offset;
 
       *dy = rp - lp;
       points.push_back (Offset (stems[LEFT]->relative_coordinate (commonx, X_AXIS) - x0, lp));
 
       *dy = rp - lp;
       points.push_back (Offset (stems[LEFT]->relative_coordinate (commonx, X_AXIS) - x0, lp));
@@ -581,18 +585,17 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       else
        *dy = 0;
 
       else
        *dy = 0;
 
-      *offset = -dir * infinity_f;      
       for (vsize i = 0; i < columns.size (); i++)
        {
          Interval note_ext = columns[i]->extent (commony, Y_AXIS);
       for (vsize i = 0; i < columns.size (); i++)
        {
          Interval note_ext = columns[i]->extent (commony, Y_AXIS);
-         Real notey = note_ext[dir] - me->relative_coordinate (commony, Y_AXIS);
+         Real notey = note_ext[dir] - my_offset;
 
          Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0;
          points.push_back (Offset (x, notey));
        }
     }
 
 
          Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0;
          points.push_back (Offset (x, notey));
        }
     }
 
-  if (!(par_beam && get_grob_direction (par_beam) == dir))
+  if (!follow_beam)
     {
       points.push_back (Offset (x0 - x0, staff[dir]));
       points.push_back (Offset (x1 - x0, staff[dir]));
     {
       points.push_back (Offset (x0 - x0, staff[dir]));
       points.push_back (Offset (x1 - x0, staff[dir]));
@@ -636,6 +639,7 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
       while (flip (&d) != LEFT);
     }
 
       while (flip (&d) != LEFT);
     }
 
+  *offset = -dir * infinity_f;
   Real factor = (columns.size () > 1) ? 1 / (x1 - x0) : 1.0;
   for (vsize i = 0; i < points.size (); i++)
     {
   Real factor = (columns.size () > 1) ? 1 / (x1 - x0) : 1.0;
   for (vsize i = 0; i < points.size (); i++)
     {
@@ -654,6 +658,8 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy)
     Kind of pointless since we put them outside the staff anyway, but
     let's leave code for the future when possibly allow them to move
     into the staff once again.
     Kind of pointless since we put them outside the staff anyway, but
     let's leave code for the future when possibly allow them to move
     into the staff once again.
+  
+    This doesn't seem to support cross-staff tuplets atm.
   */
   if (*dy == 0
       && fabs (*offset) < ss * Staff_symbol_referencer::staff_radius (me))
   */
   if (*dy == 0
       && fabs (*offset) < ss * Staff_symbol_referencer::staff_radius (me))
@@ -737,6 +743,33 @@ Tuplet_bracket::add_tuplet_bracket (Grob *me, Grob *bracket)
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("tuplets"), bracket);
 }
 
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("tuplets"), bracket);
 }
 
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_cross_staff, 1);
+SCM
+Tuplet_bracket::calc_cross_staff (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Grob *staff_symbol = 0;
+  extract_grob_set (me, "note-columns", cols);
+  bool equally_long = false;
+  Grob *par_beam = parallel_beam (me, cols, &equally_long);
+
+  if (par_beam)
+    return par_beam->get_property ("cross-staff");
+
+  for (vsize i = 0; i < cols.size (); i++)
+    {
+      Grob *stem = unsmob_grob (cols[i]->get_object ("stem"));
+      if (to_boolean (stem->get_property ("cross-staff")))
+       return SCM_BOOL_T;
+
+      Grob *stem_staff = Staff_symbol_referencer::get_staff_symbol (stem);
+      if (staff_symbol && (stem_staff != staff_symbol))
+        return SCM_BOOL_T;
+      staff_symbol = stem_staff;
+    }
+  return SCM_BOOL_F;
+}
+
 ADD_INTERFACE (Tuplet_bracket,
               "A bracket with a number in the middle, used for tuplets. "
               "When the bracket spans  a line break, the value of "
 ADD_INTERFACE (Tuplet_bracket,
               "A bracket with a number in the middle, used for tuplets. "
               "When the bracket spans  a line break, the value of "