X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftuplet-engraver.cc;h=7d97443e1d3db2ffac3ce03ae60ce2fb602c606f;hb=848abb841bc7e17ec915a546bca09a7373dbee98;hp=a588f48571403c23328565c8f5eec51e5776d2ba;hpb=ee8f78c08a35777bf7d4da02f0d3c9c967ada4d6;p=lilypond.git diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index a588f48571..7d97443e1d 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -3,31 +3,39 @@ source file of the GNU LilyPond music typesetter - (c) 1998--2006 Han-Wen Nienhuys + (c) 1998--2007 Han-Wen Nienhuys */ -#include "tuplet-bracket.hh" -#include "note-column.hh" #include "beam.hh" #include "engraver.hh" +#include "international.hh" +#include "note-column.hh" #include "spanner.hh" +#include "stream-event.hh" +#include "tuplet-bracket.hh" +#include "warn.hh" +#include "item.hh" +#include "moment.hh" #include "translator.icc" struct Tuplet_description { - Music *music_; + Stream_event *event_; Spanner *bracket_; Spanner *number_; bool full_length_; bool full_length_note_; + Moment stop_moment_; + Moment start_moment_; + Moment length_; Tuplet_description () { + event_ = 0; full_length_note_ = false; full_length_ = false; - music_ = 0; bracket_ = 0; number_ = 0; } @@ -40,43 +48,78 @@ public: protected: vector tuplets_; + vector new_tuplets_; vector stopped_tuplets_; vector last_tuplets_; + DECLARE_ACKNOWLEDGER (note_column); - virtual bool try_music (Music *r); + DECLARE_TRANSLATOR_LISTENER (tuplet_span); virtual void finalize (); void start_translation_timestep (); void process_music (); }; -bool -Tuplet_engraver::try_music (Music *music) +IMPLEMENT_TRANSLATOR_LISTENER (Tuplet_engraver, tuplet_span); +void +Tuplet_engraver::listen_tuplet_span (Stream_event *ev) { - if (music->is_mus_type ("tuplet-spanner-event")) + Direction dir = to_dir (ev->get_property ("span-direction")); + if (dir == START) { - Direction dir = to_dir (music->get_property ("span-direction")); - if (dir == START) + Tuplet_description d; + d.event_ = ev; + + d.length_ = robust_scm2moment (d.event_->get_property ("length"), + Moment (0)); + d.start_moment_ = now_mom (); + d.stop_moment_ = now_mom () + d.length_; + + for (vsize i=0; i < new_tuplets_.size (); i++) { - Tuplet_description d; - d.music_ = music; - tuplets_.push_back (d); + /* + discard duplicates. + */ + if (new_tuplets_[i].stop_moment_ == d.stop_moment_) + return; } - if (dir == STOP) + + new_tuplets_.push_back (d); + } + else if (dir == STOP) + { + if (tuplets_.size ()) { stopped_tuplets_.push_back (tuplets_.back ()); tuplets_.pop_back (); } - return true; + else if (!to_boolean (get_property ("skipTypesetting"))) + ev->origin ()->warning (_f ("No tuplet to end")); } - return false; + else + ev->origin ()->programming_error ("direction tuplet-span-event_ invalid."); } void Tuplet_engraver::process_music () { + /* + This may happen if the end of a tuplet is part of a quoted voice. + */ + Moment now = now_mom (); + for (vsize i = tuplets_.size (); i --; ) + { + if (tuplets_[i].stop_moment_ == now) + { + stopped_tuplets_.push_back (tuplets_[i]); + tuplets_.erase (tuplets_.begin () + i); + } + } + for (vsize i = 0; i < stopped_tuplets_.size (); i++) { - if (stopped_tuplets_[i].bracket_) + Spanner *bracket = stopped_tuplets_[i].bracket_; + Spanner *number = stopped_tuplets_[i].number_; + if (bracket) { if (stopped_tuplets_[i].full_length_) { @@ -85,24 +128,27 @@ Tuplet_engraver::process_music () ? get_property ("currentMusicalColumn") : get_property ("currentCommandColumn")); - stopped_tuplets_[i].bracket_->set_bound (RIGHT, col); - stopped_tuplets_[i].number_->set_bound (RIGHT, col); + bracket->set_bound (RIGHT, col); + number->set_bound (RIGHT, col); } - else if (!stopped_tuplets_[i].bracket_->get_bound (RIGHT)) + else if (!bracket->get_bound (RIGHT)) { - stopped_tuplets_[i].bracket_->set_bound (RIGHT, - stopped_tuplets_[i].bracket_->get_bound (LEFT)); - stopped_tuplets_[i].number_->set_bound (RIGHT, - stopped_tuplets_[i].bracket_->get_bound (LEFT)); + bracket->set_bound (RIGHT, + bracket->get_bound (LEFT)); + number->set_bound (RIGHT, + stopped_tuplets_[i].bracket_->get_bound (LEFT)); } + // todo: scrap last_tuplets_, use stopped_tuplets_ only. // clear stopped_tuplets_ at start_translation_timestep - last_tuplets_.push_back (tuplets_[i].bracket_); - last_tuplets_.push_back (tuplets_[i].number_); + last_tuplets_.push_back (bracket); + last_tuplets_.push_back (number); } } stopped_tuplets_.clear (); + concat (tuplets_, new_tuplets_); + new_tuplets_.clear (); for (vsize j = tuplets_.size (); j > 0; j--) { /* i goes from size-1 downto 0, inclusively */ @@ -117,13 +163,15 @@ Tuplet_engraver::process_music () = to_boolean (get_property ("tupletFullLengthNote")); tuplets_[i].bracket_ = make_spanner ("TupletBracket", - tuplets_[i].music_->self_scm ()); + tuplets_[i].event_->self_scm ()); tuplets_[i].number_ = make_spanner ("TupletNumber", - tuplets_[i].music_->self_scm ()); + tuplets_[i].event_->self_scm ()); tuplets_[i].number_->set_object ("bracket", tuplets_[i].bracket_->self_scm ()); tuplets_[i].bracket_->set_object ("tuplet-number", tuplets_[i].number_->self_scm ()); + tuplets_[i].stop_moment_.grace_part_ = 0; - if (i < tuplets_.size () - 1 && tuplets_[i + 1].bracket_) + + if (i + 1 < tuplets_.size () && tuplets_[i + 1].bracket_) Tuplet_bracket::add_tuplet_bracket (tuplets_[i].bracket_, tuplets_[i + 1].bracket_); if (i > 0 && tuplets_[i - 1].bracket_) @@ -148,6 +196,10 @@ void Tuplet_engraver::start_translation_timestep () { last_tuplets_.clear (); + /* + May seem superfluous, but necessary for skipTypesetting. + */ + new_tuplets_.clear (); } void @@ -167,8 +219,14 @@ Tuplet_engraver::Tuplet_engraver () ADD_ACKNOWLEDGER (Tuplet_engraver, note_column); ADD_TRANSLATOR (Tuplet_engraver, - /* doc */ "Catch TupletSpannerEvent and generate appropriate bracket ", - /* create */ "TupletBracket TupletNumber ", - /* accept */ "tuplet-spanner-event", - /* read */ "tupletFullLength ", + + /* doc */ + "Catch tuplet events and generate appropriate bracket.", + + /* create */ + "TupletBracket " + "TupletNumber ", + /* read */ + "tupletFullLength " + "tupletFullLengthNote ", /* write */ "");