X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fpercent-repeat-engraver.cc;h=eaffc2295cfca282ee94867de5597e1d093cec85;hb=aa23e460ca96734a29387c163e75db4f3980d13f;hp=325f9306b64cc182e59447c0da3f8e19211febd4;hpb=163225c0cbb1055dfd3614615350ab9f3aaba74c;p=lilypond.git diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index 325f9306b6..eaffc2295c 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -1,11 +1,13 @@ -/* - new-chord-tremolo-engraver.cc -- implement Chord_tremolo_engraver - +/* + new-chord-tremolo-engraver.cc -- implement Chord_tremolo_engraver + source file of the GNU LilyPond music typesetter - - (c) 2000--2004 Han-Wen Nienhuys - - */ + + (c) 2000--2005 Han-Wen Nienhuys +*/ + + +#include "score-engraver.hh" #include "repeated-music.hh" #include "global-context.hh" @@ -15,109 +17,116 @@ #include "item.hh" #include "percent-repeat-iterator.hh" #include "bar-line.hh" -#include "score-engraver.hh" +#include "side-position-interface.hh" -/** - This acknowledges repeated music with "percent" style. It typesets - a % sign. +#include "translator.icc" - TODO: - - - BEAT case: Create items for single beat repeats, i.e. c4 / / / - - - DOUBLE_MEASURE case: attach a % to an appropriate barline. - -*/ class Percent_repeat_engraver : public Engraver { void typeset_perc (); public: TRANSLATOR_DECLARATIONS (Percent_repeat_engraver); + protected: - Repeated_music * repeat_; + Music *repeat_; /// moment (global time) where beam started. Moment start_mom_; Moment stop_mom_; - /// location within measure where beam started. + /// location within measure where beam started. Moment beam_start_location_; Moment next_moment_; Moment body_length_; - enum { - UNKNOWN, - MEASURE, - DOUBLE_MEASURE, - } repeat_sign_type_ ; + enum Repeat_sign_type + { + UNKNOWN, + MEASURE, + DOUBLE_MEASURE, + }; + Repeat_sign_type repeat_sign_type_; + + Item *double_percent_; + Item *double_percent_counter_; + + Spanner *percent_; + Spanner *percent_counter_; + Spanner *finished_percent_; + Spanner *finished_percent_counter_; - Item * double_percent_; - Spanner * perc_; - Spanner * finished_perc_; + int count_; + int total_count_; protected: virtual void finalize (); - virtual bool try_music (Music*); - virtual void stop_translation_timestep (); - virtual void start_translation_timestep (); - virtual void process_music (); + virtual bool try_music (Music *); + + void stop_translation_timestep (); + void start_translation_timestep (); + void process_music (); }; Percent_repeat_engraver::Percent_repeat_engraver () { - perc_ = 0; - finished_perc_ = 0; - repeat_ = 0; + percent_ = 0; + percent_counter_ = 0; + + finished_percent_ = 0; + finished_percent_counter_ = 0; double_percent_ = 0; + double_percent_counter_ = 0; + + repeat_ = 0; + count_ = 0; + total_count_ = 0; } bool -Percent_repeat_engraver::try_music (Music * m) +Percent_repeat_engraver::try_music (Music *m) { - Repeated_music * rp = dynamic_cast (m); - if (rp - && rp->get_property ("iterator-ctor") - == Percent_repeat_iterator::constructor_proc + if (m->is_mus_type ("repeated-music") + && m->get_property ("iterator-ctor") + == Percent_repeat_iterator::constructor_proc && !repeat_) { - body_length_ = rp->body_get_length (); - int count = rp->repeat_count (); + body_length_ = Repeated_music::body_get_length (m); + total_count_ = Repeated_music::repeat_count (m); Moment now = now_mom (); start_mom_ = now; - stop_mom_ = start_mom_ + Moment (count) * body_length_; - next_moment_ = start_mom_ + body_length_; + stop_mom_ = start_mom_ + Moment (total_count_) * body_length_; + next_moment_ = start_mom_; + next_moment_ += body_length_; - Moment meas_len (robust_scm2moment (get_property ("measureLength"), Moment (1))); + Moment meas_len (robust_scm2moment (get_property ("measureLength"), + Moment (1))); + if (meas_len == body_length_) repeat_sign_type_ = MEASURE; - else if (Moment (2)* meas_len == body_length_) - { - repeat_sign_type_ = DOUBLE_MEASURE; - next_moment_ += meas_len ; - } + else if (Moment (2) * meas_len == body_length_) + repeat_sign_type_ = DOUBLE_MEASURE; else - { - warning (_ ("Don't know how to handle a percent repeat of this length.")); - return false; - } + return false; + - repeat_ = rp; + repeat_ = m; - Global_context *global = get_global_context (); - for (int i = 0; i < count; i++) + for (int i = 1; i < total_count_; i++) { - global->add_moment_to_process (next_moment_ + Moment (i) * body_length_); + Moment m = next_moment_ + Moment (i) * body_length_; + global->add_moment_to_process (m); - /* - bars between % too. - */ + /* bars between % too. */ if (repeat_sign_type_ == DOUBLE_MEASURE) - global->add_moment_to_process (next_moment_ + meas_len + Moment (i) * body_length_); - + global->add_moment_to_process (m - meas_len); } - + + if (repeat_sign_type_ == DOUBLE_MEASURE) + next_moment_ += meas_len; + + count_ = 1; return true; } @@ -129,26 +138,64 @@ Percent_repeat_engraver::process_music () { if (repeat_ && now_mom () == next_moment_) { + count_ ++; if (repeat_sign_type_ == MEASURE) { - finished_perc_ = perc_; + finished_percent_ = percent_; + finished_percent_counter_ = percent_counter_; + typeset_perc (); - perc_ = make_spanner ("PercentRepeat", repeat_->self_scm ()); - SCM col =get_property ("currentCommandColumn"); - perc_->set_bound (LEFT, unsmob_grob (col)); + percent_ = make_spanner ("PercentRepeat", repeat_->self_scm ()); + + Grob *col = unsmob_grob (get_property ("currentCommandColumn")); + percent_->set_bound (LEFT, col); + + if (total_count_ > 2 + && to_boolean (get_property ("countPercentRepeats"))) + { + percent_counter_ + = make_spanner ("PercentRepeatCounter", repeat_->self_scm ()); + + + SCM text = scm_number_to_string (scm_from_int (count_), + scm_from_int (10)); + percent_counter_->set_property ("text", text); + percent_counter_->set_bound (LEFT, col); + Side_position_interface::add_support (percent_counter_, + percent_); + percent_counter_->set_parent (percent_, Y_AXIS); + } } else if (repeat_sign_type_ == DOUBLE_MEASURE) { double_percent_ = make_item ("DoublePercentRepeat", repeat_->self_scm ()); - /* - forbid breaks on a % line. Should forbid all breaks, really. - */ - get_score_engraver ()->forbid_breaks (); // guh. Use properties! + if (total_count_ > 2 + && to_boolean (get_property ("countPercentRepeats"))) + { + double_percent_counter_ + = make_item ("DoublePercentRepeatCounter", + repeat_->self_scm()); + + SCM text = scm_number_to_string (scm_from_int (count_), + scm_from_int (10)); + double_percent_counter_->set_property ("text", text); + + Side_position_interface::add_support (double_percent_counter_, + double_percent_); + double_percent_counter_->set_parent (double_percent_, Y_AXIS); + double_percent_counter_->set_parent (double_percent_, X_AXIS); + } + + /* + forbid breaks on a % line. Should forbid all breaks, really. + + Ugh. Why can't this be regular communication between + contexts? + */ + get_score_engraver ()->forbid_breaks (); } next_moment_ = next_moment_ + body_length_; - - get_global_context ()->add_moment_to_process (next_moment_); } } @@ -156,59 +203,76 @@ void Percent_repeat_engraver::finalize () { typeset_perc (); - if (perc_) + if (percent_) { repeat_->origin ()->warning (_ ("unterminated percent repeat")); - perc_->suicide (); + percent_->suicide (); + percent_counter_->suicide(); } } void Percent_repeat_engraver::typeset_perc () { - if (finished_perc_) + if (finished_percent_) { - SCM col =get_property ("currentCommandColumn"); - finished_perc_->set_bound (RIGHT, unsmob_grob (col)); - finished_perc_ = 0; + Grob *col = unsmob_grob (get_property ("currentCommandColumn")); + + finished_percent_->set_bound (RIGHT, col); + finished_percent_ = 0; + + if (finished_percent_counter_) + finished_percent_counter_->set_bound (RIGHT, col); + + finished_percent_counter_ = 0; } double_percent_ = 0; + double_percent_counter_ = 0; } - - - void Percent_repeat_engraver::start_translation_timestep () { if (stop_mom_ == now_mom ()) { - if (perc_) + if (percent_) { - finished_perc_ = perc_; + finished_percent_ = percent_; + finished_percent_counter_ = percent_counter_; + typeset_perc (); } repeat_ = 0; - perc_ = 0; + percent_ = 0; + + percent_counter_ = 0; repeat_sign_type_ = UNKNOWN; } } - void Percent_repeat_engraver::stop_translation_timestep () { typeset_perc (); } - - - -ENTER_DESCRIPTION (Percent_repeat_engraver, -/* descr */ "Make whole bar and double bar repeats.", -/* creats*/ "PercentRepeat DoublePercentRepeat", -/* accepts */ "repeated-music", -/* acks */ "", -/* reads */ "measureLength currentCommandColumn", -/* write */ ""); +ADD_TRANSLATOR (Percent_repeat_engraver, + /* doc */ + "Make whole bar and double bar repeats.", + + /* create */ + "PercentRepeat " + "DoublePercentRepeat " + "PercentRepeatCounter " + "DoublePercentRepeatCounter", + + /* accept */ + "repeated-music", + + /* read */ + "measureLength " + "currentCommandColumn " + "countPercentRepeats", + + /* write */ "");