From 6a87b40e3e24a49a2513507826e40a851dcbb1e4 Mon Sep 17 00:00:00 2001 From: Mike Solomon Date: Mon, 7 Feb 2011 13:23:03 -0200 Subject: [PATCH] Add Beam_collision_engraver. --- lily/beam-collision-engraver.cc | 181 ++++++++++++++++++++++++++++++++ lily/beam.cc | 1 + ly/engraver-init.ly | 1 + scm/define-grob-properties.scm | 2 + 4 files changed, 185 insertions(+) create mode 100644 lily/beam-collision-engraver.cc diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc new file mode 100644 index 0000000000..99f9298209 --- /dev/null +++ b/lily/beam-collision-engraver.cc @@ -0,0 +1,181 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2011 Mike Solomon + + 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 . +*/ + +#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 active_beams_; + vector signaled_beams_; + vector end_beams_; + vector covered_grobs_; + vector 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 */ + "" + ); diff --git a/lily/beam.cc b/lily/beam.cc index f983040bca..26404ce883 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -1625,6 +1625,7 @@ ADD_INTERFACE (Beam, "break-overshoot " "clip-edges " "concaveness " + "covered-grobs " "damping " "details " "direction " diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 99d057ceda..92c8398f34 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -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" diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index e92bf9ce34..f6abf1a8cf 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -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.") -- 2.39.2