X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftuplet-engraver.cc;h=0892cda3e38afda99244362d7db651bbd32664e8;hb=ddd59edaae68e71d5d3ea2576b3d0d25807fb500;hp=fd280e127e2978475315f8112afa848a9d798248;hpb=711cf44d0ab28f3159230c84d63c0b19199408b0;p=lilypond.git diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index fd280e127e..0892cda3e3 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -1,9 +1,20 @@ /* - tuplet-engraver.cc -- implement Tuplet_engraver + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 1998--2009 Han-Wen Nienhuys - (c) 1998--2006 Han-Wen Nienhuys + 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" @@ -15,6 +26,7 @@ #include "tuplet-bracket.hh" #include "warn.hh" #include "item.hh" +#include "moment.hh" #include "translator.icc" @@ -26,6 +38,9 @@ struct Tuplet_description bool full_length_; bool full_length_note_; + Moment stop_moment_; + Moment start_moment_; + Moment length_; Tuplet_description () { @@ -64,21 +79,53 @@ Tuplet_engraver::listen_tuplet_span (Stream_event *ev) { 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++) + { + /* + discard duplicates. + */ + if (new_tuplets_[i].stop_moment_ == d.stop_moment_) + return; + } + new_tuplets_.push_back (d); } - else if (dir == STOP && tuplets_.size ()) + else if (dir == STOP) { - stopped_tuplets_.push_back (tuplets_.back ()); - tuplets_.pop_back (); + if (tuplets_.size ()) + { + stopped_tuplets_.push_back (tuplets_.back ()); + tuplets_.pop_back (); + } + else if (!to_boolean (get_property ("skipTypesetting"))) + ev->origin ()->warning (_ ("No tuplet to end")); } else - programming_error (_f ("direction of %s invalid: %d", - "tuplet-span-event", int (dir))); + 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++) { Spanner *bracket = stopped_tuplets_[i].bracket_; @@ -97,11 +144,16 @@ Tuplet_engraver::process_music () } else if (!bracket->get_bound (RIGHT)) { - bracket->set_bound (RIGHT, - bracket->get_bound (LEFT)); - number->set_bound (RIGHT, - stopped_tuplets_[i].bracket_->get_bound (LEFT)); - } + if (bracket->get_bound (LEFT)) + { + bracket->set_bound (RIGHT, + bracket->get_bound (LEFT)); + number->set_bound (RIGHT, + stopped_tuplets_[i].bracket_->get_bound (LEFT)); + } + else + programming_error ("stopped tuplet bracket has left nor right bound."); + } // todo: scrap last_tuplets_, use stopped_tuplets_ only. // clear stopped_tuplets_ at start_translation_timestep last_tuplets_.push_back (bracket); @@ -131,8 +183,10 @@ Tuplet_engraver::process_music () 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_) @@ -157,6 +211,10 @@ void Tuplet_engraver::start_translation_timestep () { last_tuplets_.clear (); + /* + May seem superfluous, but necessary for skipTypesetting. + */ + new_tuplets_.clear (); } void @@ -176,11 +234,17 @@ Tuplet_engraver::Tuplet_engraver () ADD_ACKNOWLEDGER (Tuplet_engraver, note_column); ADD_TRANSLATOR (Tuplet_engraver, - /* doc */ "Catch TupletSpannerEvent and generate appropriate bracket ", + /* doc */ + "Catch tuplet events and generate appropriate bracket.", + /* create */ "TupletBracket " "TupletNumber ", + /* read */ "tupletFullLength " "tupletFullLengthNote ", - /* write */ ""); + + /* write */ + "" + );