]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam.cc
Fix off-by-one error in constrained-breaking.
[lilypond.git] / lily / beam.cc
index 4a59a069be9ae407f2b5786d87eff2f92d76d288..77953070c91192eb47af325d7ad013c44530c4c1 100644 (file)
@@ -296,6 +296,10 @@ typedef map<int, vector<Beam_stem_segment> >  Position_stem_segments_map;
 vector<Beam_segment>
 Beam::get_beam_segments (Grob *me_grob, Grob **common)
 {
+  /* ugh, this has a side-effect that we need to ensure that
+     Stem #'beaming is correct */
+  (void) me_grob->get_property ("quantized-positions");
+
   Spanner *me = dynamic_cast<Spanner*> (me_grob);
 
   extract_grob_set (me, "stems", stems);
@@ -381,10 +385,14 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
          Direction event_dir = LEFT;
          do
            {
-             Drul_array<bool> on_bound (j == 0 && event_dir==LEFT,
-                                        j == segs.size() - 1 && event_dir==RIGHT);
-             Drul_array<bool> inside (j > 0, j < segs.size()-1);
-             bool event = on_bound[event_dir]
+             bool on_bound = (event_dir == LEFT) ? j == 0 :
+               j == segs.size() - 1;
+
+             bool inside_stem = (event_dir == LEFT)
+                       ? segs[j].stem_index_ > 0
+                       : segs[j].stem_index_ < stems.size () - 1;
+                     
+             bool event = on_bound
                || abs (segs[j].rank_ - segs[j+event_dir].rank_) > 1
                || (abs (vertical_count) >= segs[j].max_connect_
                    || abs (vertical_count) >= segs[j + event_dir].max_connect_);
@@ -396,7 +404,7 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
              current.horizontal_[event_dir] = segs[j].stem_x_;
              if (segs[j].dir_ == event_dir)
                {
-                 if (on_bound[event_dir]
+                 if (on_bound
                      && me->get_bound (event_dir)->break_status_dir ())
                    {
                      current.horizontal_[event_dir]
@@ -409,12 +417,16 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
                        Stem::duration_log (segs[j].stem_) == 1
                        ? 1.98
                        : 1.32; // URG.
-                     
-                     if (inside[event_dir])
-                       notehead_width = min (notehead_width,
-                                             fabs (segs[j+ event_dir].stem_x_
-                                                   - segs[j].stem_x_)/2);
-                     
+
+
+                     if (inside_stem)
+                       {
+                         Grob *neighbor_stem = stems[segs[j].stem_index_ + event_dir];
+                         Real neighbor_stem_x = neighbor_stem->relative_coordinate (commonx, X_AXIS);
+
+                         notehead_width = min (notehead_width,
+                                               fabs (neighbor_stem_x - segs[j].stem_x_)/2);
+                       }
                      current.horizontal_[event_dir] += event_dir * notehead_width;
                    }
                }
@@ -557,7 +569,7 @@ Beam::get_default_dir (Grob *me)
     {
       Grob *s = stems[i];
       Direction stem_dir = CENTER;
-      SCM stem_dir_scm = s->get_property_data (ly_symbol2scm ("direction"));
+      SCM stem_dir_scm = s->get_property_data ("direction");
       if (is_direction (stem_dir_scm))
        {
          stem_dir = to_dir (stem_dir_scm);
@@ -613,7 +625,7 @@ Beam::set_stem_directions (Grob *me, Direction d)
     {
       Grob *s = stems[i];
 
-      SCM forcedir = s->get_property_data (ly_symbol2scm ("direction"));
+      SCM forcedir = s->get_property_data ("direction");
       if (!to_dir (forcedir))
        set_grob_direction (s, d);
     }
@@ -668,7 +680,7 @@ Beam::consider_auto_knees (Grob *me)
          */
          head_extents += stem->relative_coordinate (common, Y_AXIS);
 
-         if (to_dir (stem->get_property_data (ly_symbol2scm ("direction"))))
+         if (to_dir (stem->get_property_data ("direction")))
            {
              Direction stemdir = to_dir (stem->get_property ("direction"));
              head_extents[-stemdir] = -stemdir * infinity_f;
@@ -1169,8 +1181,6 @@ Beam::set_stem_lengths (SCM smob)
   for (vsize i = 0; i < stems.size (); i++)
     {
       Grob *s = stems[i];
-      if (Stem::is_invisible (s))
-       continue;
 
       bool french = to_boolean (s->get_property ("french-beaming"));
       Real stem_y = calc_stem_y (me, s, common,
@@ -1181,9 +1191,14 @@ Beam::set_stem_lengths (SCM smob)
        Make the stems go up to the end of the beam. This doesn't matter
        for normal beams, but for tremolo beams it looks silly otherwise.
       */
-      if (gap)
+      if (gap
+          && !Stem::is_invisible (s))
        stem_y += thick * 0.5 * get_grob_direction (s);
 
+      /*
+       Do set_stemend for invisible stems too, so tuplet brackets
+       have a reference point for sloping
+       */
       Stem::set_stemend (s, 2 * stem_y / staff_space);
     }
 
@@ -1433,7 +1448,6 @@ Beam::get_direction_beam_count (Grob *me, Direction d)
 }
 
 ADD_INTERFACE (Beam,
-              "beam-interface",
 
               "A beam. \n\n"
               "The @code{thickness} property is the weight of beams, "