LEFT | RIGHT |
(no file at all) | |
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--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 Jan Nieuwenhuizen <janneke@gnu.org> | 5 Jan Nieuwenhuizen <janneke@gnu.org> |
6 | 6 |
7 LilyPond is free software: you can redistribute it and/or modify | 7 LilyPond is free software: you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation, either version 3 of the License, or | 9 the Free Software Foundation, either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 void | 110 void |
111 Beam::add_stem (Grob *me, Grob *s) | 111 Beam::add_stem (Grob *me, Grob *s) |
112 { | 112 { |
113 if (Stem::get_beam (s)) | 113 if (Stem::get_beam (s)) |
114 { | 114 { |
115 programming_error ("Stem already has beam"); | 115 programming_error ("Stem already has beam"); |
116 return; | 116 return; |
117 } | 117 } |
118 | 118 |
119 Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), s); | 119 Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), s); |
120 s->set_object ("beam", me->self_scm ()); | 120 set_object (s, "beam", me->self_scm ()); |
121 add_bound_item (dynamic_cast<Spanner *> (me), dynamic_cast<Item *> (s)); | 121 add_bound_item (dynamic_cast<Spanner *> (me), dynamic_cast<Item *> (s)); |
122 } | 122 } |
123 | 123 |
124 Real | 124 Real |
125 Beam::get_beam_thickness (Grob *me) | 125 Beam::get_beam_thickness (Grob *me) |
126 { | 126 { |
127 return robust_scm2double (me->get_property ("beam-thickness"), 0) | 127 return robust_scm2double (get_property (me, "beam-thickness"), 0) |
128 * Staff_symbol_referencer::staff_space (me); | 128 * Staff_symbol_referencer::staff_space (me); |
129 } | 129 } |
130 | 130 |
131 /* Return the translation between 2 adjoining beams. */ | 131 /* Return the translation between 2 adjoining beams. */ |
132 Real | 132 Real |
133 Beam::get_beam_translation (Grob *me) | 133 Beam::get_beam_translation (Grob *me) |
134 { | 134 { |
135 int beam_count = get_beam_count (me); | 135 int beam_count = get_beam_count (me); |
136 Real staff_space = Staff_symbol_referencer::staff_space (me); | 136 Real staff_space = Staff_symbol_referencer::staff_space (me); |
137 Real line = Staff_symbol_referencer::line_thickness (me); | 137 Real line = Staff_symbol_referencer::line_thickness (me); |
138 Real beam_thickness = get_beam_thickness (me); | 138 Real beam_thickness = get_beam_thickness (me); |
139 Real fract = robust_scm2double (me->get_property ("length-fraction"), 1.0); | 139 Real fract = robust_scm2double (get_property (me, "length-fraction"), 1.0); |
140 | 140 |
141 /* | 141 /* |
142 if fract != 1.0, as is the case for grace notes, we want the gap | 142 if fract != 1.0, as is the case for grace notes, we want the gap |
143 to decrease too. To achieve this, we divide the thickness by | 143 to decrease too. To achieve this, we divide the thickness by |
144 fract */ | 144 fract */ |
145 return (beam_count < 4 | 145 return (beam_count < 4 |
146 ? (2 * staff_space * fract + line * fract - beam_thickness) / 2.0 | 146 ? (2 * staff_space * fract + line * fract - beam_thickness) / 2.0 |
147 : (3 * staff_space * fract + line * fract - beam_thickness) / 3.0); | 147 : (3 * staff_space * fract + line * fract - beam_thickness) / 3.0); |
148 } | 148 } |
149 | 149 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 else | 207 else |
208 { | 208 { |
209 Grob *stem = first_normal_stem (me); | 209 Grob *stem = first_normal_stem (me); |
210 | 210 |
211 /* | 211 /* |
212 This happens for chord tremolos. | 212 This happens for chord tremolos. |
213 */ | 213 */ |
214 if (!stem) | 214 if (!stem) |
215 stem = stems[0]; | 215 stem = stems[0]; |
216 | 216 |
217 if (is_direction (stem->get_property_data ("direction"))) | 217 if (is_direction (get_property_data (stem, "direction"))) |
218 dir = to_dir (stem->get_property_data ("direction")); | 218 dir = to_dir (get_property_data (stem, "direction")); |
219 else | 219 else |
220 dir = to_dir (stem->get_property ("default-direction")); | 220 dir = to_dir (get_property (stem, "default-direction")); |
221 | 221 |
222 extract_grob_set (stem, "note-heads", heads); | 222 extract_grob_set (stem, "note-heads", heads); |
223 /* default position of Kievan heads with beams is down | 223 /* default position of Kievan heads with beams is down |
224 placing this here avoids warnings downstream */ | 224 placing this here avoids warnings downstream */ |
225 if (heads.size ()) | 225 if (heads.size ()) |
226 { | 226 { |
227 if (scm_is_eq (heads[0]->get_property ("style"), | 227 if (scm_is_eq (get_property (heads[0], "style"), |
228 ly_symbol2scm ("kievan"))) | 228 ly_symbol2scm ("kievan"))) |
229 { | 229 { |
230 if (dir == CENTER) | 230 if (dir == CENTER) |
231 dir = DOWN; | 231 dir = DOWN; |
232 } | 232 } |
233 } | 233 } |
234 } | 234 } |
235 } | 235 } |
236 | 236 |
237 if (count >= 1) | 237 if (count >= 1) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 extract_grob_set (me, "stems", stems); | 301 extract_grob_set (me, "stems", stems); |
302 | 302 |
303 Slice last_int; | 303 Slice last_int; |
304 last_int.set_empty (); | 304 last_int.set_empty (); |
305 | 305 |
306 SCM last_beaming = scm_cons (SCM_EOL, scm_list_1 (scm_from_int (0))); | 306 SCM last_beaming = scm_cons (SCM_EOL, scm_list_1 (scm_from_int (0))); |
307 Direction last_dir = CENTER; | 307 Direction last_dir = CENTER; |
308 for (vsize i = 0; i < stems.size (); i++) | 308 for (vsize i = 0; i < stems.size (); i++) |
309 { | 309 { |
310 Grob *this_stem = stems[i]; | 310 Grob *this_stem = stems[i]; |
311 SCM this_beaming = this_stem->get_property ("beaming"); | 311 SCM this_beaming = get_property (this_stem, "beaming"); |
312 | 312 |
313 Direction this_dir = get_grob_direction (this_stem); | 313 Direction this_dir = get_grob_direction (this_stem); |
314 if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming)) | 314 if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming)) |
315 { | 315 { |
316 int start_point = position_with_maximal_common_beams | 316 int start_point = position_with_maximal_common_beams |
317 (last_beaming, this_beaming, | 317 (last_beaming, this_beaming, |
318 last_dir ? last_dir : this_dir, | 318 last_dir ? last_dir : this_dir, |
319 this_dir); | 319 this_dir); |
320 | 320 |
321 Slice new_slice; | 321 Slice new_slice; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 369 |
370 typedef map<int, vector<Beam_stem_segment> > Position_stem_segments_map; | 370 typedef map<int, vector<Beam_stem_segment> > Position_stem_segments_map; |
371 | 371 |
372 MAKE_SCHEME_CALLBACK (Beam, calc_beam_segments, 1); | 372 MAKE_SCHEME_CALLBACK (Beam, calc_beam_segments, 1); |
373 SCM | 373 SCM |
374 Beam::calc_beam_segments (SCM smob) | 374 Beam::calc_beam_segments (SCM smob) |
375 { | 375 { |
376 /* ugh, this has a side-effect that we need to ensure that | 376 /* ugh, this has a side-effect that we need to ensure that |
377 Stem.beaming is correct */ | 377 Stem.beaming is correct */ |
378 Grob *me_grob = unsmob<Grob> (smob); | 378 Grob *me_grob = unsmob<Grob> (smob); |
379 (void) me_grob->get_property ("beaming"); | 379 (void) get_property (me_grob, "beaming"); |
380 | 380 |
381 Spanner *me = dynamic_cast<Spanner *> (me_grob); | 381 Spanner *me = dynamic_cast<Spanner *> (me_grob); |
382 | 382 |
383 extract_grob_set (me, "stems", stems); | 383 extract_grob_set (me, "stems", stems); |
384 | 384 |
385 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); | 385 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); |
386 for (LEFT_and_RIGHT (d)) | 386 for (LEFT_and_RIGHT (d)) |
387 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); | 387 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); |
388 | 388 |
389 int gap_count = robust_scm2int (me->get_property ("gap-count"), 0); | 389 int gap_count = robust_scm2int (get_property (me, "gap-count"), 0); |
390 Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0); | 390 Real gap_length = robust_scm2double (get_property (me, "gap"), 0.0); |
391 | 391 |
392 Position_stem_segments_map stem_segments; | 392 Position_stem_segments_map stem_segments; |
393 Real lt = Staff_symbol_referencer::line_thickness (me); | 393 Real lt = Staff_symbol_referencer::line_thickness (me); |
394 | 394 |
395 /* There are two concepts of "rank" that are used in the following code. | 395 /* There are two concepts of "rank" that are used in the following code. |
396 The beam_rank is the vertical position of the beam (larger numbers are | 396 The beam_rank is the vertical position of the beam (larger numbers are |
397 closer to the noteheads). Beam_stem_segment.rank_, on the other hand, | 397 closer to the noteheads). Beam_stem_segment.rank_, on the other hand, |
398 is the horizontal position of the segment (this is incremented by two | 398 is the horizontal position of the segment (this is incremented by two |
399 for each stem; the beam segment on the right side of the stem has | 399 for each stem; the beam segment on the right side of the stem has |
400 a higher rank (by one) than its neighbour to the left). */ | 400 a higher rank (by one) than its neighbour to the left). */ |
401 Slice ranks; | 401 Slice ranks; |
402 for (vsize i = 0; i < stems.size (); i++) | 402 for (vsize i = 0; i < stems.size (); i++) |
403 { | 403 { |
404 Grob *stem = stems[i]; | 404 Grob *stem = stems[i]; |
405 Real stem_width = robust_scm2double (stem->get_property ("thickness"), 1.0
) * lt; | 405 Real stem_width = robust_scm2double (get_property (stem, "thickness"), 1.0
) * lt; |
406 Real stem_x = stem->relative_coordinate (commonx, X_AXIS); | 406 Real stem_x = stem->relative_coordinate (commonx, X_AXIS); |
407 SCM beaming = stem->get_property ("beaming"); | 407 SCM beaming = get_property (stem, "beaming"); |
408 | 408 |
409 for (LEFT_and_RIGHT (d)) | 409 for (LEFT_and_RIGHT (d)) |
410 { | 410 { |
411 // Find the maximum and minimum beam ranks. | 411 // Find the maximum and minimum beam ranks. |
412 // Given that RANKS is never reset to empty, the interval will always
be | 412 // Given that RANKS is never reset to empty, the interval will always
be |
413 // smallest for the left beamlet of the first stem, and then it might
grow. | 413 // smallest for the left beamlet of the first stem, and then it might
grow. |
414 // Do we really want this? (It only affects the tremolo gaps) --jneem | 414 // Do we really want this? (It only affects the tremolo gaps) --jneem |
415 for (SCM s = index_get_cell (beaming, d); | 415 for (SCM s = index_get_cell (beaming, d); |
416 scm_is_pair (s); s = scm_cdr (s)) | 416 scm_is_pair (s); s = scm_cdr (s)) |
417 { | 417 { |
(...skipping 11 matching lines...) Expand all Loading... |
429 continue; | 429 continue; |
430 | 430 |
431 int beam_rank = scm_to_int (scm_car (s)); | 431 int beam_rank = scm_to_int (scm_car (s)); |
432 Beam_stem_segment seg; | 432 Beam_stem_segment seg; |
433 seg.stem_ = stem; | 433 seg.stem_ = stem; |
434 seg.stem_x_ = stem_x; | 434 seg.stem_x_ = stem_x; |
435 seg.rank_ = 2 * i + (d + 1) / 2; | 435 seg.rank_ = 2 * i + (d + 1) / 2; |
436 seg.width_ = stem_width; | 436 seg.width_ = stem_width; |
437 seg.stem_index_ = i; | 437 seg.stem_index_ = i; |
438 seg.dir_ = d; | 438 seg.dir_ = d; |
439 seg.max_connect_ = robust_scm2int (stem->get_property ("max-beam-c
onnect"), 1000); | 439 seg.max_connect_ = robust_scm2int (get_property (stem, "max-beam-c
onnect"), 1000); |
440 | 440 |
441 Direction stem_dir = get_grob_direction (stem); | 441 Direction stem_dir = get_grob_direction (stem); |
442 | 442 |
443 seg.gapped_ | 443 seg.gapped_ |
444 = (stem_dir * beam_rank < (stem_dir * ranks[-stem_dir] + gap_cou
nt)); | 444 = (stem_dir * beam_rank < (stem_dir * ranks[-stem_dir] + gap_cou
nt)); |
445 stem_segments[beam_rank].push_back (seg); | 445 stem_segments[beam_rank].push_back (seg); |
446 } | 446 } |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 Drul_array<Real> break_overshoot | 450 Drul_array<Real> break_overshoot |
451 = robust_scm2drul (me->get_property ("break-overshoot"), | 451 = robust_scm2drul (get_property (me, "break-overshoot"), |
452 Drul_array<Real> (-0.5, 0.0)); | 452 Drul_array<Real> (-0.5, 0.0)); |
453 | 453 |
454 vector<Beam_segment> segments; | 454 vector<Beam_segment> segments; |
455 for (Position_stem_segments_map::const_iterator i (stem_segments.begin ()); | 455 for (Position_stem_segments_map::const_iterator i (stem_segments.begin ()); |
456 i != stem_segments.end (); i++) | 456 i != stem_segments.end (); i++) |
457 { | 457 { |
458 vector<Beam_stem_segment> segs = (*i).second; | 458 vector<Beam_stem_segment> segs = (*i).second; |
459 vector_sort (segs, std::less<Beam_stem_segment> ()); | 459 vector_sort (segs, std::less<Beam_stem_segment> ()); |
460 | 460 |
461 Beam_segment current; | 461 Beam_segment current; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 { | 513 { |
514 current.horizontal_[event_dir] | 514 current.horizontal_[event_dir] |
515 = (Axis_group_interface::generic_bound_extent (me->get_b
ound (event_dir), | 515 = (Axis_group_interface::generic_bound_extent (me->get_b
ound (event_dir), |
516 commonx,
X_AXIS)[RIGHT] | 516 commonx,
X_AXIS)[RIGHT] |
517 + event_dir * break_overshoot[event_dir]); | 517 + event_dir * break_overshoot[event_dir]); |
518 } | 518 } |
519 else | 519 else |
520 { | 520 { |
521 Grob *stem = stems[seg.stem_index_]; | 521 Grob *stem = stems[seg.stem_index_]; |
522 Drul_array<Real> beamlet_length | 522 Drul_array<Real> beamlet_length |
523 = robust_scm2interval (stem->get_property ("beamlet-defa
ult-length"), Interval (1.1, 1.1)); | 523 = robust_scm2interval (get_property (stem, "beamlet-defa
ult-length"), Interval (1.1, 1.1)); |
524 Drul_array<Real> max_proportion | 524 Drul_array<Real> max_proportion |
525 = robust_scm2interval (stem->get_property ("beamlet-max-
length-proportion"), Interval (0.75, 0.75)); | 525 = robust_scm2interval (get_property (stem, "beamlet-max-
length-proportion"), Interval (0.75, 0.75)); |
526 Real length = beamlet_length[seg.dir_]; | 526 Real length = beamlet_length[seg.dir_]; |
527 | 527 |
528 if (inside_stem) | 528 if (inside_stem) |
529 { | 529 { |
530 Grob *neighbor_stem = stems[seg.stem_index_ + event_di
r]; | 530 Grob *neighbor_stem = stems[seg.stem_index_ + event_di
r]; |
531 Real neighbor_stem_x = neighbor_stem->relative_coordin
ate (commonx, X_AXIS); | 531 Real neighbor_stem_x = neighbor_stem->relative_coordin
ate (commonx, X_AXIS); |
532 | 532 |
533 length = std::min (length, | 533 length = std::min (length, |
534 fabs (neighbor_stem_x - seg.stem_x_
) * max_proportion[seg.dir_]); | 534 fabs (neighbor_stem_x - seg.stem_x_
) * max_proportion[seg.dir_]); |
535 } | 535 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 } | 586 } |
587 | 587 |
588 return segments_scm; | 588 return segments_scm; |
589 } | 589 } |
590 | 590 |
591 MAKE_SCHEME_CALLBACK (Beam, calc_x_positions, 1); | 591 MAKE_SCHEME_CALLBACK (Beam, calc_x_positions, 1); |
592 SCM | 592 SCM |
593 Beam::calc_x_positions (SCM smob) | 593 Beam::calc_x_positions (SCM smob) |
594 { | 594 { |
595 Spanner *me = unsmob<Spanner> (smob); | 595 Spanner *me = unsmob<Spanner> (smob); |
596 SCM segments = me->get_property ("beam-segments"); | 596 SCM segments = get_property (me, "beam-segments"); |
597 Interval x_positions; | 597 Interval x_positions; |
598 x_positions.set_empty (); | 598 x_positions.set_empty (); |
599 for (SCM s = segments; scm_is_pair (s); s = scm_cdr (s)) | 599 for (SCM s = segments; scm_is_pair (s); s = scm_cdr (s)) |
600 x_positions.unite (robust_scm2interval (ly_assoc_get (ly_symbol2scm ("horizo
ntal"), | 600 x_positions.unite (robust_scm2interval (ly_assoc_get (ly_symbol2scm ("horizo
ntal"), |
601 scm_car (s), | 601 scm_car (s), |
602 SCM_EOL), | 602 SCM_EOL), |
603 Interval (0.0, 0.0))); | 603 Interval (0.0, 0.0))); |
604 | 604 |
605 // Case for beams without segments (i.e. uniting two skips with a beam) | 605 // Case for beams without segments (i.e. uniting two skips with a beam) |
606 // TODO: should issue a warning? warning likely issued downstream, but couldn
't hurt... | 606 // TODO: should issue a warning? warning likely issued downstream, but couldn
't hurt... |
607 if (x_positions.is_empty ()) | 607 if (x_positions.is_empty ()) |
608 { | 608 { |
609 extract_grob_set (me, "stems", stems); | 609 extract_grob_set (me, "stems", stems); |
610 Grob *common_x = common_refpoint_of_array (stems, me, X_AXIS); | 610 Grob *common_x = common_refpoint_of_array (stems, me, X_AXIS); |
611 for (LEFT_and_RIGHT (d)) | 611 for (LEFT_and_RIGHT (d)) |
612 x_positions[d] = me->relative_coordinate (common_x, X_AXIS); | 612 x_positions[d] = me->relative_coordinate (common_x, X_AXIS); |
613 } | 613 } |
614 return ly_interval2scm (x_positions); | 614 return ly_interval2scm (x_positions); |
615 } | 615 } |
616 | 616 |
617 vector<Beam_segment> | 617 vector<Beam_segment> |
618 Beam::get_beam_segments (Grob *me) | 618 Beam::get_beam_segments (Grob *me) |
619 { | 619 { |
620 SCM segments_scm = me->get_property ("beam-segments"); | 620 SCM segments_scm = get_property (me, "beam-segments"); |
621 vector<Beam_segment> segments; | 621 vector<Beam_segment> segments; |
622 for (SCM s = segments_scm; scm_is_pair (s); s = scm_cdr (s)) | 622 for (SCM s = segments_scm; scm_is_pair (s); s = scm_cdr (s)) |
623 { | 623 { |
624 segments.push_back (Beam_segment ()); | 624 segments.push_back (Beam_segment ()); |
625 segments.back ().vertical_count_ = robust_scm2int (ly_assoc_get (ly_symbol
2scm ("vertical-count"), scm_car (s), SCM_EOL), 0); | 625 segments.back ().vertical_count_ = robust_scm2int (ly_assoc_get (ly_symbol
2scm ("vertical-count"), scm_car (s), SCM_EOL), 0); |
626 segments.back ().horizontal_ = robust_scm2interval (ly_assoc_get (ly_symbo
l2scm ("horizontal"), scm_car (s), SCM_EOL), Interval (0.0, 0.0)); | 626 segments.back ().horizontal_ = robust_scm2interval (ly_assoc_get (ly_symbo
l2scm ("horizontal"), scm_car (s), SCM_EOL), Interval (0.0, 0.0)); |
627 } | 627 } |
628 | 628 |
629 return segments; | 629 return segments; |
630 } | 630 } |
(...skipping 16 matching lines...) Expand all Loading... |
647 for (LEFT_and_RIGHT (d)) | 647 for (LEFT_and_RIGHT (d)) |
648 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); | 648 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); |
649 | 649 |
650 vector<Beam_segment> segments = get_beam_segments (me); | 650 vector<Beam_segment> segments = get_beam_segments (me); |
651 | 651 |
652 if (!segments.size ()) | 652 if (!segments.size ()) |
653 return SCM_EOL; | 653 return SCM_EOL; |
654 | 654 |
655 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); | 655 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); |
656 | 656 |
657 SCM posns = me->get_property ("quantized-positions"); | 657 SCM posns = get_property (me, "quantized-positions"); |
658 Interval span = robust_scm2interval (me->get_property ("X-positions"), Interva
l (0, 0)); | 658 Interval span = robust_scm2interval (get_property (me, "X-positions"), Interva
l (0, 0)); |
659 Interval pos; | 659 Interval pos; |
660 if (!is_number_pair (posns)) | 660 if (!is_number_pair (posns)) |
661 { | 661 { |
662 programming_error ("no beam positions?"); | 662 programming_error ("no beam positions?"); |
663 pos = Interval (0, 0); | 663 pos = Interval (0, 0); |
664 } | 664 } |
665 else | 665 else |
666 pos = ly_scm2realdrul (posns); | 666 pos = ly_scm2realdrul (posns); |
667 | 667 |
668 scale_drul (&pos, Staff_symbol_referencer::staff_space (me)); | 668 scale_drul (&pos, Staff_symbol_referencer::staff_space (me)); |
669 | 669 |
670 Real dy = pos[RIGHT] - pos[LEFT]; | 670 Real dy = pos[RIGHT] - pos[LEFT]; |
671 Real slope = (dy && span.length ()) ? dy / span.length () : 0; | 671 Real slope = (dy && span.length ()) ? dy / span.length () : 0; |
672 | 672 |
673 Real beam_thickness = get_beam_thickness (me); | 673 Real beam_thickness = get_beam_thickness (me); |
674 Real beam_dy = get_beam_translation (me); | 674 Real beam_dy = get_beam_translation (me); |
675 | 675 |
676 Direction feather_dir = to_dir (me->get_property ("grow-direction")); | 676 Direction feather_dir = to_dir (get_property (me, "grow-direction")); |
677 | 677 |
678 Interval placements = robust_scm2interval (me->get_property ("normalized-endpo
ints"), Interval (0.0, 0.0)); | 678 Interval placements = robust_scm2interval (get_property (me, "normalized-endpo
ints"), Interval (0.0, 0.0)); |
679 | 679 |
680 Stencil the_beam; | 680 Stencil the_beam; |
681 vsize extreme = (segments[0].vertical_count_ == 0 | 681 vsize extreme = (segments[0].vertical_count_ == 0 |
682 ? segments[0].vertical_count_ | 682 ? segments[0].vertical_count_ |
683 : segments.back ().vertical_count_); | 683 : segments.back ().vertical_count_); |
684 | 684 |
685 for (vsize i = 0; i < segments.size (); i++) | 685 for (vsize i = 0; i < segments.size (); i++) |
686 { | 686 { |
687 Real local_slope = slope; | 687 Real local_slope = slope; |
688 /* | 688 /* |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 weighted_average += beam_dy * n * factor; | 739 weighted_average += beam_dy * n * factor; |
740 } | 740 } |
741 | 741 |
742 b.translate_axis (weighted_average, Y_AXIS); | 742 b.translate_axis (weighted_average, Y_AXIS); |
743 | 743 |
744 the_beam.add_stencil (b); | 744 the_beam.add_stencil (b); |
745 | 745 |
746 } | 746 } |
747 | 747 |
748 #if (DEBUG_BEAM_SCORING) | 748 #if (DEBUG_BEAM_SCORING) |
749 SCM annotation = me->get_property ("annotation"); | 749 SCM annotation = get_property (me, "annotation"); |
750 if (scm_is_string (annotation)) | 750 if (scm_is_string (annotation)) |
751 { | 751 { |
752 extract_grob_set (me, "stems", stems); | 752 extract_grob_set (me, "stems", stems); |
753 | 753 |
754 /* | 754 /* |
755 This code prints the demerits for each beam. Perhaps this | 755 This code prints the demerits for each beam. Perhaps this |
756 should be switchable for those who want to twiddle with the | 756 should be switchable for those who want to twiddle with the |
757 parameters. | 757 parameters. |
758 */ | 758 */ |
759 string str; | 759 string str; |
760 SCM properties = Font_interface::text_font_alist_chain (me); | 760 SCM properties = Font_interface::text_font_alist_chain (me); |
761 | 761 |
762 properties = scm_cons (scm_acons (ly_symbol2scm ("font-size"), scm_from_in
t (-5), SCM_EOL), | 762 properties = scm_cons (scm_acons (ly_symbol2scm ("font-size"), scm_from_in
t (-5), SCM_EOL), |
763 properties); | 763 properties); |
764 | 764 |
765 Direction stem_dir = stems.size () ? to_dir (stems[0]->get_property ("dire
ction")) : UP; | 765 Direction stem_dir = stems.size () ? to_dir (get_property (stems[0], "dire
ction")) : UP; |
766 | 766 |
767 Stencil score = *unsmob<Stencil> (Text_interface::interpret_markup | 767 Stencil score = *unsmob<Stencil> (Text_interface::interpret_markup |
768 (me->layout ()->self_scm (), properties,
annotation)); | 768 (me->layout ()->self_scm (), properties,
annotation)); |
769 | 769 |
770 if (!score.is_empty ()) | 770 if (!score.is_empty ()) |
771 { | 771 { |
772 score.translate_axis (me->relative_coordinate (commonx, X_AXIS), X_AXI
S); | 772 score.translate_axis (me->relative_coordinate (commonx, X_AXIS), X_AXI
S); |
773 the_beam.add_at_edge (Y_AXIS, stem_dir, score, 1.0); | 773 the_beam.add_at_edge (Y_AXIS, stem_dir, score, 1.0); |
774 } | 774 } |
775 } | 775 } |
(...skipping 20 matching lines...) Expand all Loading... |
796 } | 796 } |
797 | 797 |
798 Drul_array<int> total (0, 0); | 798 Drul_array<int> total (0, 0); |
799 Drul_array<int> count (0, 0); | 799 Drul_array<int> count (0, 0); |
800 | 800 |
801 bool force_dir = false; | 801 bool force_dir = false; |
802 for (vsize i = 0; i < stems.size (); i++) | 802 for (vsize i = 0; i < stems.size (); i++) |
803 { | 803 { |
804 Grob *s = stems[i]; | 804 Grob *s = stems[i]; |
805 Direction stem_dir = CENTER; | 805 Direction stem_dir = CENTER; |
806 SCM stem_dir_scm = s->get_property_data ("direction"); | 806 SCM stem_dir_scm = get_property_data (s, "direction"); |
807 if (is_direction (stem_dir_scm)) | 807 if (is_direction (stem_dir_scm)) |
808 { | 808 { |
809 stem_dir = to_dir (stem_dir_scm); | 809 stem_dir = to_dir (stem_dir_scm); |
810 force_dir = true; | 810 force_dir = true; |
811 } | 811 } |
812 else | 812 else |
813 stem_dir = to_dir (s->get_property ("default-direction")); | 813 stem_dir = to_dir (get_property (s, "default-direction")); |
814 | 814 |
815 if (!stem_dir) | 815 if (!stem_dir) |
816 stem_dir = to_dir (s->get_property ("neutral-direction")); | 816 stem_dir = to_dir (get_property (s, "neutral-direction")); |
817 | 817 |
818 if (stem_dir) | 818 if (stem_dir) |
819 { | 819 { |
820 count[stem_dir]++; | 820 count[stem_dir]++; |
821 total[stem_dir] += std::max (int (- stem_dir * Stem::head_positions (s
) [-stem_dir]), 0); | 821 total[stem_dir] += std::max (int (- stem_dir * Stem::head_positions (s
) [-stem_dir]), 0); |
822 } | 822 } |
823 } | 823 } |
824 | 824 |
825 if (!force_dir) | 825 if (!force_dir) |
826 { | 826 { |
827 if (abs (extremes[UP]) > -extremes[DOWN]) | 827 if (abs (extremes[UP]) > -extremes[DOWN]) |
828 return DOWN; | 828 return DOWN; |
829 else if (extremes[UP] < -extremes[DOWN]) | 829 else if (extremes[UP] < -extremes[DOWN]) |
830 return UP; | 830 return UP; |
831 } | 831 } |
832 | 832 |
833 Direction dir = CENTER; | 833 Direction dir = CENTER; |
834 Direction d = CENTER; | 834 Direction d = CENTER; |
835 if ((d = (Direction) sign (count[UP] - count[DOWN]))) | 835 if ((d = (Direction) sign (count[UP] - count[DOWN]))) |
836 dir = d; | 836 dir = d; |
837 else if (count[UP] | 837 else if (count[UP] |
838 && count[DOWN] | 838 && count[DOWN] |
839 && (d = (Direction) sign (total[UP] / count[UP] - total[DOWN] / count
[DOWN]))) | 839 && (d = (Direction) sign (total[UP] / count[UP] - total[DOWN] / count
[DOWN]))) |
840 dir = d; | 840 dir = d; |
841 else if ((d = (Direction) sign (total[UP] - total[DOWN]))) | 841 else if ((d = (Direction) sign (total[UP] - total[DOWN]))) |
842 dir = d; | 842 dir = d; |
843 else | 843 else |
844 dir = to_dir (me->get_property ("neutral-direction")); | 844 dir = to_dir (get_property (me, "neutral-direction")); |
845 | 845 |
846 return dir; | 846 return dir; |
847 } | 847 } |
848 | 848 |
849 /* Set all stems with non-forced direction to beam direction. | 849 /* Set all stems with non-forced direction to beam direction. |
850 Urg: non-forced should become `without/with unforced' direction, | 850 Urg: non-forced should become `without/with unforced' direction, |
851 once stem gets cleaned-up. */ | 851 once stem gets cleaned-up. */ |
852 void | 852 void |
853 Beam::set_stem_directions (Grob *me, Direction d) | 853 Beam::set_stem_directions (Grob *me, Direction d) |
854 { | 854 { |
855 extract_grob_set (me, "stems", stems); | 855 extract_grob_set (me, "stems", stems); |
856 | 856 |
857 for (vsize i = 0; i < stems.size (); i++) | 857 for (vsize i = 0; i < stems.size (); i++) |
858 { | 858 { |
859 Grob *s = stems[i]; | 859 Grob *s = stems[i]; |
860 | 860 |
861 SCM forcedir = s->get_property_data ("direction"); | 861 SCM forcedir = get_property_data (s, "direction"); |
862 if (!to_dir (forcedir)) | 862 if (!to_dir (forcedir)) |
863 set_grob_direction (s, d); | 863 set_grob_direction (s, d); |
864 } | 864 } |
865 } | 865 } |
866 | 866 |
867 /* | 867 /* |
868 Only try horizontal beams for knees. No reliable detection of | 868 Only try horizontal beams for knees. No reliable detection of |
869 anything else is possible here, since we don't know funky-beaming | 869 anything else is possible here, since we don't know funky-beaming |
870 settings, or X-distances (slopes!) People that want sloped | 870 settings, or X-distances (slopes!) People that want sloped |
871 knee-beams, should set the directions manually. | 871 knee-beams, should set the directions manually. |
872 | 872 |
873 | 873 |
874 TODO: | 874 TODO: |
875 | 875 |
876 this routine should take into account the stemlength scoring | 876 this routine should take into account the stemlength scoring |
877 of a possible knee/nonknee beam. | 877 of a possible knee/nonknee beam. |
878 */ | 878 */ |
879 void | 879 void |
880 Beam::consider_auto_knees (Grob *me) | 880 Beam::consider_auto_knees (Grob *me) |
881 { | 881 { |
882 SCM scm = me->get_property ("auto-knee-gap"); | 882 SCM scm = get_property (me, "auto-knee-gap"); |
883 if (!scm_is_number (scm)) | 883 if (!scm_is_number (scm)) |
884 return; | 884 return; |
885 | 885 |
886 vector<Interval> forbidden_intervals; | 886 vector<Interval> forbidden_intervals; |
887 | 887 |
888 extract_grob_set (me, "normal-stems", stems); | 888 extract_grob_set (me, "normal-stems", stems); |
889 | 889 |
890 Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); | 890 Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); |
891 Real staff_space = Staff_symbol_referencer::staff_space (me); | 891 Real staff_space = Staff_symbol_referencer::staff_space (me); |
892 | 892 |
893 vector<Interval> head_extents_array; | 893 vector<Interval> head_extents_array; |
894 for (vsize i = 0; i < stems.size (); i++) | 894 for (vsize i = 0; i < stems.size (); i++) |
895 { | 895 { |
896 Grob *stem = stems[i]; | 896 Grob *stem = stems[i]; |
897 | 897 |
898 Interval head_extents; | 898 Interval head_extents; |
899 if (Stem::head_count (stem)) | 899 if (Stem::head_count (stem)) |
900 { | 900 { |
901 head_extents = Stem::head_positions (stem); | 901 head_extents = Stem::head_positions (stem); |
902 head_extents.widen (1); | 902 head_extents.widen (1); |
903 head_extents *= staff_space * 0.5; | 903 head_extents *= staff_space * 0.5; |
904 | 904 |
905 /* | 905 /* |
906 We could subtract beam Y position, but this routine only | 906 We could subtract beam Y position, but this routine only |
907 sets stem directions, a constant shift does not have an | 907 sets stem directions, a constant shift does not have an |
908 influence. | 908 influence. |
909 */ | 909 */ |
910 head_extents += stem->pure_relative_y_coordinate (common, 0, INT_MAX); | 910 head_extents += stem->pure_relative_y_coordinate (common, 0, INT_MAX); |
911 | 911 |
912 if (to_dir (stem->get_property_data ("direction"))) | 912 if (to_dir (get_property_data (stem, "direction"))) |
913 { | 913 { |
914 Direction stemdir = to_dir (stem->get_property ("direction")); | 914 Direction stemdir = to_dir (get_property (stem, "direction")); |
915 head_extents[-stemdir] = -stemdir * infinity_f; | 915 head_extents[-stemdir] = -stemdir * infinity_f; |
916 } | 916 } |
917 } | 917 } |
918 head_extents_array.push_back (head_extents); | 918 head_extents_array.push_back (head_extents); |
919 | 919 |
920 forbidden_intervals.push_back (head_extents); | 920 forbidden_intervals.push_back (head_extents); |
921 } | 921 } |
922 | 922 |
923 Interval max_gap; | 923 Interval max_gap; |
924 Real max_gap_len = 0.0; | 924 Real max_gap_len = 0.0; |
(...skipping 28 matching lines...) Expand all Loading... |
953 { | 953 { |
954 int j = 0; | 954 int j = 0; |
955 for (vsize i = 0; i < stems.size (); i++) | 955 for (vsize i = 0; i < stems.size (); i++) |
956 { | 956 { |
957 Grob *stem = stems[i]; | 957 Grob *stem = stems[i]; |
958 Interval head_extents = head_extents_array[j++]; | 958 Interval head_extents = head_extents_array[j++]; |
959 | 959 |
960 Direction d = (head_extents.center () < max_gap.center ()) | 960 Direction d = (head_extents.center () < max_gap.center ()) |
961 ? UP : DOWN; | 961 ? UP : DOWN; |
962 | 962 |
963 stem->set_property ("direction", scm_from_int (d)); | 963 set_property (stem, "direction", scm_from_int (d)); |
964 | 964 |
965 head_extents.intersect (max_gap); | 965 head_extents.intersect (max_gap); |
966 assert (head_extents.is_empty () || head_extents.length () < 1e-6); | 966 assert (head_extents.is_empty () || head_extents.length () < 1e-6); |
967 } | 967 } |
968 } | 968 } |
969 } | 969 } |
970 | 970 |
971 MAKE_SCHEME_CALLBACK (Beam, calc_stem_shorten, 1) | 971 MAKE_SCHEME_CALLBACK (Beam, calc_stem_shorten, 1) |
972 SCM | 972 SCM |
973 Beam::calc_stem_shorten (SCM smob) | 973 Beam::calc_stem_shorten (SCM smob) |
974 { | 974 { |
975 Grob *me = unsmob<Grob> (smob); | 975 Grob *me = unsmob<Grob> (smob); |
976 | 976 |
977 /* | 977 /* |
978 shortening looks silly for x staff beams | 978 shortening looks silly for x staff beams |
979 */ | 979 */ |
980 if (is_knee (me)) | 980 if (is_knee (me)) |
981 return scm_from_int (0); | 981 return scm_from_int (0); |
982 | 982 |
983 Real forced_fraction = static_cast<Real> (forced_stem_count (me)) | 983 Real forced_fraction = static_cast<Real> (forced_stem_count (me)) |
984 / static_cast<Real> (normal_stem_count (me)); | 984 / static_cast<Real> (normal_stem_count (me)); |
985 | 985 |
986 int beam_count = get_beam_count (me); | 986 int beam_count = get_beam_count (me); |
987 | 987 |
988 SCM shorten_list = me->get_property ("beamed-stem-shorten"); | 988 SCM shorten_list = get_property (me, "beamed-stem-shorten"); |
989 if (scm_is_null (shorten_list)) | 989 if (scm_is_null (shorten_list)) |
990 return scm_from_int (0); | 990 return scm_from_int (0); |
991 | 991 |
992 Real staff_space = Staff_symbol_referencer::staff_space (me); | 992 Real staff_space = Staff_symbol_referencer::staff_space (me); |
993 | 993 |
994 SCM shorten_elt | 994 SCM shorten_elt |
995 = robust_list_ref (beam_count - 1, shorten_list); | 995 = robust_list_ref (beam_count - 1, shorten_list); |
996 Real shorten = scm_to_double (shorten_elt) * staff_space; | 996 Real shorten = scm_to_double (shorten_elt) * staff_space; |
997 | 997 |
998 shorten *= forced_fraction; | 998 shorten *= forced_fraction; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 Hmm. At this time, beam position and slope are determined. Maybe, | 1073 Hmm. At this time, beam position and slope are determined. Maybe, |
1074 stem directions and length should set to relative to the chord's | 1074 stem directions and length should set to relative to the chord's |
1075 position of the beam. */ | 1075 position of the beam. */ |
1076 MAKE_SCHEME_CALLBACK (Beam, set_stem_lengths, 1); | 1076 MAKE_SCHEME_CALLBACK (Beam, set_stem_lengths, 1); |
1077 SCM | 1077 SCM |
1078 Beam::set_stem_lengths (SCM smob) | 1078 Beam::set_stem_lengths (SCM smob) |
1079 { | 1079 { |
1080 Grob *me = unsmob<Grob> (smob); | 1080 Grob *me = unsmob<Grob> (smob); |
1081 | 1081 |
1082 /* trigger callbacks. */ | 1082 /* trigger callbacks. */ |
1083 (void) me->get_property ("direction"); | 1083 (void) get_property (me, "direction"); |
1084 (void) me->get_property ("beaming"); | 1084 (void) get_property (me, "beaming"); |
1085 | 1085 |
1086 SCM posns = me->get_property ("positions"); | 1086 SCM posns = get_property (me, "positions"); |
1087 | 1087 |
1088 extract_grob_set (me, "stems", stems); | 1088 extract_grob_set (me, "stems", stems); |
1089 if (!stems.size ()) | 1089 if (!stems.size ()) |
1090 return posns; | 1090 return posns; |
1091 | 1091 |
1092 Grob *common[2]; | 1092 Grob *common[2]; |
1093 for (int a = 2; a--;) | 1093 for (int a = 2; a--;) |
1094 common[a] = common_refpoint_of_array (stems, me, Axis (a)); | 1094 common[a] = common_refpoint_of_array (stems, me, Axis (a)); |
1095 | 1095 |
1096 Drul_array<Real> pos = ly_scm2realdrul (posns); | 1096 Drul_array<Real> pos = ly_scm2realdrul (posns); |
1097 Real staff_space = Staff_symbol_referencer::staff_space (me); | 1097 Real staff_space = Staff_symbol_referencer::staff_space (me); |
1098 scale_drul (&pos, staff_space); | 1098 scale_drul (&pos, staff_space); |
1099 | 1099 |
1100 bool gap = false; | 1100 bool gap = false; |
1101 Real thick = 0.0; | 1101 Real thick = 0.0; |
1102 if (robust_scm2int (me->get_property ("gap-count"), 0)) | 1102 if (robust_scm2int (get_property (me, "gap-count"), 0)) |
1103 { | 1103 { |
1104 gap = true; | 1104 gap = true; |
1105 thick = get_beam_thickness (me); | 1105 thick = get_beam_thickness (me); |
1106 } | 1106 } |
1107 | 1107 |
1108 Interval x_span = robust_scm2interval (me->get_property ("X-positions"), Inter
val (0, 0)); | 1108 Interval x_span = robust_scm2interval (get_property (me, "X-positions"), Inter
val (0, 0)); |
1109 Direction feather_dir = to_dir (me->get_property ("grow-direction")); | 1109 Direction feather_dir = to_dir (get_property (me, "grow-direction")); |
1110 | 1110 |
1111 for (vsize i = 0; i < stems.size (); i++) | 1111 for (vsize i = 0; i < stems.size (); i++) |
1112 { | 1112 { |
1113 Grob *s = stems[i]; | 1113 Grob *s = stems[i]; |
1114 bool french = to_boolean (s->get_property ("french-beaming")); | 1114 bool french = to_boolean (get_property (s, "french-beaming")); |
1115 int french_count = 0; | 1115 int french_count = 0; |
1116 if (french) | 1116 if (french) |
1117 { | 1117 { |
1118 /* | 1118 /* |
1119 french_count is the number of beams a particular stem length | 1119 french_count is the number of beams a particular stem length |
1120 must be shortened in French Beaming. Determined by intersecting | 1120 must be shortened in French Beaming. Determined by intersecting |
1121 left/right beaming information Slices. | 1121 left/right beaming information Slices. |
1122 */ | 1122 */ |
1123 SCM beaming = s->get_property ("beaming"); | 1123 SCM beaming = get_property (s, "beaming"); |
1124 Slice le = int_list_to_slice (scm_car (beaming)); | 1124 Slice le = int_list_to_slice (scm_car (beaming)); |
1125 Slice ri = int_list_to_slice (scm_cdr (beaming)); | 1125 Slice ri = int_list_to_slice (scm_cdr (beaming)); |
1126 le.intersect (ri); | 1126 le.intersect (ri); |
1127 french_count = le.length (); | 1127 french_count = le.length (); |
1128 } | 1128 } |
1129 Beam_stem_end stem_end = calc_stem_y (me, s, common, | 1129 Beam_stem_end stem_end = calc_stem_y (me, s, common, |
1130 x_span[LEFT], x_span[RIGHT], | 1130 x_span[LEFT], x_span[RIGHT], |
1131 feather_dir, pos, french_count); | 1131 feather_dir, pos, french_count); |
1132 Real stem_y = stem_end.stem_y_; | 1132 Real stem_y = stem_end.stem_y_; |
1133 Real fb_stem_adjustment = stem_end.french_beaming_stem_adjustment_; | 1133 Real fb_stem_adjustment = stem_end.french_beaming_stem_adjustment_; |
(...skipping 22 matching lines...) Expand all Loading... |
1156 extract_grob_set (me, "stems", stems); | 1156 extract_grob_set (me, "stems", stems); |
1157 | 1157 |
1158 for (vsize i = 0; i < stems.size (); i++) | 1158 for (vsize i = 0; i < stems.size (); i++) |
1159 { | 1159 { |
1160 /* | 1160 /* |
1161 Don't overwrite user settings. | 1161 Don't overwrite user settings. |
1162 */ | 1162 */ |
1163 for (LEFT_and_RIGHT (d)) | 1163 for (LEFT_and_RIGHT (d)) |
1164 { | 1164 { |
1165 Grob *stem = stems[i]; | 1165 Grob *stem = stems[i]; |
1166 SCM beaming_prop = stem->get_property ("beaming"); | 1166 SCM beaming_prop = get_property (stem, "beaming"); |
1167 if (scm_is_null (beaming_prop) | 1167 if (scm_is_null (beaming_prop) |
1168 || scm_is_null (index_get_cell (beaming_prop, d))) | 1168 || scm_is_null (index_get_cell (beaming_prop, d))) |
1169 { | 1169 { |
1170 int count = beaming->beamlet_count (i, d); | 1170 int count = beaming->beamlet_count (i, d); |
1171 if (i > 0 | 1171 if (i > 0 |
1172 && i + 1 < stems.size () | 1172 && i + 1 < stems.size () |
1173 && Stem::is_invisible (stem)) | 1173 && Stem::is_invisible (stem)) |
1174 count = std::min (count, beaming->beamlet_count (i, -d)); | 1174 count = std::min (count, beaming->beamlet_count (i, -d)); |
1175 | 1175 |
1176 if ( ((i == 0 && d == LEFT) | 1176 if ( ((i == 0 && d == LEFT) |
1177 || (i == stems.size () - 1 && d == RIGHT)) | 1177 || (i == stems.size () - 1 && d == RIGHT)) |
1178 && stems.size () > 1 | 1178 && stems.size () > 1 |
1179 && to_boolean (me->get_property ("clip-edges"))) | 1179 && to_boolean (get_property (me, "clip-edges"))) |
1180 count = 0; | 1180 count = 0; |
1181 | 1181 |
1182 Stem::set_beaming (stem, count, d); | 1182 Stem::set_beaming (stem, count, d); |
1183 } | 1183 } |
1184 } | 1184 } |
1185 } | 1185 } |
1186 } | 1186 } |
1187 | 1187 |
1188 vsize | 1188 vsize |
1189 Beam::forced_stem_count (Grob *me) | 1189 Beam::forced_stem_count (Grob *me) |
1190 { | 1190 { |
1191 extract_grob_set (me, "normal-stems", stems); | 1191 extract_grob_set (me, "normal-stems", stems); |
1192 | 1192 |
1193 vsize f = 0; | 1193 vsize f = 0; |
1194 for (vsize i = 0; i < stems.size (); i++) | 1194 for (vsize i = 0; i < stems.size (); i++) |
1195 { | 1195 { |
1196 Grob *s = stems[i]; | 1196 Grob *s = stems[i]; |
1197 | 1197 |
1198 /* I can imagine counting those boundaries as a half forced stem, | 1198 /* I can imagine counting those boundaries as a half forced stem, |
1199 but let's count them full for now. */ | 1199 but let's count them full for now. */ |
1200 Direction defdir = to_dir (s->get_property ("default-direction")); | 1200 Direction defdir = to_dir (get_property (s, "default-direction")); |
1201 | 1201 |
1202 if (abs (Stem::chord_start_y (s)) > 0.1 | 1202 if (abs (Stem::chord_start_y (s)) > 0.1 |
1203 && defdir | 1203 && defdir |
1204 && get_grob_direction (s) != defdir) | 1204 && get_grob_direction (s) != defdir) |
1205 f++; | 1205 f++; |
1206 } | 1206 } |
1207 return f; | 1207 return f; |
1208 } | 1208 } |
1209 | 1209 |
1210 vsize | 1210 vsize |
(...skipping 28 matching lines...) Expand all Loading... |
1239 rest -> stem -> beam -> interpolate_y_position () | 1239 rest -> stem -> beam -> interpolate_y_position () |
1240 */ | 1240 */ |
1241 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, rest_collision_callback, 2, 1, ""); | 1241 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, rest_collision_callback, 2, 1, ""); |
1242 SCM | 1242 SCM |
1243 Beam::rest_collision_callback (SCM smob, SCM prev_offset) | 1243 Beam::rest_collision_callback (SCM smob, SCM prev_offset) |
1244 { | 1244 { |
1245 if (!scm_is_number (prev_offset)) | 1245 if (!scm_is_number (prev_offset)) |
1246 prev_offset = SCM_INUM0; | 1246 prev_offset = SCM_INUM0; |
1247 | 1247 |
1248 Grob *rest = unsmob<Grob> (smob); | 1248 Grob *rest = unsmob<Grob> (smob); |
1249 if (scm_is_number (rest->get_property ("staff-position"))) | 1249 if (scm_is_number (get_property (rest, "staff-position"))) |
1250 return prev_offset; | 1250 return prev_offset; |
1251 | 1251 |
1252 Grob *stem = unsmob<Grob> (rest->get_object ("stem")); | 1252 Grob *stem = unsmob<Grob> (get_object (rest, "stem")); |
1253 | 1253 |
1254 if (!stem) | 1254 if (!stem) |
1255 return prev_offset; | 1255 return prev_offset; |
1256 | 1256 |
1257 Grob *beam = unsmob<Grob> (stem->get_object ("beam")); | 1257 Grob *beam = unsmob<Grob> (get_object (stem, "beam")); |
1258 if (!beam | 1258 if (!beam |
1259 || !has_interface<Beam> (beam) | 1259 || !has_interface<Beam> (beam) |
1260 || !Beam::normal_stem_count (beam)) | 1260 || !Beam::normal_stem_count (beam)) |
1261 return prev_offset; | 1261 return prev_offset; |
1262 | 1262 |
1263 Grob *common_y = rest->common_refpoint (beam, Y_AXIS); | 1263 Grob *common_y = rest->common_refpoint (beam, Y_AXIS); |
1264 | 1264 |
1265 Drul_array<Real> pos (robust_scm2drul (beam->get_property ("positions"), | 1265 Drul_array<Real> pos (robust_scm2drul (get_property (beam, "positions"), |
1266 Drul_array<Real> (0, 0))); | 1266 Drul_array<Real> (0, 0))); |
1267 | 1267 |
1268 for (LEFT_and_RIGHT (dir)) | 1268 for (LEFT_and_RIGHT (dir)) |
1269 pos[dir] += beam->relative_coordinate (common_y, Y_AXIS); | 1269 pos[dir] += beam->relative_coordinate (common_y, Y_AXIS); |
1270 | 1270 |
1271 Real staff_space = Staff_symbol_referencer::staff_space (rest); | 1271 Real staff_space = Staff_symbol_referencer::staff_space (rest); |
1272 | 1272 |
1273 scale_drul (&pos, staff_space); | 1273 scale_drul (&pos, staff_space); |
1274 | 1274 |
1275 Real dy = pos[RIGHT] - pos[LEFT]; | 1275 Real dy = pos[RIGHT] - pos[LEFT]; |
1276 | 1276 |
1277 extract_grob_set (beam, "stems", stems); | 1277 extract_grob_set (beam, "stems", stems); |
1278 Grob *common = common_refpoint_of_array (stems, beam, X_AXIS); | 1278 Grob *common = common_refpoint_of_array (stems, beam, X_AXIS); |
1279 | 1279 |
1280 Interval x_span = robust_scm2interval (beam->get_property ("X-positions"), | 1280 Interval x_span = robust_scm2interval (get_property (beam, "X-positions"), |
1281 Interval (0.0, 0.0)); | 1281 Interval (0.0, 0.0)); |
1282 Real x0 = x_span[LEFT]; | 1282 Real x0 = x_span[LEFT]; |
1283 Real dx = x_span.length (); | 1283 Real dx = x_span.length (); |
1284 Real slope = dy && dx ? dy / dx : 0; | 1284 Real slope = dy && dx ? dy / dx : 0; |
1285 | 1285 |
1286 Direction d = get_grob_direction (stem); | 1286 Direction d = get_grob_direction (stem); |
1287 Real stem_y = pos[LEFT] | 1287 Real stem_y = pos[LEFT] |
1288 + (stem->relative_coordinate (common, X_AXIS) - x0) * slope; | 1288 + (stem->relative_coordinate (common, X_AXIS) - x0) * slope; |
1289 | 1289 |
1290 Real beam_translation = get_beam_translation (beam); | 1290 Real beam_translation = get_beam_translation (beam); |
1291 Real beam_thickness = Beam::get_beam_thickness (beam); | 1291 Real beam_thickness = Beam::get_beam_thickness (beam); |
1292 | 1292 |
1293 /* | 1293 /* |
1294 TODO: this is not strictly correct for 16th knee beams. | 1294 TODO: this is not strictly correct for 16th knee beams. |
1295 */ | 1295 */ |
1296 int beam_count | 1296 int beam_count |
1297 = Stem::beam_multiplicity (stem).length () + 1; | 1297 = Stem::beam_multiplicity (stem).length () + 1; |
1298 | 1298 |
1299 Real height_of_my_beams = beam_thickness / 2 | 1299 Real height_of_my_beams = beam_thickness / 2 |
1300 + (beam_count - 1) * beam_translation; | 1300 + (beam_count - 1) * beam_translation; |
1301 Real beam_y = stem_y - d * height_of_my_beams; | 1301 Real beam_y = stem_y - d * height_of_my_beams; |
1302 | 1302 |
1303 Real offset = robust_scm2double (prev_offset, 0.0); | 1303 Real offset = robust_scm2double (prev_offset, 0.0); |
1304 Interval rest_extent = rest->extent (rest, Y_AXIS); | 1304 Interval rest_extent = rest->extent (rest, Y_AXIS); |
1305 rest_extent.translate (offset + rest->parent_relative (common_y, Y_AXIS)); | 1305 rest_extent.translate (offset + rest->parent_relative (common_y, Y_AXIS)); |
1306 | 1306 |
1307 Real rest_dim = rest_extent[d]; | 1307 Real rest_dim = rest_extent[d]; |
1308 Real minimum_distance | 1308 Real minimum_distance |
1309 = staff_space * (robust_scm2double (stem->get_property ("stemlet-length"), 0
.0) | 1309 = staff_space * (robust_scm2double (get_property (stem, "stemlet-length"), 0
.0) |
1310 + robust_scm2double (rest->get_property ("minimum-distance"
), 0.0)); | 1310 + robust_scm2double (get_property (rest, "minimum-distance"
), 0.0)); |
1311 | 1311 |
1312 Real shift = d * std::min (d * (beam_y - d * minimum_distance - rest_dim), 0.0
); | 1312 Real shift = d * std::min (d * (beam_y - d * minimum_distance - rest_dim), 0.0
); |
1313 | 1313 |
1314 shift /= staff_space; | 1314 shift /= staff_space; |
1315 | 1315 |
1316 /* Always move discretely by half spaces */ | 1316 /* Always move discretely by half spaces */ |
1317 shift = ceil (fabs (shift * 2.0)) / 2.0 * sign (shift); | 1317 shift = ceil (fabs (shift * 2.0)) / 2.0 * sign (shift); |
1318 | 1318 |
1319 Interval staff_span = Staff_symbol_referencer::staff_span (rest); | 1319 Interval staff_span = Staff_symbol_referencer::staff_span (rest); |
1320 staff_span *= staff_space / 2; | 1320 staff_span *= staff_space / 2; |
(...skipping 14 matching lines...) Expand all Loading... |
1335 SCM | 1335 SCM |
1336 Beam::pure_rest_collision_callback (SCM smob, | 1336 Beam::pure_rest_collision_callback (SCM smob, |
1337 SCM, /* start */ | 1337 SCM, /* start */ |
1338 SCM, /* end */ | 1338 SCM, /* end */ |
1339 SCM prev_offset) | 1339 SCM prev_offset) |
1340 { | 1340 { |
1341 if (!scm_is_number (prev_offset)) | 1341 if (!scm_is_number (prev_offset)) |
1342 prev_offset = SCM_INUM0; | 1342 prev_offset = SCM_INUM0; |
1343 | 1343 |
1344 Grob *me = unsmob<Grob> (smob); | 1344 Grob *me = unsmob<Grob> (smob); |
1345 Grob *stem = unsmob<Grob> (me->get_object ("stem")); | 1345 Grob *stem = unsmob<Grob> (get_object (me, "stem")); |
1346 if (!stem) | 1346 if (!stem) |
1347 return prev_offset; | 1347 return prev_offset; |
1348 Grob *beam = unsmob<Grob> (stem->get_object ("beam")); | 1348 Grob *beam = unsmob<Grob> (get_object (stem, "beam")); |
1349 if (!beam | 1349 if (!beam |
1350 || !Beam::normal_stem_count (beam) | 1350 || !Beam::normal_stem_count (beam) |
1351 || !is_direction (beam->get_property_data ("direction"))) | 1351 || !is_direction (get_property_data (beam, "direction"))) |
1352 return prev_offset; | 1352 return prev_offset; |
1353 | 1353 |
1354 Real ss = Staff_symbol_referencer::staff_space (me); | 1354 Real ss = Staff_symbol_referencer::staff_space (me); |
1355 | 1355 |
1356 extract_grob_set (beam, "stems", stems); | 1356 extract_grob_set (beam, "stems", stems); |
1357 vector<Grob *> my_stems; | 1357 vector<Grob *> my_stems; |
1358 | 1358 |
1359 for (vsize i = 0; i < stems.size (); i++) | 1359 for (vsize i = 0; i < stems.size (); i++) |
1360 if (Stem::head_count (stems[i]) || stems[i] == stem) | 1360 if (Stem::head_count (stems[i]) || stems[i] == stem) |
1361 my_stems.push_back (stems[i]); | 1361 my_stems.push_back (stems[i]); |
(...skipping 23 matching lines...) Expand all Loading... |
1385 | 1385 |
1386 /* Estimate the closest beam to be four positions away from the heads, */ | 1386 /* Estimate the closest beam to be four positions away from the heads, */ |
1387 Direction beamdir = get_grob_direction (beam); | 1387 Direction beamdir = get_grob_direction (beam); |
1388 Real beam_pos = (Stem::head_positions (left)[beamdir] | 1388 Real beam_pos = (Stem::head_positions (left)[beamdir] |
1389 + Stem::head_positions (right)[beamdir]) / 2.0 | 1389 + Stem::head_positions (right)[beamdir]) / 2.0 |
1390 + 4.0 * beamdir; // four staff-positions | 1390 + 4.0 * beamdir; // four staff-positions |
1391 /* and that the closest beam never crosses staff center by more than two posit
ions */ | 1391 /* and that the closest beam never crosses staff center by more than two posit
ions */ |
1392 beam_pos = std::max (-2.0, beam_pos * beamdir) * beamdir; | 1392 beam_pos = std::max (-2.0, beam_pos * beamdir) * beamdir; |
1393 | 1393 |
1394 Real minimum_distance | 1394 Real minimum_distance |
1395 = ss * (robust_scm2double (stem->get_property ("stemlet-length"), 0.0) | 1395 = ss * (robust_scm2double (get_property (stem, "stemlet-length"), 0.0) |
1396 + robust_scm2double (me->get_property ("minimum-distance"), 0.0)); | 1396 + robust_scm2double (get_property (me, "minimum-distance"), 0.0)); |
1397 Real offset = beam_pos * ss / 2.0 | 1397 Real offset = beam_pos * ss / 2.0 |
1398 - minimum_distance * beamdir | 1398 - minimum_distance * beamdir |
1399 - me->extent (me, Y_AXIS)[beamdir]; | 1399 - me->extent (me, Y_AXIS)[beamdir]; |
1400 Real previous = robust_scm2double (prev_offset, 0.0); | 1400 Real previous = robust_scm2double (prev_offset, 0.0); |
1401 | 1401 |
1402 /* Always move by a whole number of staff spaces, always away from the beam */ | 1402 /* Always move by a whole number of staff spaces, always away from the beam */ |
1403 offset = floor (std::min (0.0, (offset - previous) / ss * beamdir)) | 1403 offset = floor (std::min (0.0, (offset - previous) / ss * beamdir)) |
1404 * ss * beamdir + previous; | 1404 * ss * beamdir + previous; |
1405 | 1405 |
1406 return scm_from_double (offset); | 1406 return scm_from_double (offset); |
1407 } | 1407 } |
1408 | 1408 |
1409 bool | 1409 bool |
1410 Beam::is_knee (Grob *me) | 1410 Beam::is_knee (Grob *me) |
1411 { | 1411 { |
1412 SCM k = me->get_property ("knee"); | 1412 SCM k = get_property (me, "knee"); |
1413 if (scm_is_bool (k)) | 1413 if (scm_is_bool (k)) |
1414 return ly_scm2bool (k); | 1414 return ly_scm2bool (k); |
1415 | 1415 |
1416 bool knee = false; | 1416 bool knee = false; |
1417 int d = 0; | 1417 int d = 0; |
1418 extract_grob_set (me, "stems", stems); | 1418 extract_grob_set (me, "stems", stems); |
1419 for (vsize i = stems.size (); i--;) | 1419 for (vsize i = stems.size (); i--;) |
1420 { | 1420 { |
1421 Direction dir = get_grob_direction (stems[i]); | 1421 Direction dir = get_grob_direction (stems[i]); |
1422 if (d && d != dir) | 1422 if (d && d != dir) |
1423 { | 1423 { |
1424 knee = true; | 1424 knee = true; |
1425 break; | 1425 break; |
1426 } | 1426 } |
1427 d = dir; | 1427 d = dir; |
1428 } | 1428 } |
1429 | 1429 |
1430 me->set_property ("knee", ly_bool2scm (knee)); | 1430 set_property (me, "knee", ly_bool2scm (knee)); |
1431 | 1431 |
1432 return knee; | 1432 return knee; |
1433 } | 1433 } |
1434 | 1434 |
1435 bool | 1435 bool |
1436 Beam::is_cross_staff (Grob *me) | 1436 Beam::is_cross_staff (Grob *me) |
1437 { | 1437 { |
1438 extract_grob_set (me, "stems", stems); | 1438 extract_grob_set (me, "stems", stems); |
1439 Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me); | 1439 Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me); |
1440 for (vsize i = 0; i < stems.size (); i++) | 1440 for (vsize i = 0; i < stems.size (); i++) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 "least-squares-dy " | 1534 "least-squares-dy " |
1535 "neutral-direction " | 1535 "neutral-direction " |
1536 "normal-stems " | 1536 "normal-stems " |
1537 "positions " | 1537 "positions " |
1538 "quantized-positions " | 1538 "quantized-positions " |
1539 "shorten " | 1539 "shorten " |
1540 "skip-quanting " | 1540 "skip-quanting " |
1541 "stems " | 1541 "stems " |
1542 "X-positions " | 1542 "X-positions " |
1543 ); | 1543 ); |
LEFT | RIGHT |