lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

First step towards fixing the cross staff problem (issue4430063)


From: mtsolo
Subject: First step towards fixing the cross staff problem (issue4430063)
Date: Sun, 24 Apr 2011 12:14:16 +0000

Reviewers: ,

Message:
This patch seems to get everything right in the beam-collision engraver.

If the typesetting in beam.cc can accommodate it, I think we'll have hit
beam collision nirvana.

In:


<<
  \new Staff = up \relative c' {
    c8 c c c
  }
  \new Staff = down \relative c' {
    s8 c c c
    \change Staff = up
  }


<<
  \new Staff = up \relative c' {
    c8 c c c
  }
  \new Staff = down \relative c' {
    s8 c c
    \change Staff = up
    c8
  }


The first example now clears, whereas the last one still has problems.
These problems stem from the first beam trying to avoid the second beam
(not stems, noteheads, etc.).

If anyone can figure out a way to make this work in beam.cc, then it
seems like a good solution, as it genuinely handles cross-staff beams.



Description:
First step towards fixing cross staff problem

Please review this at http://codereview.appspot.com/4430063/

Affected files:
  M lily/beam-collision-engraver.cc
  M ly/engraver-init.ly


Index: lily/beam-collision-engraver.cc
diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc index 19e9b82caf2c1d482d1a944a5da588ed89298c0b..e7371429e8c54000febd945272c27eaf1c779790 100644
--- a/lily/beam-collision-engraver.cc
+++ b/lily/beam-collision-engraver.cc
@@ -17,11 +17,15 @@
   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */

+#include <set>
+
 #include "beam.hh"
+#include "context.hh"
 #include "engraver.hh"
 #include "item.hh"
 #include "note-head.hh"
 #include "pointer-group-interface.hh"
+#include "staff-symbol-referencer.hh"
 #include "stem.hh"

 class Beam_collision_engraver : public Engraver
@@ -76,15 +80,31 @@ Beam_collision_engraver::finalize ()
   for (vsize i = 0; i < beams_.size (); i++)
     {
       Grob *beam_grob = beams_[i].grob ();
-      if (Beam::is_cross_staff (beam_grob))
-        continue;
-
       Context *beam_context = beams_[i].context ();

Interval_t<int> beam_spanned_rank_ = beam_grob->spanned_rank_interval ();
+
+      set<Grob *> staff_symbols;
+      extract_grob_set (beam_grob, "stems", stems);
+      vsize k = 0;
+
// Start considering grobs at the first grob whose end falls at or after the beam's beginning. while (covered_grobs_[start].grob ()->spanned_rank_interval ()[RIGHT] < beam_spanned_rank_[LEFT])
         start++;
+
+      // First, find the staves to which any covered grob may belong
+      for (vsize j = start; j < covered_grobs_.size (); j++)
+        {
+          Grob *covered_grob = covered_grobs_[j].grob ();
+
+          if (covered_grob == stems[k])
+            {
+ staff_symbols.insert (Staff_symbol_referencer::get_staff_symbol (covered_grob));
+              k++;
+            }
+          if (k == stems.size ())
+            break;
+        }

       // Stop when the grob's beginning comes after the beam's end.
       for (vsize j = start; j < covered_grobs_.size (); j++)
@@ -92,6 +112,37 @@ Beam_collision_engraver::finalize ()
           Grob *covered_grob = covered_grobs_[j].grob ();
           Context *covered_grob_context = covered_grobs_[j].context ();

+          bool shares_staff = false;
+
+          set<Grob *>::iterator it;
+
+ for (it = staff_symbols.begin (); it != staff_symbols.end (); it++)
+            {
+              if (Beam::has_interface (covered_grob))
+                {
+ extract_grob_set (covered_grob, "stems", covered_beam_stems);
+                  for (vsize l = 0; l < covered_beam_stems.size (); l++)
+                    {
+ if (Staff_symbol_referencer::get_staff_symbol (covered_beam_stems[l]) == *it)
+                        {
+                          shares_staff = true;
+                          break;
+                        }
+                    }
+                  if (shares_staff)
+                    break;
+                }
+              else
+ if (Staff_symbol_referencer::get_staff_symbol (covered_grob) == *it)
+                  {
+                    shares_staff = true;
+                    break;
+                  }
+              }
+
+          if (!shares_staff)
+            continue;
+
Interval_t<int> covered_grob_spanned_rank = covered_grob->spanned_rank_interval ();
           if (covered_grob_spanned_rank[LEFT] > beam_spanned_rank_[RIGHT])
             break;
Index: ly/engraver-init.ly
diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly
index 6fccc5d134631328abaf0e4efe3292a8a7b712ed..06dacdd1e57ddd38794abe00f46469710d80be88 100644
--- a/ly/engraver-init.ly
+++ b/ly/engraver-init.ly
@@ -70,7 +70,6 @@
   \consists "Ledger_line_engraver"
   \consists "Staff_symbol_engraver"
   \consists "Collision_engraver"
-  \consists "Beam_collision_engraver"
   \consists "Grob_pq_engraver"
   \consists "Rest_collision_engraver"
   \consists "Accidental_engraver"
@@ -547,6 +546,7 @@ automatically when an output definition (a @code{\score} or
   \consists "Stanza_number_align_engraver"
   \consists "Bar_number_engraver"
   \consists "Parenthesis_engraver"
+  \consists "Beam_collision_engraver"

   \defaultchild "Staff"






reply via email to

[Prev in Thread] Current Thread [Next in Thread]