From 0c1b9bfdd0747131673891fd9c293348339af2fe Mon Sep 17 00:00:00 2001
From: Mike Solomon <mike@apollinemike.com>
Date: Sat, 8 Jan 2011 17:51:47 -0500
Subject: [PATCH 3/6] Intermediary 37 patch

Intermediate patch for 37

Whitespace fixes

Intermediary fix
---
 input/regression/beam-collision.ly |   20 ++++++++++++++++
 lily/beam-collision-engraver.cc    |   45 ++++++++++++++++++++++++++++--------
 lily/beam.cc                       |   19 ++++++++++----
 scm/define-grob-properties.scm     |    2 +
 4 files changed, 70 insertions(+), 16 deletions(-)
 create mode 100644 input/regression/beam-collision.ly

diff --git a/input/regression/beam-collision.ly b/input/regression/beam-collision.ly
new file mode 100644
index 0000000..35c4d0f
--- /dev/null
+++ b/input/regression/beam-collision.ly
@@ -0,0 +1,20 @@
+\version "2.13.46"
+\header{
+	texidoc="@cindex Beam Collisions
+
+When set manually, beams do not collide in polyphonic textures.
+
+"
+
+}
+
+\layout{
+  ragged-right = ##t
+}
+
+\relative c'' {
+<< { s8 e8 [ s cis, ] } \\ { b''8 [ s b ] } >>
+<< { s16 c,,16 [ s c'' ] } \\ { b16 [ s d,, ] } >>
+<< { \times 4/5 { s32 e [ s g s g, s e'' s b' ] } } \\
+   { \times 4/5 { c,,32 [ s c'' s g, s b s d s ] } } >>
+}
diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc
index dfbaa67..e2f14b0 100644
--- a/lily/beam-collision-engraver.cc
+++ b/lily/beam-collision-engraver.cc
@@ -30,6 +30,7 @@ class Beam_collision_engraver : public Engraver
 protected:
 
   vector<Grob *> active_beams_;
+  vector<Grob *> signaled_beams_;
   vector<Grob *> end_beams_;
   vector<Grob *> note_heads_;
 
@@ -43,7 +44,34 @@ public:
 };
 
 void
-Beam_collision_engraver::stop_translation_timestep() {
+Beam_collision_engraver::stop_translation_timestep()
+{
+  for (vsize i=0; i < active_beams_.size (); i++)
+    for (vsize j=0; j < signaled_beams_.size (); j++)
+      if (active_beams_.at (i) == signaled_beams_.at (j))
+        {
+          signaled_beams_.erase (signaled_beams_.begin() + j);
+          break;
+        }
+
+  /*
+    hack.
+    in auto beaming, end beams are signaled with their beams at a later timestep.
+    we need to scrub these.
+  */
+  for (vsize i=0; i < end_beams_.size (); i++)
+    for (vsize j=0; j < signaled_beams_.size (); j++)
+      if (end_beams_.at (i) == signaled_beams_.at (j))
+        {
+          signaled_beams_.erase (signaled_beams_.begin() + j);
+          break;
+        }
+
+  for (vsize i=0; i < signaled_beams_.size (); i++)
+    active_beams_.push_back (signaled_beams_.at (i));
+
+  signaled_beams_.clear ();
+
   for (vsize i=0; i < note_heads_.size (); i++)
     for (vsize j=0; j < active_beams_.size (); j++)
       Pointer_group_interface::add_grob (active_beams_.at (j), ly_symbol2scm ("covering-note-heads"), note_heads_.at (i));
@@ -53,10 +81,11 @@ Beam_collision_engraver::stop_translation_timestep() {
   for (vsize i=0; i < end_beams_.size (); i++)
     for (vsize j=0; j < active_beams_.size (); j++)
       if (end_beams_.at (i) == active_beams_.at (j))
-      {
-        active_beams_.erase (active_beams_.begin() + j);
-        break;
-      }
+        {
+          active_beams_.erase (active_beams_.begin() + j);
+          break;
+        }
+
   end_beams_.clear ();
 }
 
@@ -74,11 +103,7 @@ Beam_collision_engraver::acknowledge_note_head (Grob_info i)
 void
 Beam_collision_engraver::acknowledge_beam (Grob_info i)
 {
-  for (vsize j=0; j < active_beams_.size (); j++)
-    if (i.grob () == active_beams_.at (j))
-      return;
-
-  active_beams_.push_back (i.grob ());
+  signaled_beams_.push_back (i.grob ());
 }
 
 void
diff --git a/lily/beam.cc b/lily/beam.cc
index 00f0668..ef78508 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -936,9 +936,12 @@ Beam::move_to_avoid_collisions (SCM smob, SCM posns)
 {
 
   Grob *me = unsmob_grob (smob);
-  Direction fd = to_dir (first_normal_stem (me)->get_property ("direction"));
-  Direction ld = to_dir (last_normal_stem (me)->get_property ("direction"));
-
+  Grob *fns = first_normal_stem (me);
+  Grob *lns = last_normal_stem (me);
+  if (!(fns && lns))
+    return posns;
+  Direction fd = to_dir (fns->get_property ("direction"));
+  Direction ld = to_dir (lns->get_property ("direction"));
 
   if (fd == ld & !is_cross_staff (me))
     {
@@ -948,24 +951,27 @@ Beam::move_to_avoid_collisions (SCM smob, SCM posns)
       Real offset = 0.0;
       Drul_array<Real> pos = ly_scm2interval (posns);
       extract_grob_set (me, "covering-note-heads", covering_note_heads);
-      Real magic = 0.0;
 
       extract_grob_set (me, "normal-stems", stems);
+      int max_duration_log = -1000;
+      for (vsize i = 0; i < stems.size (); i++)
+        max_duration_log = max (max_duration_log, Stem::duration_log (stems.at (i)));
+
       Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS);
       Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS);
       Real x0 = first_normal_stem (me)->relative_coordinate (commonx, X_AXIS);
       Real xlast = last_normal_stem (me)->relative_coordinate (commonx, X_AXIS);
 
       Real slope = (pos[LEFT] - pos[RIGHT]) / (x0 - xlast);
+      Real magic = 1.0 + max_duration_log - 3;
 
       if (fd == UP)
         {
-          magic = 2.0;
           dummy = LEFT;
         }
       else
         {
-          magic = -2.0;
+          magic *= -1.0;
           dummy = RIGHT;
         }
 
@@ -1691,6 +1697,7 @@ ADD_INTERFACE (Beam,
 	       "break-overshoot "
 	       "clip-edges "
 	       "concaveness "
+               "covering-note-heads "
 	       "damping "
 	       "details "
 	       "direction "
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 36c8954..ec7ecaa 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -969,6 +969,8 @@ bounds are spaced.")
      (columns ,ly:grob-array? "An array of grobs, typically containing
 @code{PaperColumn} or @code{NoteColumn} objects.")
      (conditional-elements ,ly:grob-array? "Internal use only.")
+     (covering-note-heads ,ly:grob-array? "Note heads that could potentially
+collide with a beam.")
 
      (direction-source ,ly:grob? "In case @code{side-relative-direction} is
 set, which grob to get the direction from.")
-- 
1.7.3.2

