Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(41)

Side by Side Diff: lily/slur-engraver.cc

Issue 6498077: Approximates cross-staff slurs in VerticalAxisGroup vertical-skylines. Base URL: http://git.savannah.gnu.org/gitweb/?p=lilypond.git/trunk/
Patch Set: Removes some cruft Created 12 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lily/slur-configuration.cc ('k') | lily/slur-scoring.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 This file is part of LilyPond, the GNU music typesetter. 2 This file is part of LilyPond, the GNU music typesetter.
3 3
4 Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl> 4 Copyright (C) 1997--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 5
6 LilyPond is free software: you can redistribute it and/or modify 6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or 8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
(...skipping 12 matching lines...) Expand all
23 #include "directional-element-interface.hh" 23 #include "directional-element-interface.hh"
24 #include "international.hh" 24 #include "international.hh"
25 #include "note-column.hh" 25 #include "note-column.hh"
26 #include "slur.hh" 26 #include "slur.hh"
27 #include "spanner.hh" 27 #include "spanner.hh"
28 #include "stream-event.hh" 28 #include "stream-event.hh"
29 #include "warn.hh" 29 #include "warn.hh"
30 30
31 #include "translator.icc" 31 #include "translator.icc"
32 32
33 #include <algorithm>
34
33 /* 35 /*
34 NOTE NOTE NOTE 36 NOTE NOTE NOTE
35 37
36 This is largely similar to Phrasing_slur_engraver. Check if fixes 38 This is largely similar to Phrasing_slur_engraver. Check if fixes
37 apply there too. 39 apply there too.
38 40
39 (on principle, engravers don't use inheritance for code sharing) 41 (on principle, engravers don't use inheritance for code sharing)
40 42
41 */ 43 */
42 44
43 /* 45 /*
44 It is possible that a slur starts and ends on the same note. At 46 It is possible that a slur starts and ends on the same note. At
45 least, it is for phrasing slurs: a note can be both beginning and 47 least, it is for phrasing slurs: a note can be both beginning and
46 ending of a phrase. 48 ending of a phrase.
47 */ 49 */
50
51 Slur_info::Slur_info (Grob *slur)
52 {
53 slur_ = slur;
54 }
55
48 class Slur_engraver : public Engraver 56 class Slur_engraver : public Engraver
49 { 57 {
50 vector<Stream_event *> start_events_; 58 vector<Stream_event *> start_events_;
51 vector<Stream_event *> stop_events_; 59 vector<Stream_event *> stop_events_;
52 vector<Grob *> slurs_; 60 vector<Slur_info> slur_infos_;
53 vector<Grob *> end_slurs_; 61 vector<Slur_info> end_slur_infos_;
54 vector<Grob_info> objects_to_acknowledge_; 62 vector<Grob_info> objects_to_acknowledge_;
55 63
56 void set_melisma (bool); 64 void set_melisma (bool);
57 65
58 protected: 66 protected:
59 DECLARE_TRANSLATOR_LISTENER (slur); 67 DECLARE_TRANSLATOR_LISTENER (slur);
60 DECLARE_ACKNOWLEDGER (inline_accidental); 68 DECLARE_ACKNOWLEDGER (inline_accidental);
61 DECLARE_ACKNOWLEDGER (fingering); 69 DECLARE_ACKNOWLEDGER (fingering);
62 DECLARE_ACKNOWLEDGER (note_column); 70 DECLARE_ACKNOWLEDGER (note_column);
63 DECLARE_ACKNOWLEDGER (script); 71 DECLARE_ACKNOWLEDGER (script);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 void 114 void
107 Slur_engraver::set_melisma (bool m) 115 Slur_engraver::set_melisma (bool m)
108 { 116 {
109 context ()->set_property ("slurMelismaBusy", m ? SCM_BOOL_T : SCM_BOOL_F); 117 context ()->set_property ("slurMelismaBusy", m ? SCM_BOOL_T : SCM_BOOL_F);
110 } 118 }
111 119
112 void 120 void
113 Slur_engraver::acknowledge_note_column (Grob_info info) 121 Slur_engraver::acknowledge_note_column (Grob_info info)
114 { 122 {
115 Grob *e = info.grob (); 123 Grob *e = info.grob ();
116 for (vsize i = slurs_.size (); i--;) 124 for (vsize i = slur_infos_.size (); i--;)
117 Slur::add_column (slurs_[i], e); 125 {
118 for (vsize i = end_slurs_.size (); i--;) 126 Slur::add_column (slur_infos_[i].slur_, e);
119 Slur::add_column (end_slurs_[i], e); 127 Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
128 slur_infos_[i].stubs_.push_back (stub);
129 }
130 for (vsize i = end_slur_infos_.size (); i--;)
131 {
132 Slur::add_column (end_slur_infos_[i].slur_, e);
133 Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
134 end_slur_infos_[i].stubs_.push_back (stub);
135 }
120 } 136 }
121 137
122 void 138 void
123 Slur_engraver::acknowledge_extra_object (Grob_info info) 139 Slur_engraver::acknowledge_extra_object (Grob_info info)
124 { 140 {
125 objects_to_acknowledge_.push_back (info); 141 objects_to_acknowledge_.push_back (info);
126 } 142 }
127 143
128 void 144 void
129 Slur_engraver::acknowledge_inline_accidental (Grob_info info) 145 Slur_engraver::acknowledge_inline_accidental (Grob_info info)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 180
165 void 181 void
166 Slur_engraver::acknowledge_tie (Grob_info info) 182 Slur_engraver::acknowledge_tie (Grob_info info)
167 { 183 {
168 acknowledge_extra_object (info); 184 acknowledge_extra_object (info);
169 } 185 }
170 186
171 void 187 void
172 Slur_engraver::finalize () 188 Slur_engraver::finalize ()
173 { 189 {
174 for (vsize i = 0; i < slurs_.size (); i++) 190 for (vsize i = 0; i < slur_infos_.size (); i++)
175 { 191 {
176 slurs_[i]->warning (_ ("unterminated slur")); 192 slur_infos_[i].slur_->warning (_ ("unterminated slur"));
177 slurs_[i]->suicide (); 193 slur_infos_[i].slur_->suicide ();
194 for (vsize j = 0; j < slur_infos_[i].stubs_.size (); j++)
195 slur_infos_[i].stubs_[j]->suicide ();
178 } 196 }
179 slurs_.clear (); 197
198 slur_infos_.clear ();
180 } 199 }
181 200
182 void 201 void
183 Slur_engraver::process_music () 202 Slur_engraver::process_music ()
184 { 203 {
185 for (vsize i = 0; i < stop_events_.size (); i++) 204 for (vsize i = 0; i < stop_events_.size (); i++)
186 { 205 {
187 Stream_event *ev = stop_events_[i]; 206 Stream_event *ev = stop_events_[i];
188 string id = robust_scm2string (ev->get_property ("spanner-id"), ""); 207 string id = robust_scm2string (ev->get_property ("spanner-id"), "");
189 208
190 // Find the slurs that are ended with this event (by checking the spanner- id) 209 // Find the slurs that are ended with this event (by checking the spanner- id)
191 bool ended = false; 210 bool ended = false;
192 for (vsize j = slurs_.size (); j--;) 211 for (vsize j = slur_infos_.size (); j--;)
193 { 212 {
194 if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), " ")) 213 if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("span ner-id"), ""))
195 { 214 {
196 ended = true; 215 ended = true;
197 end_slurs_.push_back (slurs_[j]); 216 end_slur_infos_.push_back (slur_infos_[j]);
198 slurs_.erase (slurs_.begin () + j); 217 slur_infos_.erase (slur_infos_.begin () + j);
199 } 218 }
200 } 219 }
201 if (ended) 220 if (ended)
202 { 221 {
203 // Ignore redundant stop events for this id 222 // Ignore redundant stop events for this id
204 for (vsize j = stop_events_.size (); --j > i;) 223 for (vsize j = stop_events_.size (); --j > i;)
205 { 224 {
206 if (id == robust_scm2string (stop_events_[j]->get_property ("spann er-id"), "")) 225 if (id == robust_scm2string (stop_events_[j]->get_property ("spann er-id"), ""))
207 stop_events_.erase (stop_events_.begin () + j); 226 stop_events_.erase (stop_events_.begin () + j);
208 } 227 }
209 } 228 }
210 else 229 else
211 ev->origin ()->warning (_ ("cannot end slur")); 230 ev->origin ()->warning (_ ("cannot end slur"));
212 } 231 }
213 232
214 vsize old_slurs = slurs_.size (); 233 vsize old_slurs = slur_infos_.size ();
215 for (vsize i = start_events_.size (); i--;) 234 for (vsize i = start_events_.size (); i--;)
216 { 235 {
217 Stream_event *ev = start_events_[i]; 236 Stream_event *ev = start_events_[i];
218 string id = robust_scm2string (ev->get_property ("spanner-id"), ""); 237 string id = robust_scm2string (ev->get_property ("spanner-id"), "");
219 Direction updown = to_dir (ev->get_property ("direction")); 238 Direction updown = to_dir (ev->get_property ("direction"));
220 239
221 bool completed; 240 bool completed;
222 for (vsize j = slurs_.size (); !(completed = (j-- == 0));) 241 for (vsize j = slur_infos_.size (); !(completed = (j-- == 0));)
223 { 242 {
224 // Check if we already have a slur with the same spanner-id. 243 // Check if we already have a slur with the same spanner-id.
225 if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), " ")) 244 if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("span ner-id"), ""))
226 { 245 {
227 if (j < old_slurs) 246 if (j < old_slurs)
228 { 247 {
229 // We already have an old slur, so give a warning 248 // We already have an old slur, so give a warning
230 // and completely ignore the new slur. 249 // and completely ignore the new slur.
231 ev->origin ()->warning (_ ("already have slur")); 250 ev->origin ()->warning (_ ("already have slur"));
232 start_events_.erase (start_events_.begin () + i); 251 start_events_.erase (start_events_.begin () + i);
233 break; 252 break;
234 } 253 }
235 254
236 // If this slur event has no direction, it will not 255 // If this slur event has no direction, it will not
237 // contribute anything new to the existing slur(s), so 256 // contribute anything new to the existing slur(s), so
238 // we can ignore it. 257 // we can ignore it.
239 258
240 if (!updown) 259 if (!updown)
241 break; 260 break;
242 261
243 Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("c ause")); 262 Stream_event *c = unsmob_stream_event (slur_infos_[j].slur_->get_p roperty ("cause"));
244 263
245 if (!c) 264 if (!c)
246 { 265 {
247 slurs_[j]->programming_error ("slur without a cause"); 266 slur_infos_[j].slur_->programming_error ("slur without a cause ");
248 continue; 267 continue;
249 } 268 }
250 269
251 Direction slur_dir = to_dir (c->get_property ("direction")); 270 Direction slur_dir = to_dir (c->get_property ("direction"));
252 271
253 // If the existing slur does not have a direction yet, 272 // If the existing slur does not have a direction yet,
254 // we'd rather take the new one. 273 // we'd rather take the new one.
255 274
256 if (!slur_dir) 275 if (!slur_dir)
257 { 276 {
258 slurs_[j]->suicide (); 277 slur_infos_[j].slur_->suicide ();
259 slurs_.erase (slurs_.begin () + j); 278 for (vsize k = 0; k < slur_infos_[j].stubs_.size (); k++)
279 slur_infos_[j].stubs_[k]->suicide ();
280 slur_infos_.erase (slur_infos_.begin () + j);
260 continue; 281 continue;
261 } 282 }
262 283
263 // If the existing slur has the same direction as ours, drop ours 284 // If the existing slur has the same direction as ours, drop ours
264 285
265 if (slur_dir == updown) 286 if (slur_dir == updown)
266 break; 287 break;
267 } 288 }
268 } 289 }
269 // If the loop completed, our slur is new 290 // If the loop completed, our slur is new
270 if (completed) 291 if (completed)
271 { 292 {
272 Grob *slur = make_spanner ("Slur", ev->self_scm ()); 293 Grob *slur = make_spanner ("Slur", ev->self_scm ());
273 slur->set_property ("spanner-id", ly_string2scm (id)); 294 slur->set_property ("spanner-id", ly_string2scm (id));
274 if (updown) 295 if (updown)
275 set_grob_direction (slur, updown); 296 set_grob_direction (slur, updown);
276 slurs_.push_back (slur); 297 slur_infos_.push_back (Slur_info (slur));
277 298
278 if (to_boolean (get_property ("doubleSlurs"))) 299 if (to_boolean (get_property ("doubleSlurs")))
279 { 300 {
280 set_grob_direction (slur, DOWN); 301 set_grob_direction (slur, DOWN);
281 slur = make_spanner ("Slur", ev->self_scm ()); 302 slur = make_spanner ("Slur", ev->self_scm ());
282 slur->set_property ("spanner-id", ly_string2scm (id)); 303 slur->set_property ("spanner-id", ly_string2scm (id));
283 set_grob_direction (slur, UP); 304 set_grob_direction (slur, UP);
284 slurs_.push_back (slur); 305 slur_infos_.push_back (Slur_info (slur));
285 } 306 }
286 } 307 }
287 } 308 }
288 set_melisma (slurs_.size ()); 309 set_melisma (slur_infos_.size ());
289 } 310 }
290 311
291 void 312 void
292 Slur_engraver::stop_translation_timestep () 313 Slur_engraver::stop_translation_timestep ()
293 { 314 {
294 if (Grob *g = unsmob_grob (get_property ("currentCommandColumn"))) 315 if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
295 { 316 {
296 for (vsize i = 0; i < end_slurs_.size (); i++) 317 for (vsize i = 0; i < end_slur_infos_.size (); i++)
297 Slur::add_extra_encompass (end_slurs_[i], g); 318 Slur::add_extra_encompass (end_slur_infos_[i].slur_, g);
298 319
299 if (!start_events_.size ()) 320 if (!start_events_.size ())
300 for (vsize i = 0; i < slurs_.size (); i++) 321 for (vsize i = 0; i < slur_infos_.size (); i++)
301 Slur::add_extra_encompass (slurs_[i], g); 322 Slur::add_extra_encompass (slur_infos_[i].slur_, g);
302 } 323 }
303 324
304 for (vsize i = 0; i < end_slurs_.size (); i++) 325 for (vsize i = 0; i < end_slur_infos_.size (); i++)
305 { 326 {
306 Spanner *s = dynamic_cast<Spanner *> (end_slurs_[i]); 327 Spanner *s = dynamic_cast<Spanner *> (end_slur_infos_[i].slur_);
307 if (!s->get_bound (RIGHT)) 328 if (!s->get_bound (RIGHT))
308 s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")) ); 329 s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")) );
309 announce_end_grob (s, SCM_EOL); 330 announce_end_grob (s, SCM_EOL);
310 } 331 }
311 332
312 for (vsize i = 0; i < objects_to_acknowledge_.size (); i++) 333 for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
313 Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_ , end_slurs_); 334 Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slur_i nfos_, end_slur_infos_);
335
336 for (vsize i = 0; i < end_slur_infos_.size (); i++)
337 {
338 // There are likely SlurStubs we don't need. Get rid of them.
339 vector<Grob *> vags;
340 vector<Grob *> stubs;
341 for (vsize j = 0; j < end_slur_infos_[i].stubs_.size (); j++)
342 {
343 Grob *stub = end_slur_infos_[i].stubs_[j];
344 Grob *vag = Grob::get_vertical_axis_group (stub);
345 if (vag)
346 {
347 vector<Grob *>::const_iterator it =
348 find (vags.begin (), vags.end (), vag);
349 if (it != vags.end ())
350 stub->suicide ();
351 else
352 {
353 vags.push_back (vag);
354 stubs.push_back (stub);
355 }
356 }
357 else
358 {
359 end_slur_infos_[i].slur_->programming_error ("Cannot find vertical axis group for NoteColumn.");
360 stub->suicide ();
361 }
362 }
363 for (vsize j = 0; j < stubs.size (); j++)
364 Slur::main_to_stub (end_slur_infos_[i].slur_, stubs[j]);
365 }
314 366
315 objects_to_acknowledge_.clear (); 367 objects_to_acknowledge_.clear ();
316 end_slurs_.clear (); 368 end_slur_infos_.clear ();
317 start_events_.clear (); 369 start_events_.clear ();
318 stop_events_.clear (); 370 stop_events_.clear ();
319 } 371 }
320 372
321 ADD_ACKNOWLEDGER (Slur_engraver, inline_accidental); 373 ADD_ACKNOWLEDGER (Slur_engraver, inline_accidental);
322 ADD_ACKNOWLEDGER (Slur_engraver, fingering); 374 ADD_ACKNOWLEDGER (Slur_engraver, fingering);
323 ADD_ACKNOWLEDGER (Slur_engraver, note_column); 375 ADD_ACKNOWLEDGER (Slur_engraver, note_column);
324 ADD_ACKNOWLEDGER (Slur_engraver, script); 376 ADD_ACKNOWLEDGER (Slur_engraver, script);
325 ADD_ACKNOWLEDGER (Slur_engraver, text_script); 377 ADD_ACKNOWLEDGER (Slur_engraver, text_script);
326 ADD_ACKNOWLEDGER (Slur_engraver, dots); 378 ADD_ACKNOWLEDGER (Slur_engraver, dots);
327 ADD_ACKNOWLEDGER (Slur_engraver, tie); 379 ADD_ACKNOWLEDGER (Slur_engraver, tie);
328 ADD_ACKNOWLEDGER (Slur_engraver, tuplet_number); 380 ADD_ACKNOWLEDGER (Slur_engraver, tuplet_number);
329 ADD_TRANSLATOR (Slur_engraver, 381 ADD_TRANSLATOR (Slur_engraver,
330 /* doc */ 382 /* doc */
331 "Build slur grobs from slur events.", 383 "Build slur grobs from slur events.",
332 384
333 /* create */ 385 /* create */
334 "Slur ", 386 "Slur ",
335 387
336 /* read */ 388 /* read */
337 "slurMelismaBusy " 389 "slurMelismaBusy "
338 "doubleSlurs ", 390 "doubleSlurs ",
339 391
340 /* write */ 392 /* write */
341 "" 393 ""
342 ); 394 );
OLDNEW
« no previous file with comments | « lily/slur-configuration.cc ('k') | lily/slur-scoring.cc » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b