2 repeat-engraver.cc -- implement Repeat_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--1999 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "repeat-engraver.hh"
11 #include "bar-engraver.hh"
12 #include "musical-request.hh"
13 #include "multi-measure-rest.hh"
14 #include "command-request.hh"
15 #include "time-description.hh"
16 #include "engraver-group-engraver.hh"
17 #include "new-repeated-music.hh"
18 #include "time-description.hh"
19 #include "volta-spanner.hh"
20 #include "note-column.hh"
21 #include "paper-def.hh"
22 #include "music-list.hh"
24 ADD_THIS_TRANSLATOR (Repeat_engraver);
29 - Logic needs to be moved out of do_try_music(),
31 - don't try to do multiple repeated music. Lets assume repeats don't nest.
35 Repeat_engraver::do_try_music (Music* m)
37 if (Repeated_music* r = dynamic_cast<Repeated_music *> (m))
39 if (repeated_music_l_)
41 m->warning ("Already have repeated music.");
47 repeated_music_l_ = r;
55 Walk through repeat music, and generate events for appropriate times.
58 Repeat_engraver::queue_events ()
60 Music_sequence* alt = repeated_music_l_->alternatives_p_;
61 Moment walk_mom = now_mom () + repeated_music_l_->repeat_body_p_->length_mom ();
64 Cons_list<Bar_create_event> becel;
65 becel.append (new Bar_create_event (now_mom (), "|:"));
69 becel.append (new Bar_create_event (walk_mom, ":|"));
70 becel.append (new Bar_create_event (walk_mom, "stop"));
75 int volta_number = repeated_music_l_->repeats_i_ - alt->length_i () + 1;
78 all repeat alternatives, and generate events with
79 appropriate timestamps. The volta spanner event (a number string)
80 happens at the begin of the alt. The :| bar event at the ending.
82 for (Cons<Music> *i = alt->music_p_list_p_->head_; i; i = i->next_)
86 some idiot might typeset a repeat not starting on a
87 barline. Make sure there is one.
89 (todo: should try to avoid line breaks?)
93 becel.append (new Bar_create_event (walk_mom, ""));
97 Bar_create_event * c = new Bar_create_event (walk_mom, last_number+ 1,
104 last_number = volta_number;
107 // should think about voltaSpannerDuration
108 walk_mom += i->car_->length_mom();
111 becel.append (new Bar_create_event (walk_mom, ":|"));
113 becel.append (new Bar_create_event (walk_mom, "stop"));
116 create_barmoments_queue_ = becel.head_ ;
121 Repeat_engraver::do_process_requests ()
123 if (repeated_music_l_ && !done_this_one_b_)
126 done_this_one_b_ = true;
130 Cons<Bar_create_event> * head = create_barmoments_queue_;
134 Bar_engraver* bar_engraver_l = dynamic_cast <Bar_engraver*>
135 (daddy_grav_l ()->get_simple_translator ("Bar_engraver"));
138 Do all the events that need to be done now.
141 while (head && now_mom () == head->car_->when_)
143 create_barmoments_queue_ = create_barmoments_queue_->next_;
147 String t = head->car_->type_;
148 if (head->car_->bar_b_)
150 if (t == "stop" || t == ":|")
152 end_volta_span_p_ = volta_span_p_;
157 bar_engraver_l->request_bar (t);
161 assert (!volta_span_p_);
162 volta_span_p_ = new Volta_spanner;
163 announce_element (Score_element_info (volta_span_p_,0));
164 volta_span_p_->number_str_ = t;
165 volta_span_p_->last_b_ = head->car_->last_b_;
166 // voltaSpannerDuration stuff here.
167 // other property stuff here.
173 warning ("No bar engraver found. Ignoring repeats.");
179 head = create_barmoments_queue_;
182 assert (!head || head->car_->when_ > now_mom ());
187 Repeat_engraver::acknowledge_element (Score_element_info i)
189 if (Note_column *c = dynamic_cast<Note_column *> (i.elem_l_))
192 volta_span_p_->add_column (c);
193 if (end_volta_span_p_)
194 end_volta_span_p_->add_column (c);
196 if (Bar *c = dynamic_cast<Bar*> (i.elem_l_))
199 volta_span_p_->add_bar (c);
200 if (end_volta_span_p_)
201 end_volta_span_p_ ->add_bar(c);
207 Repeat_engraver::do_removal_processing ()
211 typeset_element(volta_span_p_);
213 if (end_volta_span_p_)
215 typeset_element (end_volta_span_p_);
217 // todo: the paranoid may also delete create_barmoments_queue_
221 Repeat_engraver::do_post_move_processing ()
223 for (Cons<Bar_create_event> *p = create_barmoments_queue_;
224 p && p->car_->when_ == now_mom (); p = p->next_)
225 if (p->car_->type_ == "stop")
227 repeated_music_l_ = 0;
228 done_this_one_b_ = false;
233 Repeat_engraver::do_pre_move_processing ()
235 if (end_volta_span_p_)
237 typeset_element (end_volta_span_p_ );
238 end_volta_span_p_ =0;
244 Repeat_engraver::Repeat_engraver()
246 repeated_music_l_ =0;
247 end_volta_span_p_ =0;
249 done_this_one_b_ = false;
250 create_barmoments_queue_ =0;
254 Bar_create_event::Bar_create_event()
260 Bar_create_event::Bar_create_event (Moment w, String s)
268 Bar_create_event::Bar_create_event (Moment w, int i, int j)
275 type_ = to_str (i) + ".-" ;
277 type_ += to_str(j) + ".";