OLD | NEW |
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) 2002--2012 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 2002--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 |
11 LilyPond is distributed in the hope that it will be useful, | 11 LilyPond is distributed in the hope that it will be useful, |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
18 */ | 18 */ |
19 | 19 |
20 #include "accidental-placement.hh" | 20 #include "accidental-placement.hh" |
21 | 21 |
22 #include "accidental-interface.hh" | 22 #include "accidental-interface.hh" |
23 #include "item.hh" | 23 #include "item.hh" |
24 #include "music.hh" | 24 #include "music.hh" |
25 #include "note-collision.hh" | 25 #include "note-collision.hh" |
26 #include "note-column.hh" | 26 #include "note-column.hh" |
27 #include "pointer-group-interface.hh" | 27 #include "pointer-group-interface.hh" |
28 #include "rhythmic-head.hh" | 28 #include "rhythmic-head.hh" |
29 #include "skyline.hh" | 29 #include "skyline.hh" |
| 30 #include "skyline-pair.hh" |
30 #include "stream-event.hh" | 31 #include "stream-event.hh" |
31 #include "warn.hh" | 32 #include "warn.hh" |
32 | 33 |
33 static Pitch * | 34 static Pitch * |
34 accidental_pitch (Grob *acc) | 35 accidental_pitch (Grob *acc) |
35 { | 36 { |
36 SCM cause = acc->get_parent (Y_AXIS)->get_property ("cause"); | 37 SCM cause = acc->get_parent (Y_AXIS)->get_property ("cause"); |
37 | 38 |
38 Stream_event *mcause = unsmob_stream_event (cause); | 39 Stream_event *mcause = unsmob_stream_event (cause); |
39 if (!mcause) | 40 if (!mcause) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 ret.insert (ret.end (), ra.begin (), ra.end ()); | 109 ret.insert (ret.end (), ra.begin (), ra.end ()); |
109 | 110 |
110 if (right) | 111 if (right) |
111 ret.insert (ret.end (), br.begin (), br.end ()); | 112 ret.insert (ret.end (), br.begin (), br.end ()); |
112 } | 113 } |
113 return ret; | 114 return ret; |
114 } | 115 } |
115 | 116 |
116 struct Accidental_placement_entry | 117 struct Accidental_placement_entry |
117 { | 118 { |
118 Skyline left_skyline_; | 119 Skyline_pair horizontal_skylines_; |
119 Skyline right_skyline_; | |
120 Interval vertical_extent_; | |
121 vector<Box> extents_; | |
122 vector<Grob *> grobs_; | 120 vector<Grob *> grobs_; |
123 }; | 121 }; |
124 | 122 |
125 Real ape_priority (Accidental_placement_entry const *a) | 123 Real ape_priority (Accidental_placement_entry const *a) |
126 { | 124 { |
127 return a->vertical_extent_[UP]; | 125 // right is up because we're horizontal |
| 126 return a->horizontal_skylines_.right (); |
128 } | 127 } |
129 | 128 |
130 bool ape_less (Accidental_placement_entry *const &a, | 129 bool ape_less (Accidental_placement_entry *const &a, |
131 Accidental_placement_entry *const &b) | 130 Accidental_placement_entry *const &b) |
132 { | 131 { |
133 return ape_priority (a) < ape_priority (b); | 132 return ape_priority (a) < ape_priority (b); |
134 } | 133 } |
135 | 134 |
136 /* | 135 /* |
137 This function provides a method for sorting accidentals that belong to the | 136 This function provides a method for sorting accidentals that belong to the |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 a->translate_axis (last_offset, X_AXIS); | 253 a->translate_axis (last_offset, X_AXIS); |
255 else /* Our alteration is different from the last one */ | 254 else /* Our alteration is different from the last one */ |
256 { | 255 { |
257 Real this_offset = offset - a->extent (a, X_AXIS)[RIGHT]; | 256 Real this_offset = offset - a->extent (a, X_AXIS)[RIGHT]; |
258 a->translate_axis (this_offset, X_AXIS); | 257 a->translate_axis (this_offset, X_AXIS); |
259 | 258 |
260 last_offset = this_offset; | 259 last_offset = this_offset; |
261 offset -= a->extent (a, X_AXIS).length () + padding; | 260 offset -= a->extent (a, X_AXIS).length () + padding; |
262 } | 261 } |
263 | 262 |
264 vector<Box> boxes = Accidental_interface::accurate_boxes (a, common); | 263 if (Skyline_pair *sky = Skyline_pair::unsmob (a->get_property ("horizontal
-skylines"))) |
265 ape->extents_.insert (ape->extents_.end (), boxes.begin (), boxes.end ()); | 264 { |
266 | 265 Skyline_pair copy (*sky); |
267 for (vsize j = boxes.size (); j--;) | 266 copy.raise (a->relative_coordinate (common[X_AXIS], X_AXIS)); |
268 ape->vertical_extent_.unite (boxes[j][Y_AXIS]); | 267 copy.shift (a->relative_coordinate (common[Y_AXIS], Y_AXIS)); |
| 268 ape->horizontal_skylines_.merge (copy); |
| 269 } |
269 | 270 |
270 last_octave = p->get_octave (); | 271 last_octave = p->get_octave (); |
271 last_alteration = p->get_alteration (); | 272 last_alteration = p->get_alteration (); |
272 } | 273 } |
273 ape->left_skyline_ = Skyline (ape->extents_, Y_AXIS, LEFT); | |
274 ape->right_skyline_ = Skyline (ape->extents_, Y_AXIS, RIGHT); | |
275 } | 274 } |
276 | 275 |
277 static vector<Grob *> | 276 static vector<Grob *> |
278 extract_heads_and_stems (vector<Accidental_placement_entry *> const &apes) | 277 extract_heads_and_stems (vector<Accidental_placement_entry *> const &apes) |
279 { | 278 { |
280 vector<Grob *> note_cols; | 279 vector<Grob *> note_cols; |
281 vector<Grob *> ret; | 280 vector<Grob *> ret; |
282 | 281 |
283 for (vsize i = apes.size (); i--;) | 282 for (vsize i = apes.size (); i--;) |
284 { | 283 { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 | 367 |
369 /* | 368 /* |
370 Add accs entries right-to-left. | 369 Add accs entries right-to-left. |
371 */ | 370 */ |
372 Interval width; | 371 Interval width; |
373 Real last_offset = 0.0; | 372 Real last_offset = 0.0; |
374 for (vsize i = apes.size (); i-- > 0;) | 373 for (vsize i = apes.size (); i-- > 0;) |
375 { | 374 { |
376 Accidental_placement_entry *ape = apes[i]; | 375 Accidental_placement_entry *ape = apes[i]; |
377 | 376 |
378 Real offset = -ape->right_skyline_.distance (left_skyline); | 377 Real offset = -ape->horizontal_skylines_[RIGHT].distance (left_skyline); |
379 if (isinf (offset)) | 378 if (isinf (offset)) |
380 offset = last_offset; | 379 offset = last_offset; |
381 else | 380 else |
382 offset -= padding; | 381 offset -= padding; |
383 | 382 |
384 Skyline new_left_skyline = ape->left_skyline_; | 383 Skyline new_left_skyline = ape->horizontal_skylines_[LEFT]; |
385 new_left_skyline.raise (offset); | 384 new_left_skyline.raise (offset); |
386 new_left_skyline.merge (left_skyline); | 385 new_left_skyline.merge (left_skyline); |
387 left_skyline = new_left_skyline; | 386 left_skyline = new_left_skyline; |
388 | 387 |
389 /* Shift all of the accidentals in this ape */ | 388 /* Shift all of the accidentals in this ape */ |
390 for (vsize j = ape->grobs_.size (); j--;) | 389 for (vsize j = ape->grobs_.size (); j--;) |
391 ape->grobs_[j]->translate_axis (offset, X_AXIS); | 390 ape->grobs_[j]->translate_axis (offset, X_AXIS); |
392 | 391 |
393 for (vsize j = ape->extents_.size (); j--;) | 392 for (LEFT_and_RIGHT (d)) |
394 width.unite (offset + ape->extents_[j][X_AXIS]); | 393 { |
| 394 Real mh = ape->horizontal_skylines_[d].max_height (); |
| 395 if (!isinf (mh)) |
| 396 width.add_point (mh); |
| 397 } |
395 | 398 |
396 last_offset = offset; | 399 last_offset = offset; |
397 } | 400 } |
398 | 401 |
399 return width; | 402 return width; |
400 } | 403 } |
401 | 404 |
402 /* | 405 /* |
403 This routine computes placements of accidentals. During | 406 This routine computes placements of accidentals. During |
404 add_accidental (), accidentals are already grouped by note, so that | 407 add_accidental (), accidentals are already grouped by note, so that |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 "Resolve accidental collisions.", | 485 "Resolve accidental collisions.", |
483 | 486 |
484 /* properties */ | 487 /* properties */ |
485 "accidental-grobs " | 488 "accidental-grobs " |
486 "direction " | 489 "direction " |
487 "padding " | 490 "padding " |
488 "positioning-done " | 491 "positioning-done " |
489 "right-padding " | 492 "right-padding " |
490 "script-priority " | 493 "script-priority " |
491 ); | 494 ); |
OLD | NEW |