*** empty log message ***
[lilypond.git] / lily / percent-repeat-engraver.cc
blob3090e9b615cce4ab84fe4f5d109bbf0b7a40d555
1 /*
2 new-chord-tremolo-engraver.cc -- implement Chord_tremolo_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2004 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-context.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 "context.hh"
25 /**
26 This acknowledges repeated music with "percent" style. It typesets
27 a % sign.
29 TODO:
31 - BEAT case: Create items for single beat repeats, i.e. c4 / / /
33 - DOUBLE_MEASURE case: attach a % to an appropriate barline.
36 class Percent_repeat_engraver : public Engraver
38 void typeset_perc ();
39 public:
40 TRANSLATOR_DECLARATIONS (Percent_repeat_engraver);
41 protected:
42 Repeated_music * repeat_;
44 /// moment (global time) where beam started.
45 Moment start_mom_;
46 Moment stop_mom_;
48 /// location within measure where beam started.
49 Moment beam_start_location_;
50 Moment next_moment_;
51 Moment body_length_;
53 enum {
54 UNKNOWN,
55 MEASURE,
56 DOUBLE_MEASURE,
57 } repeat_sign_type_ ;
59 Item * double_percent_;
60 Spanner * perc_;
61 Spanner * finished_perc_;
62 protected:
63 virtual void finalize ();
64 virtual bool try_music (Music*);
65 virtual void stop_translation_timestep ();
66 virtual void start_translation_timestep ();
67 virtual void process_music ();
70 Percent_repeat_engraver::Percent_repeat_engraver ()
72 perc_ = 0;
73 finished_perc_ = 0;
74 repeat_ =0;
76 double_percent_ = 0;
79 bool
80 Percent_repeat_engraver::try_music (Music * m)
82 Repeated_music * rp = dynamic_cast<Repeated_music*> (m);
83 if (rp
84 && rp->get_property ("iterator-ctor")
85 == Percent_repeat_iterator::constructor_proc
86 && !repeat_)
88 body_length_ = rp->body_get_length ();
89 int count = rp->repeat_count ();
91 Moment now = now_mom ();
92 start_mom_ = now;
93 stop_mom_ = start_mom_ + Moment (count) * body_length_;
94 next_moment_ = start_mom_ + body_length_;
96 SCM m = get_property ("measureLength");
97 Moment meas_len;
98 if (unsmob_moment (m))
99 meas_len = *unsmob_moment (m);
101 if (meas_len == body_length_)
102 repeat_sign_type_ = MEASURE;
103 else if (Moment (2)* meas_len == body_length_)
105 repeat_sign_type_ = DOUBLE_MEASURE;
106 next_moment_ += meas_len ;
108 else
110 warning (_ ("Don't know how to handle a percent repeat of this length."));
111 return false;
114 repeat_ = rp;
117 Global_context *global = get_global_context ();
118 for (int i = 0; i < count; i++)
119 global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
121 return true;
124 return false;
127 void
128 Percent_repeat_engraver::process_music ()
130 if (repeat_ && now_mom () == next_moment_)
132 if (repeat_sign_type_ == MEASURE)
134 finished_perc_ = perc_;
135 typeset_perc ();
136 perc_ = make_spanner ("PercentRepeat");
137 SCM col =get_property ("currentCommandColumn");
138 perc_->set_bound (LEFT, unsmob_grob (col));
139 announce_grob (perc_, repeat_->self_scm ());
141 else if (repeat_sign_type_ == DOUBLE_MEASURE)
143 double_percent_ = make_item ("DoublePercentRepeat");
144 announce_grob (double_percent_, repeat_->self_scm ());
147 forbid breaks on a % line. Should forbid all breaks, really.
150 get_score_engraver ()->forbid_breaks (); // guh. Use properties!
152 next_moment_ = next_moment_ + body_length_;
154 get_global_context ()->add_moment_to_process (next_moment_);
158 void
159 Percent_repeat_engraver::finalize ()
161 typeset_perc ();
162 if (perc_)
164 repeat_->origin ()->warning (_ ("unterminated percent repeat"));
165 perc_->suicide ();
169 void
170 Percent_repeat_engraver::typeset_perc ()
172 if (finished_perc_)
174 SCM col =get_property ("currentCommandColumn");
175 finished_perc_->set_bound (RIGHT, unsmob_grob (col));
176 typeset_grob (finished_perc_);
177 finished_perc_ = 0;
180 if (double_percent_)
182 typeset_grob (double_percent_);
183 double_percent_ = 0;
190 void
191 Percent_repeat_engraver::start_translation_timestep ()
193 if (stop_mom_ == now_mom ())
195 if (perc_)
197 finished_perc_ = perc_;
198 typeset_perc ();
200 repeat_ = 0;
201 perc_ = 0;
202 repeat_sign_type_ = UNKNOWN;
207 void
208 Percent_repeat_engraver::stop_translation_timestep ()
210 typeset_perc ();
216 ENTER_DESCRIPTION (Percent_repeat_engraver,
217 /* descr */ "Make whole bar and double bar repeats.",
218 /* creats*/ "PercentRepeat DoublePercentRepeat",
219 /* accepts */ "repeated-music",
220 /* acks */ "",
221 /* reads */ "measureLength currentCommandColumn",
222 /* write */ "");