]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add Beam_collision_engraver.
authorMike Solomon <mike@apollinemike.com>
Mon, 7 Feb 2011 15:23:03 +0000 (13:23 -0200)
committerHan-Wen Nienhuys <hanwen@lilypond.org>
Wed, 9 Feb 2011 03:50:56 +0000 (01:50 -0200)
lily/beam-collision-engraver.cc [new file with mode: 0644]
lily/beam.cc
ly/engraver-init.ly
scm/define-grob-properties.scm

diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc
new file mode 100644 (file)
index 0000000..99f9298
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "beam.hh"
+#include "engraver.hh"
+#include "item.hh"
+#include "note-head.hh"
+#include "pointer-group-interface.hh"
+
+class Beam_collision_engraver : public Engraver
+{
+protected:
+  vector<Grob *> active_beams_;
+  vector<Grob *> signaled_beams_;
+  vector<Grob *> end_beams_;
+  vector<Grob *> covered_grobs_;
+  vector<Grob *> covered_interior_grobs_;
+
+  DECLARE_ACKNOWLEDGER (note_head);
+  DECLARE_ACKNOWLEDGER (accidental);
+  DECLARE_ACKNOWLEDGER (clef);
+  DECLARE_ACKNOWLEDGER (key_signature);
+  DECLARE_ACKNOWLEDGER (time_signature);
+  DECLARE_ACKNOWLEDGER (bar_line);
+  DECLARE_ACKNOWLEDGER (beam);
+  DECLARE_END_ACKNOWLEDGER (beam);
+  void stop_translation_timestep ();
+public:
+  TRANSLATOR_DECLARATIONS (Beam_collision_engraver);
+};
+
+void
+Beam_collision_engraver::stop_translation_timestep ()
+{
+  for (vsize i = 0; i < covered_interior_grobs_.size (); i++)
+    for (vsize j = 0; j < active_beams_.size (); j++)
+      Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), covered_interior_grobs_[i]);
+
+  covered_interior_grobs_.clear ();
+
+  for (vsize i = 0; i < active_beams_.size (); i++)
+    for (vsize j = 0; j < signaled_beams_.size (); j++)
+      if (active_beams_[i] == signaled_beams_[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_[i] == signaled_beams_[j])
+        {
+          signaled_beams_.erase (signaled_beams_.begin () + j);
+          break;
+        }
+
+  for (vsize i = 0; i < signaled_beams_.size (); i++)
+    active_beams_.push_back (signaled_beams_[i]);
+
+  signaled_beams_.clear ();
+
+  for (vsize i = 0; i < covered_grobs_.size (); i++)
+    for (vsize j = 0; j < active_beams_.size (); j++)
+      {
+        Grob *g = covered_grobs_[i];
+        if (Grob *stem = unsmob_grob (g->get_object ("stem")))
+          if (Grob *beam = unsmob_grob (stem->get_object ("beam")))
+            if (beam == active_beams_[j])
+              continue;
+
+        Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), g);
+      }
+
+  covered_grobs_.clear ();
+
+  for (vsize i = 0; i < end_beams_.size (); i++)
+    for (vsize j = 0; j < active_beams_.size (); j++)
+      if (end_beams_[i] == active_beams_[j])
+        {
+          active_beams_.erase (active_beams_.begin () + j);
+          break;
+        }
+
+  end_beams_.clear ();
+}
+
+Beam_collision_engraver::Beam_collision_engraver () {}
+
+void
+Beam_collision_engraver::acknowledge_note_head (Grob_info i)
+{
+  covered_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_accidental (Grob_info i)
+{
+  covered_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_bar_line (Grob_info i)
+{
+  covered_interior_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_clef (Grob_info i)
+{
+  covered_interior_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_key_signature (Grob_info i)
+{
+  covered_interior_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_time_signature (Grob_info i)
+{
+  covered_interior_grobs_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_beam (Grob_info i)
+{
+  signaled_beams_.push_back (i.grob ());
+}
+
+void
+Beam_collision_engraver::acknowledge_end_beam (Grob_info i)
+{
+  end_beams_.push_back (i.grob ());
+}
+
+#include "translator.icc"
+
+ADD_ACKNOWLEDGER (Beam_collision_engraver, note_head);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, accidental);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, clef);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, key_signature);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, time_signature);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, beam);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, bar_line);
+ADD_END_ACKNOWLEDGER (Beam_collision_engraver, beam);
+
+ADD_TRANSLATOR (Beam_collision_engraver,
+               /* doc */
+               "Help beams avoid colliding with notes and clefs in other voices.",
+
+               /* create */
+               "",
+
+               /* read */
+               "",
+
+               /* write */
+               ""
+               );
index f983040bcabc51aaab2962563eac22135f43c1a0..26404ce8836078d8bd1c0bea886c137e959858c5 100644 (file)
@@ -1625,6 +1625,7 @@ ADD_INTERFACE (Beam,
               "break-overshoot "
               "clip-edges "
               "concaveness "
+              "covered-grobs "
               "damping "
               "details "
               "direction "
index 99d057cedaf5327919ef62affe37b246323fb759..92c8398f34c56ebeb95b30999664e2b51041f26b 100644 (file)
@@ -70,6 +70,7 @@
   \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"
index e92bf9ce345a908bec29d023681330e0ef446b2f..f6abf1a8cfdab7d9114020e61970941270c6805b 100644 (file)
@@ -971,6 +971,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.")
+     (covered-grobs ,ly:grob-array? "Grobs 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.")