]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam.cc
Merge commit '2a2f4f5'
[lilypond.git] / lily / beam.cc
index f2f0c645f35fe12ba30d4d290c0794e105ce2d7a..843278aff38e8b8f97c645ba73d24ed3f329ab6b 100644 (file)
@@ -336,7 +336,6 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
   Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
 
   Slice ranks;
-  
   for (vsize i = 0; i < stems.size (); i++)
     {
       Grob *stem = stems[i];
@@ -366,7 +365,7 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
              Beam_stem_segment seg;
              seg.stem_ = stem;
              seg.stem_x_ = stem_x;
-             seg.rank_ = 2 * i  + (d+1)/2;
+             seg.rank_ = 2 * i + (d+1)/2;
              seg.width_ = stem_width;
              seg.stem_index_ = i;
              seg.dir_ = d;
@@ -404,14 +403,15 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
          Direction event_dir = LEFT;
          do
            {
-             bool on_bound = (event_dir == LEFT) ? j == 0 :
+             bool on_line_bound = (segs[j].dir_ == LEFT) ? segs[j].stem_index_ == 0
+               : segs[j].stem_index_ == stems.size() - 1;
+             bool on_beam_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_ + 1  < stems.size () ;
+               ? segs[j].stem_index_ > 0
+               : segs[j].stem_index_ + 1 < stems.size () ;
                      
-             bool event = on_bound
+             bool event = on_beam_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_);
@@ -423,11 +423,12 @@ 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
+                 if (on_line_bound
                      && me->get_bound (event_dir)->break_status_dir ())
                    {
                      current.horizontal_[event_dir]
-                       = (robust_relative_extent (me->get_bound (event_dir), commonx, X_AXIS)[RIGHT]
+                       = (robust_relative_extent (me->get_bound (event_dir),
+                                                  commonx, X_AXIS)[RIGHT]
                           + event_dir * break_overshoot[event_dir]);
                    }
                  else
@@ -441,7 +442,8 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
                      if (inside_stem)
                        {
                          Grob *neighbor_stem = stems[segs[j].stem_index_ + event_dir];
-                         Real neighbor_stem_x = neighbor_stem->relative_coordinate (commonx, X_AXIS);
+                         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);
@@ -468,7 +470,9 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common)
                            current.horizontal_[event_dir]
                              = event_dir * min  (event_dir * current.horizontal_[event_dir],
                                                  - gap_length/2
-                                                 + event_dir * heads[k]->extent (commonx, X_AXIS)[-event_dir]);
+                                                 + event_dir
+                                                   * heads[k]->extent (commonx,
+                                                                       X_AXIS)[-event_dir]);
                        }
                    }
                }
@@ -1128,36 +1132,41 @@ where_are_the_whole_beams (SCM beaming)
    in POS for stem S.  This Y position is relative to S. */
 Real
 Beam::calc_stem_y (Grob *me, Grob *stem, Grob **common,
-                  Real xl, Real xr,
+                  Real xl, Real xr, Direction feather_dir, 
                   Drul_array<Real> pos, bool french)
 {
   Real beam_translation = get_beam_translation (me);
+  Direction stem_dir = get_grob_direction (stem);
 
-  Real r = stem->relative_coordinate (common[X_AXIS], X_AXIS) - xl;
-  Real dy = pos[RIGHT] - pos[LEFT];
   Real dx = xr - xl;
-  Real stem_y_beam0 = (dy && dx
-                      ? r / dx
-                      * dy
-                      : 0) + pos[LEFT];
+  Real relx = dx ? (stem->relative_coordinate (common[X_AXIS], X_AXIS) - xl)/dx : 0;
+  Real xdir = 2*relx-1;
+
+  Real stem_y = linear_combination(pos, xdir);
 
-  Direction my_dir = get_grob_direction (stem);
   SCM beaming = stem->get_property ("beaming");
 
-  Real stem_y = stem_y_beam0;
-  if (french)
-    {
-      Slice bm = where_are_the_whole_beams (beaming);
-      if (!bm.is_empty ())
-       stem_y += beam_translation * bm[-my_dir];
-    }
-  else
-    {
-      Slice bm = Stem::beam_multiplicity (stem);
-      if (!bm.is_empty ())
-       stem_y += bm[my_dir] * beam_translation;
-    }
+  Slice beam_slice (french
+                   ? where_are_the_whole_beams (beaming)
+                   : Stem::beam_multiplicity (stem));
+  if (beam_slice.is_empty ())
+    beam_slice = Slice (0,0);
+  Interval beam_multiplicity(beam_slice[LEFT],
+                            beam_slice[RIGHT]);
 
+  /*
+    feather dir = 1 , relx 0->1 : factor 0 -> 1
+    feather dir = 0 , relx 0->1 : factor 1 -> 1    
+    feather dir = -1, relx 0->1 : factor 1 -> 0    
+   */
+  Real feather_factor = 1;
+  if (feather_dir > 0)
+    feather_factor = relx;
+  else if (feather_dir < 0)
+    feather_factor = 1 - relx;
+  
+  stem_y += feather_factor * beam_translation
+    * beam_multiplicity[Direction(((french) ? DOWN : UP)*stem_dir)];
   Real id = me->relative_coordinate (common[Y_AXIS], Y_AXIS)
     - stem->relative_coordinate (common[Y_AXIS], Y_AXIS);
 
@@ -1205,6 +1214,7 @@ Beam::set_stem_lengths (SCM smob)
 
   Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
   Real xr = lvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
+  Direction feather_dir = to_dir (me->get_property ("grow-direction"));
 
   for (vsize i = 0; i < stems.size (); i++)
     {
@@ -1212,7 +1222,7 @@ Beam::set_stem_lengths (SCM smob)
 
       bool french = to_boolean (s->get_property ("french-beaming"));
       Real stem_y = calc_stem_y (me, s, common,
-                                xl, xr,
+                                xl, xr, feather_dir,
                                 pos, french && s != lvs && s!= fvs);
 
       /*