-/*
- 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--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-#include "engraver.hh"
+ (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+
+#include "score-engraver.hh"
+
#include "repeated-music.hh"
-#include "engraver-group-engraver.hh"
-#include "global-translator.hh"
+#include "global-context.hh"
#include "warn.hh"
#include "misc.hh"
#include "spanner.hh"
#include "item.hh"
#include "percent-repeat-iterator.hh"
#include "bar-line.hh"
+#include "side-position-interface.hh"
-#include "score-engraver.hh"
-#include "translator-group.hh"
-
-/**
- This acknowledges repeated music with "percent" style. It typesets
- a % sign.
-
- TODO:
-
- - BEAT case: Create items for single beat repeats, i.e. c4 / / /
+#include "translator.icc"
- - DOUBLE_MEASURE case: attach a % to an appropriate barline.
-
-*/
class Percent_repeat_engraver : public Engraver
{
void typeset_perc ();
public:
- TRANSLATOR_DECLARATIONS(Percent_repeat_engraver);
+ 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,
- BEAT,
- MEASURE,
- DOUBLE_MEASURE,
- } repeat_sign_type_ ;
-
- Item * beat_slash_;
- Item * double_percent_;
- Spanner * perc_;
- Spanner * finished_perc_;
- Item * stem_tremolo_;
+ 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_;
+
+ 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_ = finished_perc_ = 0;
- repeat_ =0;
- stem_tremolo_ = 0;
+ percent_ = 0;
+ percent_counter_ = 0;
+
+ finished_percent_ = 0;
+ finished_percent_counter_ = 0;
- beat_slash_ = 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<Repeated_music*> (m);
- if (rp
- && rp->get_mus_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_length_mom ();
- 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_;
-
- SCM m = get_property ("measureLength");
- Moment meas_len;
- if (unsmob_moment (m))
- meas_len = *unsmob_moment (m);
-
- if (body_length_ < meas_len &&
- meas_len.main_part_.mod_rat (body_length_.main_part_) == Moment (Rational (0,0)))
- repeat_sign_type_ = BEAT;
- else if (meas_len == 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)));
+
+ 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_translator *global =0;
- Translator *t = this;
- do
+ Global_context *global = get_global_context ();
+ for (int i = 1; i < total_count_; i++)
{
- t = t->daddy_trans_ ;
- global = dynamic_cast<Global_translator*> (t);
+ Moment m = next_moment_ + Moment (i) * body_length_;
+ global->add_moment_to_process (m);
+
+ /* bars between % too. */
+ if (repeat_sign_type_ == DOUBLE_MEASURE)
+ global->add_moment_to_process (m - meas_len);
}
- while (!global);
- for (int i = 0; i < count; i++)
- global->add_moment_to_process (now + Moment (1+i) * body_length_);
-
+ if (repeat_sign_type_ == DOUBLE_MEASURE)
+ next_moment_ += meas_len;
+
+ count_ = 1;
return true;
}
{
if (repeat_ && now_mom () == next_moment_)
{
- if (repeat_sign_type_ == BEAT)
+ count_ ++;
+ if (repeat_sign_type_ == MEASURE)
{
- beat_slash_ = new Item (get_property ("RepeatSlash"));
- announce_grob(beat_slash_, repeat_->self_scm());
- }
- else if (repeat_sign_type_ == MEASURE)
- {
- finished_perc_ = perc_;
+ finished_percent_ = percent_;
+ finished_percent_counter_ = percent_counter_;
+
typeset_perc ();
- perc_ = new Spanner (get_property ("PercentRepeat"));
- SCM col =get_property ("currentCommandColumn");
- perc_->set_bound (LEFT, unsmob_grob (col));
- announce_grob(perc_, repeat_->self_scm());
+ 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_ = new Item (get_property ("DoublePercentRepeat"));
- announce_grob(double_percent_, repeat_->self_scm());
-
- /*
- forbid breaks on a % line. Should forbid all breaks, really.
- */
-
- top_engraver()->forbid_breaks (); // guh. Use properties!
+ double_percent_ = make_item ("DoublePercentRepeat", repeat_->self_scm ());
+
+ 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_;
}
Percent_repeat_engraver::finalize ()
{
typeset_perc ();
- if (perc_)
+ if (percent_)
{
- repeat_->origin ()->warning (_ ("unterminated chord tremolo"));
- perc_->suicide ();
+ repeat_->origin ()->warning (_ ("unterminated percent repeat"));
+ 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));
- typeset_grob (finished_perc_);
- finished_perc_ = 0;
- }
+ Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
- if (beat_slash_)
- {
- typeset_grob (beat_slash_);
- beat_slash_ = 0;
- }
+ finished_percent_->set_bound (RIGHT, col);
+ finished_percent_ = 0;
- if (double_percent_)
- {
- typeset_grob (double_percent_);
- double_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 beat, whole bar and double bar repeats.",
-/* creats*/ "PercentRepeat RepeatSlash DoublePercentRepeat",
-/* 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 */ "");