]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/spanner.cc
Fix 1111: Break dynamic line spanner if different direction is explicitly given
[lilypond.git] / lily / spanner.cc
index d3fd5a0955dd00df7cf78215f0452623748447c8..18a7e645f524bffc80adb2a2fab35709161c927b 100644 (file)
@@ -80,7 +80,7 @@ Spanner::do_break_processing ()
 
       Slice parent_rank_slice;
       parent_rank_slice.set_full ();
-      
+
       /*
        Check if our parent in X-direction spans equally wide
        or wider than we do.
@@ -90,7 +90,7 @@ Spanner::do_break_processing ()
          if (Spanner *parent = dynamic_cast<Spanner *> (get_parent ((Axis)a)))
            parent_rank_slice.intersect (parent->spanned_rank_interval ());
        }
-  
+
       for (vsize i = 1; i < break_points.size (); i++)
        {
          Drul_array<Item *> bounds;
@@ -112,15 +112,15 @@ Spanner::do_break_processing ()
 
          bool ok = parent_rank_slice.contains (bounds[LEFT]->get_column ()->get_rank ());
          ok = ok && parent_rank_slice.contains (bounds[RIGHT]->get_column ()->get_rank ());
-         
+
          if (!ok)
            {
              programming_error (to_string ("Spanner `%s' is not fully contained in parent spanner. Ignoring orphaned part",
                                            name ().c_str ()));
              continue;
            }
-           
-         
+
+
          Spanner *span = dynamic_cast<Spanner *> (clone ());
          span->set_bound (LEFT, bounds[LEFT]);
          span->set_bound (RIGHT, bounds[RIGHT]);
@@ -239,13 +239,28 @@ Spanner::Spanner (Spanner const &s)
 Real
 Spanner::spanner_length () const
 {
-  Real l = spanned_drul_[LEFT]->relative_coordinate (0, X_AXIS);
-  Real r = spanned_drul_[RIGHT]->relative_coordinate (0, X_AXIS);
+  Interval lr;
+
+  Drul_array<SCM> bounds (get_property ("left-bound-info"),
+                          get_property ("right-bound-info"));
+
+  Direction d =  LEFT;
+  do
+    lr[d] = robust_scm2double (ly_assoc_get (ly_symbol2scm ("X"),
+                                             bounds[d], SCM_BOOL_F), -d);
+  while (flip (&d) != LEFT);
+
+  if (lr.is_empty ())
+    {
+      do
+        lr[d] = spanned_drul_[d]->relative_coordinate (0, X_AXIS);
+      while (flip (&d) != LEFT);
+    }
 
-  if (r < l)
+  if (lr.is_empty ())
     programming_error ("spanner with negative length");
 
-  return r - l;
+  return lr.length ();
 }
 
 System *
@@ -372,7 +387,7 @@ Spanner::set_spacing_rods (SCM smob)
                                sp->get_bound (RIGHT));
       if (!bounds[LEFT] || !bounds[RIGHT])
        return SCM_UNSPECIFIED;
-      
+
       vector<Item*> cols (root->broken_col_range (bounds[LEFT]->get_column (),
                                                  bounds[RIGHT]->get_column ()));
 
@@ -383,18 +398,18 @@ Spanner::set_spacing_rods (SCM smob)
          r.item_drul_[RIGHT] = cols[0]->find_prebroken_piece (LEFT);
          r.distance_ = robust_scm2double (num_length, 0);
          r.add_to_cols ();
-         
+
          r.item_drul_[LEFT] = cols.back ()->find_prebroken_piece (RIGHT);
          r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
          r.add_to_cols ();
        }
-          
+
       r.distance_ = robust_scm2double (num_length, 0);
       r.item_drul_[LEFT] = sp->get_bound (LEFT);
       r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
       r.add_to_cols ();
     }
-  
+
   return SCM_UNSPECIFIED;
 }
 
@@ -461,7 +476,7 @@ Spanner::bounds_width (SCM grob)
 
   Interval w (me->get_bound (LEFT)->relative_coordinate (common, X_AXIS),
              me->get_bound (RIGHT)->relative_coordinate (common, X_AXIS));
-             
+
   w -= me->relative_coordinate (common, X_AXIS);
 
   return ly_interval2scm (w);
@@ -472,7 +487,6 @@ SCM
 Spanner::kill_zero_spanned_time (SCM grob)
 {
   Spanner *me = unsmob_spanner (grob);
-  Interval_t<Moment> moments = me->spanned_time ();
   /*
     Remove the line or hairpin at the start of the line.  For
     piano voice indicators, it makes no sense to have them at
@@ -488,8 +502,13 @@ Spanner::kill_zero_spanned_time (SCM grob)
     --hwn.
 
   */
-  if (moments.length () == Moment (0, 0))
-    me->suicide ();
+  if (me->get_bound (LEFT)->break_status_dir ())
+    {
+      Interval_t<Moment> moments = me->spanned_time ();
+      moments [LEFT].grace_part_ = 0;
+      if (moments.length () == Moment (0, 0))
+        me->suicide ();
+    }
 
   return SCM_UNSPECIFIED;
 }
@@ -528,6 +547,7 @@ ADD_INTERFACE (Spanner,
               /* properties */
               "normalized-endpoints "
               "minimum-length "
+               "spanner-broken "
+               "spanner-id "
               "to-barline "
               );
-