(process_acknowledged_grobs):
[lilypond.git] / lily / percent-repeat-engraver.cc
blob517ba465611af3ba8536b89e8a1c3284d5c4d710
1 /*
2 new-chord-tremolo-engraver.cc -- implement Chord_tremolo_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
10 #include "engraver.hh"
11 #include "repeated-music.hh"
12 #include "engraver-group-engraver.hh"
13 #include "global-translator.hh"
14 #include "warn.hh"
15 #include "misc.hh"
16 #include "spanner.hh"
17 #include "item.hh"
18 #include "percent-repeat-iterator.hh"
19 #include "bar-line.hh"
21 #include "score-engraver.hh"
22 #include "translator-group.hh"
24 /**
25 This acknowledges repeated music with "percent" style. It typesets
26 a % sign.
28 TODO:
30 - BEAT case: Create items for single beat repeats, i.e. c4 / / /
32 - DOUBLE_MEASURE case: attach a % to an appropriate barline.
35 class Percent_repeat_engraver : public Engraver
37 void typeset_perc ();
38 public:
39 TRANSLATOR_DECLARATIONS(Percent_repeat_engraver);
40 protected:
41 Repeated_music * repeat_;
43 /// moment (global time) where beam started.
44 Moment start_mom_;
45 Moment stop_mom_;
47 /// location within measure where beam started.
48 Moment beam_start_location_;
49 Moment next_moment_;
50 Moment body_length_;
52 enum {
53 UNKNOWN,
54 MEASURE,
55 DOUBLE_MEASURE,
56 } repeat_sign_type_ ;
58 Item * double_percent_;
59 Spanner * perc_;
60 Spanner * finished_perc_;
61 protected:
62 virtual void finalize ();
63 virtual bool try_music (Music*);
64 virtual void stop_translation_timestep ();
65 virtual void start_translation_timestep ();
66 virtual void process_music ();
69 Percent_repeat_engraver::Percent_repeat_engraver ()
71 perc_ = 0;
72 finished_perc_ = 0;
73 repeat_ =0;
75 double_percent_ = 0;
78 bool
79 Percent_repeat_engraver::try_music (Music * m)
81 Repeated_music * rp = dynamic_cast<Repeated_music*> (m);
82 if (rp
83 && rp->get_mus_property ("iterator-ctor")
84 == Percent_repeat_iterator::constructor_proc
85 && !repeat_)
87 body_length_ = rp->body_get_length ();
88 int count = rp->repeat_count ();
90 Moment now = now_mom ();
91 start_mom_ = now;
92 stop_mom_ = start_mom_ + Moment (count) * body_length_;
93 next_moment_ = start_mom_ + body_length_;
95 SCM m = get_property ("measureLength");
96 Moment meas_len;
97 if (unsmob_moment (m))
98 meas_len = *unsmob_moment (m);
100 if (meas_len == body_length_)
101 repeat_sign_type_ = MEASURE;
102 else if (Moment (2)* meas_len == body_length_)
104 repeat_sign_type_ = DOUBLE_MEASURE;
105 next_moment_ += meas_len ;
107 else
109 warning (_ ("Don't know how to handle a percent repeat of this length."));
110 return false;
113 repeat_ = rp;
116 Global_translator *global =top_engraver();
117 for (int i = 0; i < count; i++)
118 global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
120 return true;
123 return false;
126 void
127 Percent_repeat_engraver::process_music ()
129 if (repeat_ && now_mom () == next_moment_)
131 if (repeat_sign_type_ == MEASURE)
133 finished_perc_ = perc_;
134 typeset_perc ();
135 perc_ = new Spanner (get_property ("PercentRepeat"));
136 SCM col =get_property ("currentCommandColumn");
137 perc_->set_bound (LEFT, unsmob_grob (col));
138 announce_grob(perc_, repeat_->self_scm());
140 else if (repeat_sign_type_ == DOUBLE_MEASURE)
142 double_percent_ = new Item (get_property ("DoublePercentRepeat"));
143 announce_grob(double_percent_, repeat_->self_scm());
146 forbid breaks on a % line. Should forbid all breaks, really.
149 top_engraver()->forbid_breaks (); // guh. Use properties!
151 next_moment_ = next_moment_ + body_length_;
153 top_engraver()->add_moment_to_process (next_moment_);
157 void
158 Percent_repeat_engraver::finalize ()
160 typeset_perc ();
161 if (perc_)
163 repeat_->origin ()->warning (_ ("unterminated percent repeat"));
164 perc_->suicide ();
168 void
169 Percent_repeat_engraver::typeset_perc ()
171 if (finished_perc_)
173 SCM col =get_property ("currentCommandColumn");
174 finished_perc_->set_bound (RIGHT, unsmob_grob (col));
175 typeset_grob (finished_perc_);
176 finished_perc_ = 0;
179 if (double_percent_)
181 typeset_grob (double_percent_);
182 double_percent_ = 0;
189 void
190 Percent_repeat_engraver::start_translation_timestep ()
192 if (stop_mom_ == now_mom ())
194 if (perc_)
196 finished_perc_ = perc_;
197 typeset_perc ();
199 repeat_ = 0;
200 perc_ = 0;
201 repeat_sign_type_ = UNKNOWN;
206 void
207 Percent_repeat_engraver::stop_translation_timestep ()
209 typeset_perc ();
215 ENTER_DESCRIPTION(Percent_repeat_engraver,
216 /* descr */ "Make whole bar and double bar repeats.",
217 /* creats*/ "PercentRepeat DoublePercentRepeat",
218 /* accepts */ "repeated-music",
219 /* acks */ "",
220 /* reads */ "measureLength currentCommandColumn",
221 /* write */ "");