(c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
+
+#include "score-engraver.hh"
+
#include "repeated-music.hh"
#include "global-context.hh"
#include "warn.hh"
#include "item.hh"
#include "percent-repeat-iterator.hh"
#include "bar-line.hh"
-#include "score-engraver.hh"
-
-/**
- This acknowledges repeated music with "percent" style. It typesets
- a % sign.
-
- TODO:
+#include "side-position-interface.hh"
- - 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);
+
protected:
Music *repeat_;
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
+ enum Repeat_sign_type
{
UNKNOWN,
MEASURE,
DOUBLE_MEASURE,
- }
- repeat_sign_type_;
+ };
+ Repeat_sign_type repeat_sign_type_;
Item *double_percent_;
- Spanner *perc_;
- Spanner *finished_perc_;
+ 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 *);
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
&& !repeat_)
{
body_length_ = Repeated_music::body_get_length (m);
- int count = Repeated_music::repeat_count (m);
-
+ total_count_ = Repeated_music::repeat_count (m);
+
Moment now = now_mom ();
start_mom_ = now;
- stop_mom_ = start_mom_ + Moment (count) * body_length_;
+ stop_mom_ = start_mom_ + Moment (total_count_) * body_length_;
next_moment_ = start_mom_ + body_length_;
Moment meas_len (robust_scm2moment (get_property ("measureLength"), Moment (1)));
repeat_ = m;
Global_context *global = get_global_context ();
- for (int i = 1; i < count; i++)
+ for (int i = 1; i < total_count_; i++)
{
Moment m = next_moment_ + Moment (i) * body_length_;
global->add_moment_to_process (m);
if (repeat_sign_type_ == DOUBLE_MEASURE)
next_moment_ += meas_len;
+ count_ = 1;
return true;
}
{
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)
+ {
+ 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 ());
+ if (total_count_ > 2)
+ {
+ 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.
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
{
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;
}
}
typeset_perc ();
}
-#include "translator.icc"
-
ADD_TRANSLATOR (Percent_repeat_engraver,
/* doc */ "Make whole bar and double bar repeats.",
- /* create */ "PercentRepeat DoublePercentRepeat",
+ /* create */
+ "PercentRepeat DoublePercentRepeat "
+ "PercentRepeatCounter DoublePercentRepeatCounter",
/* accept */ "repeated-music",
/* read */ "measureLength currentCommandColumn",
/* write */ "");
break-aligned-interface
percent-repeat-interface))))))
+ (DoublePercentRepeatCounter
+ . ((print-function . ,Text_interface::print)
+ (X-offset-callbacks . (,Self_alignment_interface::aligned_on_self
+ ,Self_alignment_interface::centered_on_other_axis_parent))
+ (Y-offset-callbacks . (,Side_position_interface::aligned_side))
+ (font-encoding . fetaNumber)
+ (self-alignment-X . 0)
+ (font-size . -2)
+ (direction . 1)
+ (padding . 0.2)
+ (staff-padding . 0.25)
+ (meta . ((class . Item)
+ (interfaces . (side-position-interface
+ self-alignment-interface
+ percent-repeat-interface
+ font-interface
+ text-interface))))))
(DynamicLineSpanner
. (
(axes . (1))
(interfaces . (multi-measure-rest-interface
font-interface
percent-repeat-interface))))))
+ (PercentRepeatCounter
+ . ((print-function . ,Text_interface::print)
+ (X-offset-callbacks . (,Self_alignment_interface::aligned_on_self
+ ,Self_alignment_interface::centered_on_other_axis_parent))
+ (Y-offset-callbacks . (,Side_position_interface::aligned_side))
+ (self-alignment-X . 0)
+ (direction . 1)
+ (padding . 0.2)
+ (staff-padding . 0.25)
+ (font-size . -2)
+ (font-encoding . fetaNumber)
+ (meta . ((class . Spanner)
+ (interfaces . (side-position-interface
+ self-alignment-interface
+ percent-repeat-interface
+ font-interface
+ text-interface))))))
;; an example of a text spanner
(PianoPedalBracket