LEFT | RIGHT |
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 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 278 |
279 Direction this_dir = get_grob_direction (this_stem); | 279 Direction this_dir = get_grob_direction (this_stem); |
280 if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming)) | 280 if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming)) |
281 { | 281 { |
282 int start_point = position_with_maximal_common_beams | 282 int start_point = position_with_maximal_common_beams |
283 (last_beaming, this_beaming, | 283 (last_beaming, this_beaming, |
284 last_dir ? last_dir : this_dir, | 284 last_dir ? last_dir : this_dir, |
285 this_dir); | 285 this_dir); |
286 | 286 |
287 Slice new_slice; | 287 Slice new_slice; |
288 for(LEFT_and_RIGHT(d)) | 288 for (LEFT_and_RIGHT (d)) |
289 { | 289 { |
290 new_slice.set_empty (); | 290 new_slice.set_empty (); |
291 SCM s = index_get_cell (this_beaming, d); | 291 SCM s = index_get_cell (this_beaming, d); |
292 for (; scm_is_pair (s); s = scm_cdr (s)) | 292 for (; scm_is_pair (s); s = scm_cdr (s)) |
293 { | 293 { |
294 int new_beam_pos | 294 int new_beam_pos |
295 = start_point - this_dir * scm_to_int (scm_car (s)); | 295 = start_point - this_dir * scm_to_int (scm_car (s)); |
296 | 296 |
297 new_slice.add_point (new_beam_pos); | 297 new_slice.add_point (new_beam_pos); |
298 scm_set_car_x (s, scm_from_int (new_beam_pos)); | 298 scm_set_car_x (s, scm_from_int (new_beam_pos)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 /* ugh, this has a side-effect that we need to ensure that | 342 /* ugh, this has a side-effect that we need to ensure that |
343 Stem #'beaming is correct */ | 343 Stem #'beaming is correct */ |
344 Grob *me_grob = unsmob_grob (smob); | 344 Grob *me_grob = unsmob_grob (smob); |
345 (void) me_grob->get_property ("beaming"); | 345 (void) me_grob->get_property ("beaming"); |
346 | 346 |
347 Spanner *me = dynamic_cast<Spanner *> (me_grob); | 347 Spanner *me = dynamic_cast<Spanner *> (me_grob); |
348 | 348 |
349 extract_grob_set (me, "stems", stems); | 349 extract_grob_set (me, "stems", stems); |
350 | 350 |
351 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); | 351 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); |
352 for(LEFT_and_RIGHT(d)) | 352 for (LEFT_and_RIGHT (d)) |
353 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); | 353 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); |
354 | 354 |
355 int gap_count = robust_scm2int (me->get_property ("gap-count"), 0); | 355 int gap_count = robust_scm2int (me->get_property ("gap-count"), 0); |
356 Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0); | 356 Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0); |
357 | 357 |
358 Position_stem_segments_map stem_segments; | 358 Position_stem_segments_map stem_segments; |
359 Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); | 359 Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); |
360 | 360 |
361 /* There are two concepts of "rank" that are used in the following code. | 361 /* There are two concepts of "rank" that are used in the following code. |
362 The beam_rank is the vertical position of the beam (larger numbers are | 362 The beam_rank is the vertical position of the beam (larger numbers are |
363 closer to the noteheads). Beam_stem_segment.rank_, on the other hand, | 363 closer to the noteheads). Beam_stem_segment.rank_, on the other hand, |
364 is the horizontal position of the segment (this is incremented by two | 364 is the horizontal position of the segment (this is incremented by two |
365 for each stem; the beam segment on the right side of the stem has | 365 for each stem; the beam segment on the right side of the stem has |
366 a higher rank (by one) than its neighbour to the left). */ | 366 a higher rank (by one) than its neighbour to the left). */ |
367 Slice ranks; | 367 Slice ranks; |
368 for (vsize i = 0; i < stems.size (); i++) | 368 for (vsize i = 0; i < stems.size (); i++) |
369 { | 369 { |
370 Grob *stem = stems[i]; | 370 Grob *stem = stems[i]; |
371 Real stem_width = robust_scm2double (stem->get_property ("thickness"), 1.0
) * lt; | 371 Real stem_width = robust_scm2double (stem->get_property ("thickness"), 1.0
) * lt; |
372 Real stem_x = stem->relative_coordinate (commonx, X_AXIS); | 372 Real stem_x = stem->relative_coordinate (commonx, X_AXIS); |
373 SCM beaming = stem->get_property ("beaming"); | 373 SCM beaming = stem->get_property ("beaming"); |
374 | 374 |
375 for(LEFT_and_RIGHT(d)) | 375 for (LEFT_and_RIGHT (d)) |
376 { | 376 { |
377 // Find the maximum and minimum beam ranks. | 377 // Find the maximum and minimum beam ranks. |
378 // Given that RANKS is never reset to empty, the interval will always
be | 378 // Given that RANKS is never reset to empty, the interval will always
be |
379 // smallest for the left beamlet of the first stem, and then it might
grow. | 379 // smallest for the left beamlet of the first stem, and then it might
grow. |
380 // Do we really want this? (It only affects the tremolo gaps) --jneem | 380 // Do we really want this? (It only affects the tremolo gaps) --jneem |
381 for (SCM s = index_get_cell (beaming, d); | 381 for (SCM s = index_get_cell (beaming, d); |
382 scm_is_pair (s); s = scm_cdr (s)) | 382 scm_is_pair (s); s = scm_cdr (s)) |
383 { | 383 { |
384 if (!scm_is_integer (scm_car (s))) | 384 if (!scm_is_integer (scm_car (s))) |
385 continue; | 385 continue; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 for (vsize j = 0; j < segs.size (); j++) | 433 for (vsize j = 0; j < segs.size (); j++) |
434 { | 434 { |
435 // Keeping track of the different directions here is a little tricky. | 435 // Keeping track of the different directions here is a little tricky. |
436 // segs[j].dir_ is the direction of the beam segment relative to the s
tem | 436 // segs[j].dir_ is the direction of the beam segment relative to the s
tem |
437 // (ie. segs[j].dir_ == LEFT if the beam segment sticks out to the lef
t of | 437 // (ie. segs[j].dir_ == LEFT if the beam segment sticks out to the lef
t of |
438 // its stem) whereas event_dir refers to the edge of the beam segment
that | 438 // its stem) whereas event_dir refers to the edge of the beam segment
that |
439 // we are currently looking at (ie. if segs[j].dir_ == event_dir then
we | 439 // we are currently looking at (ie. if segs[j].dir_ == event_dir then
we |
440 // are looking at that edge of the beam segment that is furthest from
its | 440 // are looking at that edge of the beam segment that is furthest from
its |
441 // stem). | 441 // stem). |
442 Beam_stem_segment const &seg = segs[j]; | 442 Beam_stem_segment const &seg = segs[j]; |
443 for(LEFT_and_RIGHT(event_dir)) | 443 for (LEFT_and_RIGHT (event_dir)) |
444 { | 444 { |
445 Beam_stem_segment const &neighbor_seg = segs[j + event_dir]; | 445 Beam_stem_segment const &neighbor_seg = segs[j + event_dir]; |
446 // TODO: make names clearer? --jneem | 446 // TODO: make names clearer? --jneem |
447 // on_line_bound: whether the current segment is on the boundary o
f the WHOLE beam | 447 // on_line_bound: whether the current segment is on the boundary o
f the WHOLE beam |
448 // on_beam_bound: whether the current segment is on the boundary o
f just that part | 448 // on_beam_bound: whether the current segment is on the boundary o
f just that part |
449 // of the beam with the current beam_rank | 449 // of the beam with the current beam_rank |
450 bool on_line_bound = (seg.dir_ == LEFT) ? seg.stem_index_ == 0 | 450 bool on_line_bound = (seg.dir_ == LEFT) ? seg.stem_index_ == 0 |
451 : seg.stem_index_ == stems.size () - 1; | 451 : seg.stem_index_ == stems.size () - 1; |
452 bool on_beam_bound = (event_dir == LEFT) ? j == 0 | 452 bool on_beam_bound = (event_dir == LEFT) ? j == 0 |
453 : j == segs.size () - 1; | 453 : j == segs.size () - 1; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 scm_car (s), | 569 scm_car (s), |
570 SCM_EOL), | 570 SCM_EOL), |
571 Interval (0.0, 0.0))); | 571 Interval (0.0, 0.0))); |
572 | 572 |
573 // Case for beams without segments (i.e. uniting two skips with a beam) | 573 // Case for beams without segments (i.e. uniting two skips with a beam) |
574 // TODO: should issue a warning? warning likely issued downstream, but couldn
't hurt... | 574 // TODO: should issue a warning? warning likely issued downstream, but couldn
't hurt... |
575 if (x_positions.is_empty ()) | 575 if (x_positions.is_empty ()) |
576 { | 576 { |
577 extract_grob_set (me, "stems", stems); | 577 extract_grob_set (me, "stems", stems); |
578 Grob *common_x = common_refpoint_of_array (stems, me, X_AXIS); | 578 Grob *common_x = common_refpoint_of_array (stems, me, X_AXIS); |
579 for(LEFT_and_RIGHT(d)) | 579 for (LEFT_and_RIGHT (d)) |
580 x_positions[d] = me->relative_coordinate (common_x, X_AXIS); | 580 x_positions[d] = me->relative_coordinate (common_x, X_AXIS); |
581 } | 581 } |
582 return ly_interval2scm (x_positions); | 582 return ly_interval2scm (x_positions); |
583 } | 583 } |
584 | 584 |
585 vector<Beam_segment> | 585 vector<Beam_segment> |
586 Beam::get_beam_segments (Grob *me) | 586 Beam::get_beam_segments (Grob *me) |
587 { | 587 { |
588 SCM segments_scm = me->get_property ("beam-segments"); | 588 SCM segments_scm = me->get_property ("beam-segments"); |
589 vector<Beam_segment> segments; | 589 vector<Beam_segment> segments; |
(...skipping 15 matching lines...) Expand all Loading... |
605 /* | 605 /* |
606 TODO - mild code dup for all the commonx calls. | 606 TODO - mild code dup for all the commonx calls. |
607 Some use just common_refpoint_of_array, some (in print and | 607 Some use just common_refpoint_of_array, some (in print and |
608 calc_beam_segments) use this plus calls to get_bound. | 608 calc_beam_segments) use this plus calls to get_bound. |
609 | 609 |
610 Figure out if there is any particular reason for this and | 610 Figure out if there is any particular reason for this and |
611 consolidate in one Beam::get_common function. | 611 consolidate in one Beam::get_common function. |
612 */ | 612 */ |
613 extract_grob_set (me, "stems", stems); | 613 extract_grob_set (me, "stems", stems); |
614 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); | 614 Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); |
615 for(LEFT_and_RIGHT(d)) | 615 for (LEFT_and_RIGHT (d)) |
616 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); | 616 commonx = me->get_bound (d)->common_refpoint (commonx, X_AXIS); |
617 | 617 |
618 vector<Beam_segment> segments = get_beam_segments (me); | 618 vector<Beam_segment> segments = get_beam_segments (me); |
619 | 619 |
620 if (!segments.size ()) | 620 if (!segments.size ()) |
621 return SCM_EOL; | 621 return SCM_EOL; |
622 | 622 |
623 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); | 623 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); |
624 | 624 |
625 SCM posns = me->get_property ("quantized-positions"); | 625 SCM posns = me->get_property ("quantized-positions"); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 | 746 |
747 Direction | 747 Direction |
748 Beam::get_default_dir (Grob *me) | 748 Beam::get_default_dir (Grob *me) |
749 { | 749 { |
750 extract_grob_set (me, "stems", stems); | 750 extract_grob_set (me, "stems", stems); |
751 | 751 |
752 Drul_array<Real> extremes (0.0, 0.0); | 752 Drul_array<Real> extremes (0.0, 0.0); |
753 for (iterof (s, stems); s != stems.end (); s++) | 753 for (iterof (s, stems); s != stems.end (); s++) |
754 { | 754 { |
755 Interval positions = Stem::head_positions (*s); | 755 Interval positions = Stem::head_positions (*s); |
756 for(DOWN_and_UP(d)) | 756 for (DOWN_and_UP (d)) |
757 { | 757 { |
758 if (sign (positions[d]) == d) | 758 if (sign (positions[d]) == d) |
759 extremes[d] = d * max (d * positions[d], d * extremes[d]); | 759 extremes[d] = d * max (d * positions[d], d * extremes[d]); |
760 } | 760 } |
761 } | 761 } |
762 | 762 |
763 Drul_array<int> total (0, 0); | 763 Drul_array<int> total (0, 0); |
764 Drul_array<int> count (0, 0); | 764 Drul_array<int> count (0, 0); |
765 | 765 |
766 bool force_dir = false; | 766 bool force_dir = false; |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1118 void | 1118 void |
1119 Beam::set_beaming (Grob *me, Beaming_pattern const *beaming) | 1119 Beam::set_beaming (Grob *me, Beaming_pattern const *beaming) |
1120 { | 1120 { |
1121 extract_grob_set (me, "stems", stems); | 1121 extract_grob_set (me, "stems", stems); |
1122 | 1122 |
1123 for (vsize i = 0; i < stems.size (); i++) | 1123 for (vsize i = 0; i < stems.size (); i++) |
1124 { | 1124 { |
1125 /* | 1125 /* |
1126 Don't overwrite user settings. | 1126 Don't overwrite user settings. |
1127 */ | 1127 */ |
1128 for(LEFT_and_RIGHT(d)) | 1128 for (LEFT_and_RIGHT (d)) |
1129 { | 1129 { |
1130 Grob *stem = stems[i]; | 1130 Grob *stem = stems[i]; |
1131 SCM beaming_prop = stem->get_property ("beaming"); | 1131 SCM beaming_prop = stem->get_property ("beaming"); |
1132 if (beaming_prop == SCM_EOL | 1132 if (beaming_prop == SCM_EOL |
1133 || index_get_cell (beaming_prop, d) == SCM_EOL) | 1133 || index_get_cell (beaming_prop, d) == SCM_EOL) |
1134 { | 1134 { |
1135 int count = beaming->beamlet_count (i, d); | 1135 int count = beaming->beamlet_count (i, d); |
1136 if (i > 0 | 1136 if (i > 0 |
1137 && i + 1 < stems.size () | 1137 && i + 1 < stems.size () |
1138 && Stem::is_invisible (stem)) | 1138 && Stem::is_invisible (stem)) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 if (!beam | 1221 if (!beam |
1222 || !Beam::has_interface (beam) | 1222 || !Beam::has_interface (beam) |
1223 || !Beam::normal_stem_count (beam)) | 1223 || !Beam::normal_stem_count (beam)) |
1224 return scm_from_double (0.0); | 1224 return scm_from_double (0.0); |
1225 | 1225 |
1226 Grob *common_y = rest->common_refpoint (beam, Y_AXIS); | 1226 Grob *common_y = rest->common_refpoint (beam, Y_AXIS); |
1227 | 1227 |
1228 Drul_array<Real> pos (robust_scm2drul (beam->get_property ("positions"), | 1228 Drul_array<Real> pos (robust_scm2drul (beam->get_property ("positions"), |
1229 Drul_array<Real> (0, 0))); | 1229 Drul_array<Real> (0, 0))); |
1230 | 1230 |
1231 for(LEFT_and_RIGHT(dir)) | 1231 for (LEFT_and_RIGHT (dir)) |
1232 pos[dir] += beam->relative_coordinate (common_y, Y_AXIS); | 1232 pos[dir] += beam->relative_coordinate (common_y, Y_AXIS); |
1233 | 1233 |
1234 Real staff_space = Staff_symbol_referencer::staff_space (rest); | 1234 Real staff_space = Staff_symbol_referencer::staff_space (rest); |
1235 | 1235 |
1236 scale_drul (&pos, staff_space); | 1236 scale_drul (&pos, staff_space); |
1237 | 1237 |
1238 Real dy = pos[RIGHT] - pos[LEFT]; | 1238 Real dy = pos[RIGHT] - pos[LEFT]; |
1239 | 1239 |
1240 extract_grob_set (beam, "stems", stems); | 1240 extract_grob_set (beam, "stems", stems); |
1241 Grob *common = common_refpoint_of_array (stems, beam, X_AXIS); | 1241 Grob *common = common_refpoint_of_array (stems, beam, X_AXIS); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 "least-squares-dy " | 1488 "least-squares-dy " |
1489 "neutral-direction " | 1489 "neutral-direction " |
1490 "normal-stems " | 1490 "normal-stems " |
1491 "positions " | 1491 "positions " |
1492 "quantized-positions " | 1492 "quantized-positions " |
1493 "shorten " | 1493 "shorten " |
1494 "skip-quanting " | 1494 "skip-quanting " |
1495 "stems " | 1495 "stems " |
1496 "X-positions " | 1496 "X-positions " |
1497 ); | 1497 ); |
LEFT | RIGHT |