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 "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
);
27 Repeat_engraver::do_try_music (Music
* m
)
29 if (Repeated_music
* r
= dynamic_cast<Repeated_music
*> (m
))
31 if (repeated_music_l_
)
36 repeated_music_l_
= r
;
40 We acknowledge other types of unfolded music as well, to
41 get auto context selection right.
50 Walk through repeat music, and generate events for appropriate times.
53 Repeat_engraver::queue_events ()
55 Music_sequence
* alt
= repeated_music_l_
->alternatives_p_
;
56 Moment walk_mom
= now_mom () + repeated_music_l_
->repeat_body_p_
->length_mom ();
58 bool create_volta
= ! get_property ("noVoltaBraces",0).to_bool ();
60 Cons_list
<Bar_create_event
> becel
;
61 becel
.append (new Bar_create_event (now_mom (), "|:"));
65 becel
.append (new Bar_create_event (walk_mom
, ":|"));
66 becel
.append (new Bar_create_event (walk_mom
, "stop"));
71 int volta_number
= repeated_music_l_
->repeats_i_
- alt
->length_i () + 1;
74 all repeat alternatives, and generate events with
75 appropriate timestamps. The volta spanner event (a number string)
76 happens at the begin of the alt. The :| bar event at the ending.
78 for (Cons
<Music
> *i
= alt
->music_p_list_p_
->head_
; i
; i
= i
->next_
)
82 some idiot might typeset a repeat not starting on a
83 barline. Make sure there is one.
85 (todo: should try to avoid line breaks?)
89 becel
.append (new Bar_create_event (walk_mom
, ""));
95 Bar_create_event
* c
= new Bar_create_event (walk_mom
, last_number
+ 1,
102 last_number
= volta_number
;
105 // should think about voltaSpannerDuration
106 walk_mom
+= i
->car_
->length_mom();
109 becel
.append (new Bar_create_event (walk_mom
, ":|"));
111 becel
.append (new Bar_create_event (walk_mom
, "stop"));
115 Cons
<Bar_create_event
> *&tail
= create_barmoments_queue_
116 ? last_cons (create_barmoments_queue_
)->next_
117 : create_barmoments_queue_
;
124 Repeat_engraver::do_process_requests ()
126 if (repeated_music_l_
&& !done_this_one_b_
)
129 done_this_one_b_
= true;
133 Cons
<Bar_create_event
> * head
= create_barmoments_queue_
;
137 Bar_engraver
* bar_engraver_l
= dynamic_cast <Bar_engraver
*>
138 (daddy_grav_l ()->get_simple_translator ("Bar_engraver"));
141 Do all the events that need to be done now.
143 while (head
&& now_mom () == head
->car_
->when_
)
145 create_barmoments_queue_
= create_barmoments_queue_
->next_
;
149 String t
= head
->car_
->type_
;
150 if (head
->car_
->bar_b_
)
152 if (t
== "stop" || t
== ":|")
154 end_volta_span_p_
= volta_span_p_
;
159 bar_engraver_l
->request_bar (t
);
161 bar_engraver_l
->request_bar ("");
165 assert (!volta_span_p_
);
166 volta_span_p_
= new Volta_spanner
;
167 announce_element (Score_element_info (volta_span_p_
,0));
168 volta_span_p_
->number_str_
= t
;
169 volta_span_p_
->last_b_
= head
->car_
->last_b_
;
170 // voltaSpannerDuration stuff here.
171 // other property stuff here.
177 warning ("No bar engraver found. Ignoring repeats.");
183 head
= create_barmoments_queue_
;
186 assert (!head
|| head
->car_
->when_
> now_mom ());
191 Repeat_engraver::acknowledge_element (Score_element_info i
)
193 if (Note_column
*c
= dynamic_cast<Note_column
*> (i
.elem_l_
))
196 volta_span_p_
->add_column (c
);
197 if (end_volta_span_p_
)
198 end_volta_span_p_
->add_column (c
);
200 if (Bar
*c
= dynamic_cast<Bar
*> (i
.elem_l_
))
203 volta_span_p_
->add_bar (c
);
204 if (end_volta_span_p_
)
205 end_volta_span_p_
->add_bar(c
);
211 Repeat_engraver::do_removal_processing ()
215 typeset_element(volta_span_p_
);
217 if (end_volta_span_p_
)
219 typeset_element (end_volta_span_p_
);
221 // todo: the paranoid may also delete create_barmoments_queue_
225 Repeat_engraver::do_post_move_processing ()
227 for (Cons
<Bar_create_event
> *p
= create_barmoments_queue_
;
228 p
&& p
->car_
->when_
== now_mom (); p
= p
->next_
)
229 if (p
->car_
->type_
== "stop")
231 repeated_music_l_
= 0;
232 done_this_one_b_
= false;
237 Repeat_engraver::do_pre_move_processing ()
239 if (end_volta_span_p_
)
241 typeset_element (end_volta_span_p_
);
242 end_volta_span_p_
=0;
248 Repeat_engraver::Repeat_engraver()
250 repeated_music_l_
=0;
251 end_volta_span_p_
=0;
253 done_this_one_b_
= false;
254 create_barmoments_queue_
=0;
258 Bar_create_event::Bar_create_event()
264 Bar_create_event::Bar_create_event (Moment w
, String s
)
272 Bar_create_event::Bar_create_event (Moment w
, int i
, int j
)
279 type_
= to_str (i
) + ".-" ;
281 type_
+= to_str(j
) + ".";