]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix to also work if some dirs are not set.
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 25 Jul 2002 23:29:33 +0000 (23:29 +0000)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 25 Jul 2002 23:29:33 +0000 (23:29 +0000)
For knees, set stems to their natural direction.

Don't force stems of kneed beams to reach middle staff line.

Recalculate beam position after deciding for a knee.

ChangeLog
lily/beam-quanting.cc
lily/beam.cc
lily/stem.cc

index e44454bc01132282d9ab51d4ac9646395fb769be..0baf8ea00b72a2cd6ffb330567cb4cbdf3edc19a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,24 @@
+2002-07-26  Jan Nieuwenhuizen  <janneke@gnu.org>
+
+       * lily/beam.cc (knee_b): Fix to also work if some dirs are not
+       set.
+
+       * lily/beam.cc (set_stem_directions): For knees, set stems to
+       their natural direction.
+
+2002-07-25  Jan Nieuwenhuizen  <janneke@gnu.org>
+
+       * lily/stem.cc (calc_stem_info): Don't force stems of kneed beams
+       to reach middle staff line.
+
+       * lily/beam.cc (consider_auto_knees): Recalculate beam position
+       after deciding for a knee.
+
 2002-07-26  Han-Wen  <hanwen@cs.uu.nl>
 
        * Documentation/user/internals.itely: move output-formats doco to
        WikiWiki.
        
-
 2002-07-25  Han-Wen  <hanwen@cs.uu.nl>
        
        * po/fr.po: update from TP
index 890e7abe1fff2e181169693e408a67789fd07130..6f5733f0d535fd99e58ea41f20629a192cba59ee 100644 (file)
@@ -211,7 +211,7 @@ Beam::quanting (SCM smob)
                                     beam_count, ldir, rdir); 
       }
 
-
+  ; /* silly gdb thinks best_idx is inside for loop. */
   for (int i = qscores.size (); i--;)
     if (qscores[i].demerits < reasonable_score)
       {
@@ -223,7 +223,7 @@ Beam::quanting (SCM smob)
                                 qscores[i].yl, qscores[i].yr);
       }
 
-
+  ; /* silly gdb thinks best_idx is inside for loop. */
   int best_idx = best_quant_score_idx (qscores);
   me->set_grob_property ("positions",
                         gh_cons (gh_double2scm (qscores[best_idx].yl),
index dda0cf2c8062f2f55ae594de4f6fe9a48a78e662..655e760322dc8ccb4240e390318be11b01598f50 100644 (file)
@@ -484,75 +484,89 @@ Beam::set_stem_directions (Grob *me, Direction d)
   for (int i=0; i <stems.size (); i++)
     {
       Grob *s = stems[i];
-      SCM force = s->remove_grob_property ("dir-forced");
-      if (!gh_boolean_p (force) || !gh_scm2bool (force))
-       Directional_element_interface::set (s, d);
+      /* For knees, non-forced stems should probably have their
+        natural direction. In any case, when knee, beam direction is
+        foe. */
+      if (knee_b(me))
+       Stem::get_direction (s); // this actually sets it, if necessary
+      else
+       {
+         SCM force = s->remove_grob_property ("dir-forced");
+         if (!gh_boolean_p (force) || !gh_scm2bool (force))
+           Directional_element_interface::set (s, d);
+       }
     }
 } 
 
 /* Simplistic auto-knees; only consider vertical gap between two
    adjacent chords.
 
-  `Forced' stem directions are ignored.  If you don't want auto-knees,
-  don't set, or unset auto-knee-gap. */
+   This may decide for a knee that's impossible to fit sane scoring
+   criteria (eg, stem lengths).  We may need something smarter. */
 void
 Beam::consider_auto_knees (Grob *me, Direction d)
 {
   SCM scm = me->get_grob_property ("auto-knee-gap");
 
-  if (gh_number_p (scm))
-    {
-      bool knee_b = false;
-      Real knee_y = 0;
-      Real staff_space = Staff_symbol_referencer::staff_space (me);
-      Real gap = gh_scm2double (scm) / staff_space;
+  if (!gh_number_p (scm))
+    return;
+  
+  bool knee_b = false;
+  
+  Real staff_space = Staff_symbol_referencer::staff_space (me);
+  Real gap = gh_scm2double (scm) / staff_space;
 
-      Link_array<Grob> stems=
-       Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems");
+  Link_array<Grob> stems=
+    Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems");
       
-      Grob *common = common_refpoint_of_array (stems, me,  Y_AXIS);
-
-      int l = 0;
-      for (int i=1; i < stems.size (); i++)
-        {
-         if (!Stem::invisible_b (stems[i-1]))
-           l = i - 1;
-         if (Stem::invisible_b (stems[l]))
-           continue;
-         if (Stem::invisible_b (stems[i]))
-           continue;
+  Grob *common = common_refpoint_of_array (stems, me,  Y_AXIS);
+
+  int l = 0;
+  for (int r=1; r < stems.size (); r++)
+    {
+      if (!Stem::invisible_b (stems[r-1]))
+       l = r - 1;
+      Grob *right = stems[r];
+      Grob *left = stems[l];
+      if (Stem::invisible_b (left))
+       continue;
+      if (Stem::invisible_b (right))
+       continue;
          
-         Real left = Stem::extremal_heads (stems[l])[d]
-           ->relative_coordinate (common, Y_AXIS);
-         Real right = Stem::extremal_heads (stems[i])[-d]
-           ->relative_coordinate (common, Y_AXIS);
+      Real left_y = Stem::extremal_heads (left)[d]
+       ->relative_coordinate (common, Y_AXIS);
+      Real right_y = Stem::extremal_heads (right)[-d]
+       ->relative_coordinate (common, Y_AXIS);
 
-         Real dy = right - left;
+      Real dy = right_y - left_y;
 
-         if (abs (dy) >= gap)
-           {
-             knee_y = (right + left) / 2;
-             knee_b = true;
-             break;
-           }
-       }
-      
-      if (knee_b)
+      if (abs (dy) >= gap)
        {
-         for (int i=0; i < stems.size (); i++)
+         knee_b = true;
+         Direction knee_dir = (right_y > left_y ? UP : DOWN);
+         if (!Stem::invisible_b (left)
+             && left->get_grob_property ("dir-forced") != SCM_BOOL_T)
            {
-             Grob *s = stems[i];         
-             if (Stem::invisible_b (s) || 
-                 s->get_grob_property ("dir-forced") == SCM_BOOL_T)
-               continue;
-             Real y = Stem::extremal_heads (stems[i])[d]
-               ->relative_coordinate (common, Y_AXIS);
+             Directional_element_interface::set (left, knee_dir);
+             left->set_grob_property ("dir-forced", SCM_BOOL_T);
 
-             Directional_element_interface::set (s, y < knee_y ? UP : DOWN);
-             s->set_grob_property ("dir-forced", SCM_BOOL_T);
+           }
+         if (!Stem::invisible_b (right)
+             && stems[r]->get_grob_property ("dir-forced") != SCM_BOOL_T)
+           {
+             Directional_element_interface::set (right, -knee_dir);
+             right->set_grob_property ("dir-forced", SCM_BOOL_T);
            }
        }
     }
+
+  if (knee_b)
+    {
+      me->set_grob_property ("knee", SCM_BOOL_T);
+       
+      for (int i=0; i < stems.size (); i++)
+       stems[i]->set_grob_property ("stem-info", SCM_EOL);
+    }
 }
 
 /* Set stem's shorten property if unset.
@@ -1274,25 +1288,19 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis)
 bool
 Beam::knee_b (Grob*me)
 {
-  SCM k=   me->get_grob_property ("knee");
-  if (gh_boolean_p(k))
+  SCM k = me->get_grob_property ("knee");
+  if (gh_boolean_p (k))
     return gh_scm2bool (k);
 
-  Link_array<Grob> stems=
-    Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems");
-
-  Drul_array<bool> dirs_found(0,0);
-  
-  for (int i= 0; i < stems.size(); i++)
-    {
-      Grob*s = stems[i];
-      dirs_found[Directional_element_interface::get(s)] = true;
-
-      if (dirs_found[LEFT]&&dirs_found[RIGHT])
+  bool knee = false;
+  int d = 0;
+  for (SCM s = me->get_grob_property ("stems"); gh_pair_p (s); s = ly_cdr (s))
+    if (d != Directional_element_interface::get (unsmob_grob (ly_car (s))))
+      {
+       knee = true;
        break;
-    }
-
-  bool knee = dirs_found[LEFT]&&dirs_found[RIGHT];
+      }
+  
   me->set_grob_property ("knee", gh_bool2scm (knee));
 
   return knee;
index 502ca9dc5cbdf527edff070570fe4874c3f62a75..fb0243ae4524588f18be1a34a708b0e35dc5eb24 100644 (file)
@@ -836,10 +836,12 @@ Stem::calc_stem_info (Grob*me)
     Although this (additional) rule is probably correct,
     I expect that highest beam (UP) should also never be lower
     than middle staffline, just as normal stems.
-       
+
+    Add: not for knees.  Not sure if that's is a good thing.
   */
   bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
-  if (!grace_b && !no_extend_b)
+  bool knee_b = to_boolean (beam->get_grob_property ("knee"));
+  if (!grace_b && !no_extend_b && !knee_b)
     {
       /* highest beam of (UP) beam must never be lower than middle
         staffline