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) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 Jan Nieuwenhuizen <janneke@gnu.org> | 5 Jan Nieuwenhuizen <janneke@gnu.org> |
6 | 6 |
7 TODO: This is way too hairy | 7 TODO: This is way too hairy |
8 | 8 |
9 TODO: fix naming. | 9 TODO: fix naming. |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include <cmath> // rint | 30 #include <cmath> // rint |
31 using namespace std; | 31 using namespace std; |
32 | 32 |
33 #include "beam.hh" | 33 #include "beam.hh" |
34 #include "directional-element-interface.hh" | 34 #include "directional-element-interface.hh" |
35 #include "dot-column.hh" | 35 #include "dot-column.hh" |
36 #include "font-interface.hh" | 36 #include "font-interface.hh" |
37 #include "international.hh" | 37 #include "international.hh" |
38 #include "lookup.hh" | 38 #include "lookup.hh" |
39 #include "misc.hh" | 39 #include "misc.hh" |
| 40 #include "note-column.hh" |
40 #include "note-head.hh" | 41 #include "note-head.hh" |
41 #include "output-def.hh" | 42 #include "output-def.hh" |
42 #include "paper-column.hh" | 43 #include "paper-column.hh" |
43 #include "pointer-group-interface.hh" | 44 #include "pointer-group-interface.hh" |
44 #include "rest.hh" | 45 #include "rest.hh" |
45 #include "rhythmic-head.hh" | 46 #include "rhythmic-head.hh" |
| 47 #include "script-interface.hh" |
46 #include "side-position-interface.hh" | 48 #include "side-position-interface.hh" |
| 49 #include "simple-closure.hh" |
47 #include "staff-symbol-referencer.hh" | 50 #include "staff-symbol-referencer.hh" |
48 #include "stem-tremolo.hh" | 51 #include "stem-tremolo.hh" |
49 #include "warn.hh" | 52 #include "warn.hh" |
50 | 53 |
51 void | 54 void |
52 Stem::set_beaming (Grob *me, int beam_count, Direction d) | 55 Stem::set_beaming (Grob *me, int beam_count, Direction d) |
53 { | 56 { |
54 SCM pair = me->get_property ("beaming"); | 57 SCM pair = me->get_property ("beaming"); |
55 | 58 |
56 if (!scm_is_pair (pair)) | 59 if (!scm_is_pair (pair)) |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 243 |
241 MAKE_SCHEME_CALLBACK (Stem, pure_height, 3) | 244 MAKE_SCHEME_CALLBACK (Stem, pure_height, 3) |
242 SCM | 245 SCM |
243 Stem::pure_height (SCM smob, | 246 Stem::pure_height (SCM smob, |
244 SCM /* start */, | 247 SCM /* start */, |
245 SCM /* end */) | 248 SCM /* end */) |
246 { | 249 { |
247 Grob *me = unsmob_grob (smob); | 250 Grob *me = unsmob_grob (smob); |
248 Interval iv; | 251 Interval iv; |
249 | 252 |
250 if (!is_normal_stem (me) || to_boolean (me->get_property ("glissando-stem"))) | 253 if (!is_normal_stem (me)) |
251 return ly_interval2scm (iv); | 254 return ly_interval2scm (iv); |
252 | 255 |
253 Real ss = Staff_symbol_referencer::staff_space (me); | 256 Real ss = Staff_symbol_referencer::staff_space (me); |
254 Real rad = Staff_symbol_referencer::staff_radius (me); | 257 Real rad = Staff_symbol_referencer::staff_radius (me); |
255 | 258 |
256 if (!to_boolean (me->get_property ("cross-staff"))) | 259 if (!to_boolean (me->get_property ("cross-staff"))) |
257 { | 260 { |
258 Real len_in_halfspaces; | 261 Real len_in_halfspaces; |
259 SCM user_set_len_scm = me->get_property_data ("length"); | 262 SCM user_set_len_scm = me->get_property_data ("length"); |
260 if (scm_is_number (user_set_len_scm)) | 263 if (scm_is_number (user_set_len_scm)) |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 } | 416 } |
414 | 417 |
415 MAKE_SCHEME_CALLBACK (Stem, calc_positioning_done, 1); | 418 MAKE_SCHEME_CALLBACK (Stem, calc_positioning_done, 1); |
416 SCM | 419 SCM |
417 Stem::calc_positioning_done (SCM smob) | 420 Stem::calc_positioning_done (SCM smob) |
418 { | 421 { |
419 Grob *me = unsmob_grob (smob);·· | 422 Grob *me = unsmob_grob (smob);·· |
420 if (!head_count (me)) | 423 if (!head_count (me)) |
421 return SCM_BOOL_T; | 424 return SCM_BOOL_T; |
422 | 425 |
423 if (to_boolean (me->get_property ("glissando-stem"))) | |
424 return SCM_BOOL_T; | |
425 | |
426 me->set_property ("positioning-done", SCM_BOOL_T); | 426 me->set_property ("positioning-done", SCM_BOOL_T); |
427 ·· | 427 ·· |
428 extract_grob_set (me, "note-heads", ro_heads); | 428 extract_grob_set (me, "note-heads", ro_heads); |
429 vector<Grob*> heads (ro_heads); | 429 vector<Grob*> heads (ro_heads); |
430 vector_sort (heads, position_less); | 430 vector_sort (heads, position_less); |
431 Direction dir = get_grob_direction (me); | 431 Direction dir = get_grob_direction (me); |
432 | 432 |
433 if (dir < 0) | 433 if (dir < 0) |
434 reverse (heads); | 434 reverse (heads); |
435 | 435 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 | 520 |
521 return SCM_BOOL_T; | 521 return SCM_BOOL_T; |
522 } | 522 } |
523 | 523 |
524 MAKE_SCHEME_CALLBACK (Stem, calc_direction, 1); | 524 MAKE_SCHEME_CALLBACK (Stem, calc_direction, 1); |
525 SCM | 525 SCM |
526 Stem::calc_direction (SCM smob) | 526 Stem::calc_direction (SCM smob) |
527 { | 527 { |
528 Grob *me = unsmob_grob (smob); | 528 Grob *me = unsmob_grob (smob); |
529 Direction dir = CENTER; | 529 Direction dir = CENTER; |
530 if (to_boolean (me->get_property ("glissando-stem"))) | 530 |
531 { | |
532 Grob *glissando_column = unsmob_grob (me->get_object ("glissando-column"))
; | |
533 if (glissando_column) | |
534 if (glissando_column->get_property_data ("after-line-breaking") != SCM_B
OOL_T) | |
535 { | |
536 me->programming_error ("Glissando stem direction requested before li
ne breaking."); | |
537 return scm_from_int (dir); | |
538 } | |
539 } | |
540 if (Grob *beam = unsmob_grob (me->get_object ("beam"))) | 531 if (Grob *beam = unsmob_grob (me->get_object ("beam"))) |
541 { | 532 { |
542 SCM ignore_me = beam->get_property ("direction"); | 533 SCM ignore_me = beam->get_property ("direction"); |
543 (void) ignore_me; | 534 (void) ignore_me; |
544 dir = get_grob_direction (me); | 535 dir = get_grob_direction (me); |
545 } | 536 } |
546 else | 537 else |
547 { | 538 { |
548 SCM dd = me->get_property ("default-direction"); | 539 SCM dd = me->get_property ("default-direction"); |
549 dir = to_dir (dd); | 540 dir = to_dir (dd); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 return ly_interval2scm (r); | 730 return ly_interval2scm (r); |
740 } | 731 } |
741 | 732 |
742 Real | 733 Real |
743 Stem::thickness (Grob *me) | 734 Stem::thickness (Grob *me) |
744 { | 735 { |
745 return scm_to_double (me->get_property ("thickness")) | 736 return scm_to_double (me->get_property ("thickness")) |
746 * Staff_symbol_referencer::line_thickness (me); | 737 * Staff_symbol_referencer::line_thickness (me); |
747 } | 738 } |
748 | 739 |
| 740 MAKE_SCHEME_CALLBACK (Stem, calc_stem_begin_position, 1); |
| 741 SCM |
| 742 Stem::calc_stem_begin_position (SCM smob) |
| 743 { |
| 744 Grob *me = unsmob_grob (smob); |
| 745 Direction d = get_grob_direction (me); |
| 746 Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; |
| 747 Grob *lh |
| 748 = to_boolean (me->get_property ("avoid-note-head")) |
| 749 ? last_head (me) |
| 750 : first_head (me); |
| 751 |
| 752 Real pos = Staff_symbol_referencer::get_position (lh); |
| 753 |
| 754 if (Grob *head = support_head (me)) |
| 755 { |
| 756 Interval head_height = head->extent (head, Y_AXIS); |
| 757 Real y_attach = Note_head::stem_attachment_coordinate (head, Y_AXIS); |
| 758 |
| 759 y_attach = head_height.linear_combination (y_attach); |
| 760 pos += d * y_attach / half_space; |
| 761 } |
| 762 |
| 763 return scm_from_double (pos); |
| 764 } |
| 765 |
749 MAKE_SCHEME_CALLBACK (Stem, print, 1); | 766 MAKE_SCHEME_CALLBACK (Stem, print, 1); |
750 SCM | 767 SCM |
751 Stem::print (SCM smob) | 768 Stem::print (SCM smob) |
752 { | 769 { |
753 Grob *me = unsmob_grob (smob); | 770 Grob *me = unsmob_grob (smob); |
754 Grob *beam = get_beam (me); | 771 Grob *beam = get_beam (me); |
755 | 772 |
756 Stencil mol; | 773 Stencil mol; |
757 Direction d = get_grob_direction (me); | 774 Direction d = get_grob_direction (me); |
758 | 775 |
(...skipping 18 matching lines...) Expand all Loading... |
777 return SCM_EOL; | 794 return SCM_EOL; |
778 | 795 |
779 if (is_invisible (me)) | 796 if (is_invisible (me)) |
780 return SCM_EOL; | 797 return SCM_EOL; |
781 | 798 |
782 Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0); | 799 Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0); |
783 Real y1 = y2; | 800 Real y1 = y2; |
784 Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; | 801 Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; |
785 | 802 |
786 if (lh) | 803 if (lh) |
787 y2 = Staff_symbol_referencer::get_position (lh); | 804 y2 = robust_scm2double (me->get_property ("stem-begin-position"), 0.0); |
788 else if (stemlet) | 805 else if (stemlet) |
789 { | 806 { |
790 Real beam_translation = Beam::get_beam_translation (beam); | 807 Real beam_translation = Beam::get_beam_translation (beam); |
791 Real beam_thickness = Beam::get_beam_thickness (beam); | 808 Real beam_thickness = Beam::get_beam_thickness (beam); |
792 int beam_count = beam_multiplicity (me).length () + 1; | 809 int beam_count = beam_multiplicity (me).length () + 1; |
793 | 810 |
794 y2 -= d | 811 y2 -= d |
795 * (0.5 * beam_thickness | 812 * (0.5 * beam_thickness |
796 + beam_translation * max (0, (beam_count - 1)) | 813 + beam_translation * max (0, (beam_count - 1)) |
797 + stemlet_length) / half_space; | 814 + stemlet_length) / half_space; |
798 } | 815 } |
799 | 816 |
800 Interval stem_y (min (y1, y2), max (y2, y1)); | 817 Interval stem_y (min (y1, y2), max (y2, y1)); |
801 | |
802 if (Grob *head = support_head (me)) | |
803 { | |
804 /* | |
805 must not take ledgers into account. | |
806 */ | |
807 Interval head_height = head->extent (head, Y_AXIS); | |
808 Real y_attach = Note_head::stem_attachment_coordinate (head, Y_AXIS); | |
809 | |
810 y_attach = head_height.linear_combination (y_attach); | |
811 stem_y[Direction (-d)] += d * y_attach / half_space; | |
812 } | |
813 | 818 |
814 // URG | 819 // URG |
815 Real stem_width = thickness (me); | 820 Real stem_width = thickness (me); |
816 Real blot | 821 Real blot |
817 = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); | 822 = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); |
818 | 823 |
819 Box b = Box (Interval (-stem_width / 2, stem_width / 2), | 824 Box b = Box (Interval (-stem_width / 2, stem_width / 2), |
820 Interval (stem_y[DOWN] * half_space, stem_y[UP] * half_space)); | 825 Interval (stem_y[DOWN] * half_space, stem_y[UP] * half_space)); |
821 | 826 |
822 Stencil ss = Lookup::round_filled_box (b, blot); | 827 Stencil ss = Lookup::round_filled_box (b, blot); |
(...skipping 24 matching lines...) Expand all Loading... |
847 | 852 |
848 | 853 |
849 /* | 854 /* |
850 move the stem to right of the notehead if it is up. | 855 move the stem to right of the notehead if it is up. |
851 */ | 856 */ |
852 MAKE_SCHEME_CALLBACK (Stem, offset_callback, 1); | 857 MAKE_SCHEME_CALLBACK (Stem, offset_callback, 1); |
853 SCM | 858 SCM |
854 Stem::offset_callback (SCM smob) | 859 Stem::offset_callback (SCM smob) |
855 { | 860 { |
856 Grob *me = unsmob_grob (smob); | 861 Grob *me = unsmob_grob (smob); |
857 if (to_boolean (me->get_property ("glissando-stem"))) | |
858 return scm_from_double (0.0); | |
859 | 862 |
860 extract_grob_set (me, "rests", rests); | 863 extract_grob_set (me, "rests", rests); |
861 if (rests.size ()) | 864 if (rests.size ()) |
862 { | 865 { |
863 Grob *rest = rests.back (); | 866 Grob *rest = rests.back (); |
864 Real r = rest->extent (rest, X_AXIS).center (); | 867 Real r = rest->extent (rest, X_AXIS).center (); |
865 return scm_from_double (r); | 868 return scm_from_double (r); |
866 } | 869 } |
867 | 870 |
868 ·· | 871 ·· |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 return beam && Beam::is_cross_staff (beam); | 1073 return beam && Beam::is_cross_staff (beam); |
1071 } | 1074 } |
1072 | 1075 |
1073 MAKE_SCHEME_CALLBACK (Stem, calc_cross_staff, 1) | 1076 MAKE_SCHEME_CALLBACK (Stem, calc_cross_staff, 1) |
1074 SCM | 1077 SCM |
1075 Stem::calc_cross_staff (SCM smob) | 1078 Stem::calc_cross_staff (SCM smob) |
1076 { | 1079 { |
1077 return scm_from_bool (is_cross_staff (unsmob_grob (smob))); | 1080 return scm_from_bool (is_cross_staff (unsmob_grob (smob))); |
1078 } | 1081 } |
1079 | 1082 |
1080 MAKE_SCHEME_CALLBACK (Stem, after_line_breaking, 1); | 1083 MAKE_SCHEME_CALLBACK (Glissando_stem, after_line_breaking, 1); |
1081 SCM | 1084 SCM |
1082 Stem::after_line_breaking (SCM smob) | 1085 Glissando_stem::after_line_breaking (SCM smob) |
1083 { | 1086 {message ("ALB"); |
1084 Grob *me = unsmob_grob (smob); | 1087 Grob *me = unsmob_grob (smob); |
1085 | |
1086 if (!to_boolean (me->get_property ("glissando-stem"))) | |
1087 return SCM_BOOL_T; | |
1088 | 1088 |
1089 extract_grob_set (me, "glissandi", glissandi); | 1089 extract_grob_set (me, "glissandi", glissandi); |
1090 | 1090 |
1091 if (!glissandi.size ()) | 1091 if (!glissandi.size ()) |
1092 { | 1092 { |
1093 me->programming_error ("This glissando stem does not have any glissandi to
which it can attach. Killing stem."); | 1093 me->programming_error ("This glissando stem does not have any glissandi to
which it can attach. Killing stem."); |
1094 me->suicide (); | 1094 me->suicide (); |
1095 return SCM_BOOL_F; | 1095 return SCM_BOOL_F; |
1096 } | 1096 } |
1097 | 1097 |
1098 // first, every note column must have two and only two notes. | 1098 // first, every note column must have two and only two notes. |
1099 extract_grob_set (me, "note-heads", note_heads); | 1099 extract_grob_set (me, "note-heads", note_heads); |
1100 if (note_heads.size () != 2) | 1100 if (note_heads.size () != 2) |
1101 { | 1101 { |
1102 programming_error ("Glissandi stem must have two and only two noteheads.")
; | 1102 programming_error ("Glissandi stem does not have exactly two noteheads."); |
1103 return SCM_BOOL_F; | 1103 return SCM_BOOL_F; |
1104 } | 1104 } |
1105 | 1105 |
1106 // now, position the note heads | 1106 // now, position the note heads |
1107 | 1107 |
1108 vector<Spanner *> good_glissandi; | |
1109 Grob *common[NO_AXES]; | 1108 Grob *common[NO_AXES]; |
1110 | 1109 |
1111 Drul_array<Grob *> extremals = Stem::extremal_heads (me); | 1110 Drul_array<Grob *> extremals = Stem::extremal_heads (me); |
1112 //MAKE THIS ACTUALLY EFFECTIVE !!! | 1111 |
1113 // find all of the relevant glissandi for this staff | 1112 for (Axis a = X_AXIS; a < NO_AXES; incr (a)) |
1114 for (vsize i = 0; i < glissandi.size (); i++) | 1113 { |
1115 { | 1114 common[a] = (dynamic_cast<Spanner *> (glissandi[0]))->get_bound (LEFT)->co
mmon_refpoint ((dynamic_cast<Spanner *> (glissandi[0]))->get_bound (RIGHT), (Axi
s) a); |
1116 Spanner *gls = dynamic_cast<Spanner *> (glissandi[i]); | 1115 common[a] = glissandi[0]->common_refpoint (common[a], a); |
1117 | 1116 } |
1118 Spanner *orig = gls->is_broken () ? gls : dynamic_cast<Spanner *> (gls->or
iginal ()); | |
1119 orig = orig ? orig : dynamic_cast<Spanner *> (glissandi[i]); | |
1120 | |
1121 if (orig->broken_intos_.size ()) | |
1122 for (vsize j = 0; j < orig->broken_intos_.size (); j++) | |
1123 { | |
1124 Grob *commonx = me->common_refpoint (orig->broken_intos_[j], X_AXIS)
; | |
1125 if (commonx) | |
1126 { | |
1127 good_glissandi.push_back (orig->broken_intos_[j]); | |
1128 break; | |
1129 } | |
1130 } | |
1131 else | |
1132 good_glissandi.push_back (orig); | |
1133 | |
1134 if (!good_glissandi.size ()) | |
1135 { | |
1136 me->programming_error ("This glissando stem does not have any glissand
i to which it can attach. Killing stem."); | |
1137 me->suicide (); | |
1138 return SCM_BOOL_F; | |
1139 } | |
1140 | |
1141 for (Axis a = X_AXIS; a < NO_AXES; incr (a)) | |
1142 { | |
1143 common[a] = good_glissandi[0]->get_bound (LEFT)->common_refpoint (good
_glissandi[0]->get_bound (RIGHT), (Axis) a); | |
1144 common[a] = good_glissandi[0]->common_refpoint (common[a], a); | |
1145 } | |
1146 } | |
1147 | |
1148 Real stem_pos = me->relative_coordinate (common[X_AXIS], X_AXIS); | 1117 Real stem_pos = me->relative_coordinate (common[X_AXIS], X_AXIS); |
1149 Interval ypos; | 1118 Interval ypos; |
1150 ypos.set_empty (); | 1119 ypos.set_empty (); |
1151 | 1120 |
1152 for (vsize i = 0; i < good_glissandi.size (); i++) | 1121 for (vsize i = 0; i < glissandi.size (); i++) |
1153 { | 1122 { |
1154 Spanner *gls = dynamic_cast<Spanner *> (glissandi[i]); | 1123 Spanner *gls = dynamic_cast<Spanner *> (glissandi[i]); |
1155 | 1124 |
1156 // code dup from line spanner :( | 1125 // code dup from line spanner :( |
1157 Drul_array<SCM> bounds (gls->get_property ("left-bound-info"), | 1126 Drul_array<SCM> bounds (gls->get_property ("left-bound-info"), |
1158 gls->get_property ("right-bound-info")); | 1127 gls->get_property ("right-bound-info")); |
1159 | 1128 |
1160 Drul_array<Offset> span_points; | 1129 Drul_array<Offset> span_points; |
1161 | 1130 |
1162 Direction d = LEFT; | 1131 Direction d = LEFT; |
1163 do | 1132 do |
1164 { | 1133 { |
1165 Offset z (robust_scm2double (ly_assoc_get (ly_symbol2scm ("X"), | 1134 Offset z (robust_scm2double (ly_assoc_get (ly_symbol2scm ("X"), |
1166 bounds[d], SCM_BOOL_F), 0.0
), | 1135 bounds[d], SCM_BOOL_F), 0.0
), |
1167 robust_scm2double (ly_assoc_get (ly_symbol2scm ("Y"), | 1136 robust_scm2double (ly_assoc_get (ly_symbol2scm ("Y"), |
1168 bounds[d], SCM_BOOL_F), 0.0
)); | 1137 bounds[d], SCM_BOOL_F), 0.0
)); |
1169 | 1138 |
1170 span_points[d] = z; | 1139 span_points[d] = z; |
1171 } | 1140 } |
1172 while (flip (&d) != LEFT); | 1141 while (flip (&d) != LEFT); |
1173 | 1142 |
1174 Interval normalized_endpoints = robust_scm2interval (gls->get_property ("n
ormalized-endpoints"), Interval (0, 1)); | 1143 Interval normalized_endpoints = robust_scm2interval (gls->get_property ("n
ormalized-endpoints"), Interval (0, 1)); |
1175 Real y_length = span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS]; | 1144 Real y_length = span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS]; |
1176 | 1145 |
1177 span_points[LEFT][Y_AXIS] += normalized_endpoints[LEFT] * y_length; | 1146 span_points[LEFT][Y_AXIS] += normalized_endpoints[LEFT] * y_length; |
1178 span_points[RIGHT][Y_AXIS] -= (1 - normalized_endpoints[RIGHT]) * y_length
; | 1147 span_points[RIGHT][Y_AXIS] -= (1 - normalized_endpoints[RIGHT]) * y_length
; |
1179 | |
1180 Real slope = (span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS]) / (s
pan_points[RIGHT][X_AXIS] - span_points[LEFT][X_AXIS]); | |
1181 Real offset = span_points[RIGHT][Y_AXIS] - (span_points[RIGHT][X_AXIS] * s
lope); | |
1182 | |
1183 // end code dup :) | 1148 // end code dup :) |
| 1149 |
| 1150 SCM placement_function = gls->get_property_data ("stem-placement-function"
); |
| 1151 Real pos = 0.0; |
| 1152 |
| 1153 if (placement_function != SCM_EOL) |
| 1154 { |
| 1155 pos = robust_scm2double (scm_call_4 (placement_function, |
| 1156 scm_from_double (stem_pos), |
| 1157 ly_offset2scm (span_points[LEFT])
, |
| 1158 ly_offset2scm (span_points[RIGHT]
), |
| 1159 ly_interval2scm (normalized_endpo
ints)), |
| 1160 0.0); |
| 1161 } |
| 1162 else |
| 1163 { |
| 1164 Real slope = (span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS])
/ (span_points[RIGHT][X_AXIS] - span_points[LEFT][X_AXIS]); |
| 1165 Real offset = span_points[RIGHT][Y_AXIS] - (span_points[RIGHT][X_AXIS]
* slope); |
| 1166 pos = slope * stem_pos + offset; |
| 1167 } |
| 1168 |
1184 d = DOWN; | 1169 d = DOWN; |
1185 do | 1170 do |
1186 ypos[d] = minmax (d, ypos[d], slope * stem_pos + offset); | 1171 ypos[d] = minmax (d, ypos[d], pos); |
1187 while (flip (&d) != DOWN); | 1172 while (flip (&d) != DOWN); |
1188 } | 1173 } |
1189 | 1174 |
1190 // Note that staff symbol positions are in half space : must multiply by 0.5 | 1175 // Note that staff symbol positions are in half space : must multiply by 0.5 |
1191 Direction d = DOWN; | 1176 Direction d = DOWN; |
1192 do | 1177 do |
1193 extremals[d]->translate_axis (ypos[d] - (0.5 * Staff_symbol_referencer::get_
position (extremals[d])), Y_AXIS); | 1178 extremals[d]->translate_axis (ypos[d] - (0.5 * Staff_symbol_referencer::get_
position (extremals[d])), Y_AXIS); |
1194 while (flip (&d) != DOWN); | 1179 while (flip (&d) != DOWN); |
| 1180 |
| 1181 me->set_property ("direction", Stem::calc_direction_proc); |
| 1182 me->set_property ("flag", Stem::calc_flag_proc); |
| 1183 ·· |
| 1184 if (Grob *beam = Stem::get_beam (me)) |
| 1185 beam->set_property ("direction", Beam::calc_direction_proc); |
| 1186 |
| 1187 if (Note_column::has_interface (me->get_parent (X_AXIS))) |
| 1188 { |
| 1189 extract_grob_set (me->get_parent (X_AXIS), "scripts", elts); |
| 1190 for (vsize i = 0; i < elts.size(); i++) |
| 1191 elts[i]->set_property ("direction", Script_interface::calc_opposite_dire
ction_proc); |
| 1192 } |
| 1193 |
| 1194 if (Grob *tremolo = unsmob_grob (me->get_object ("tremolo-flag"))) |
| 1195 { |
| 1196 tremolo->set_property ("style", Stem_tremolo::calc_style_proc); |
| 1197 tremolo->set_property ("beam-width", Stem_tremolo::calc_width_proc); |
| 1198 } |
1195 | 1199 |
1196 return SCM_BOOL_T; | 1200 return SCM_BOOL_T; |
1197 } | 1201 } |
1198 | 1202 |
1199 /* FIXME: Too many properties */ | 1203 /* FIXME: Too many properties */ |
1200 ADD_INTERFACE (Stem, | 1204 ADD_INTERFACE (Stem, |
1201 "The stem represents the graphical stem. In addition, it" | 1205 "The stem represents the graphical stem. In addition, it" |
1202 " internally connects note heads, beams, and tremolos. Rests" | 1206 " internally connects note heads, beams, and tremolos. Rests" |
1203 " and whole notes have invisible stems.\n" | 1207 " and whole notes have invisible stems.\n" |
1204 "\n" | 1208 "\n" |
(...skipping 24 matching lines...) Expand all Loading... |
1229 "beaming " | 1233 "beaming " |
1230 "beamlet-default-length " | 1234 "beamlet-default-length " |
1231 "beamlet-max-length-proportion " | 1235 "beamlet-max-length-proportion " |
1232 "default-direction " | 1236 "default-direction " |
1233 "details " | 1237 "details " |
1234 "direction " | 1238 "direction " |
1235 "duration-log " | 1239 "duration-log " |
1236 "flag " | 1240 "flag " |
1237 "flag-style " | 1241 "flag-style " |
1238 "french-beaming " | 1242 "french-beaming " |
1239 » "glissando-stem " | 1243 » "length " |
| 1244 » "length-fraction " |
| 1245 » "max-beam-connect " |
| 1246 » "neutral-direction " |
| 1247 » "no-stem-extend " |
| 1248 » "note-heads " |
| 1249 » "positioning-done " |
| 1250 » "rests " |
| 1251 » "stem-begin-position " |
| 1252 » "stem-end-position " |
| 1253 » "stem-placement-function " |
| 1254 » "stem-info " |
| 1255 » "stemlet-length " |
| 1256 » "stroke-style " |
| 1257 » "thickness " |
| 1258 » "tremolo-flag " |
| 1259 » ); |
| 1260 |
| 1261 /* Fix me. Code dup. */ |
| 1262 ADD_INTERFACE (Glissando_stem, |
| 1263 » "Like stems, but for glissandi", |
| 1264 |
| 1265 » /* properties */ |
| 1266 » "avoid-note-head " |
| 1267 » "beam " |
| 1268 » "beaming " |
| 1269 » "beamlet-default-length " |
| 1270 » "beamlet-max-length-proportion " |
| 1271 » "default-direction " |
| 1272 » "details " |
| 1273 » "direction " |
| 1274 » "duration-log " |
| 1275 » "flag " |
| 1276 » "flag-style " |
| 1277 » "french-beaming " |
| 1278 » "glissandi " |
1240 "length " | 1279 "length " |
1241 "length-fraction " | 1280 "length-fraction " |
1242 "max-beam-connect " | 1281 "max-beam-connect " |
1243 "neutral-direction " | 1282 "neutral-direction " |
1244 "no-stem-extend " | 1283 "no-stem-extend " |
1245 "note-heads " | 1284 "note-heads " |
1246 "positioning-done " | 1285 "positioning-done " |
1247 "rests " | 1286 "rests " |
1248 "stem-end-position " | 1287 "stem-end-position " |
| 1288 "stem-placement-function " |
1249 "stem-info " | 1289 "stem-info " |
1250 "stemlet-length " | 1290 "stemlet-length " |
1251 "stroke-style " | 1291 "stroke-style " |
1252 "thickness " | 1292 "thickness " |
1253 "tremolo-flag " | 1293 "tremolo-flag " |
1254 ); | 1294 ); |
1255 | 1295 |
1256 /****************************************************************/ | 1296 /****************************************************************/ |
1257 | 1297 |
1258 Stem_info::Stem_info () | 1298 Stem_info::Stem_info () |
1259 { | 1299 { |
1260 ideal_y_ = shortest_y_ = 0; | 1300 ideal_y_ = shortest_y_ = 0; |
1261 dir_ = CENTER; | 1301 dir_ = CENTER; |
1262 } | 1302 } |
1263 | 1303 |
1264 void | 1304 void |
1265 Stem_info::scale (Real x) | 1305 Stem_info::scale (Real x) |
1266 { | 1306 { |
1267 ideal_y_ *= x; | 1307 ideal_y_ *= x; |
1268 shortest_y_ *= x; | 1308 shortest_y_ *= x; |
1269 } | 1309 } |
LEFT | RIGHT |