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--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_slope, 1) | 32 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_slope, 1) |
33 SCM | 33 SCM |
34 Stem_tremolo::calc_slope (SCM smob) | 34 Stem_tremolo::calc_slope (SCM smob) |
35 { | 35 { |
36 Grob *me = unsmob_grob (smob); | 36 Grob *me = unsmob_grob (smob); |
37 Grob *stem = unsmob_grob (me->get_object ("stem")); | 37 Grob *stem = unsmob_grob (me->get_object ("stem")); |
38 Spanner *beam = Stem::get_beam (stem); | 38 Spanner *beam = Stem::get_beam (stem); |
39 | 39 |
40 SCM style = me->get_property ("style"); | 40 SCM style = me->get_property ("style"); |
41 if (!scm_is_symbol (style)) | |
42 style = ly_symbol2scm ("default"); | |
43 | 41 |
44 if (beam && style != ly_symbol2scm ("constant")) | 42 if (beam && style != ly_symbol2scm ("constant")) |
45 { | 43 { |
46 Real dy = 0; | 44 Real dy = 0; |
47 SCM s = beam->get_property ("quantized-positions"); | 45 SCM s = beam->get_property ("quantized-positions"); |
48 if (is_number_pair (s)) | 46 if (is_number_pair (s)) |
49 » dy = - scm_to_double (scm_car (s)) + scm_to_double (scm_cdr (s)); | 47 dy = - scm_to_double (scm_car (s)) + scm_to_double (scm_cdr (s)); |
50 | 48 |
51 Grob *s2 = Beam::last_normal_stem (beam); | 49 Grob *s2 = Beam::last_normal_stem (beam); |
52 Grob *s1 = Beam::first_normal_stem (beam); | 50 Grob *s1 = Beam::first_normal_stem (beam); |
53 | 51 |
54 Grob *common = s1->common_refpoint (s2, X_AXIS); | 52 Grob *common = s1->common_refpoint (s2, X_AXIS); |
55 Real dx = s2->relative_coordinate (common, X_AXIS) - | 53 Real dx = s2->relative_coordinate (common, X_AXIS) |
56 » s1->relative_coordinate (common, X_AXIS); | 54 - s1->relative_coordinate (common, X_AXIS); |
57 | 55 |
58 return scm_from_double (dx ? dy / dx : 0); | 56 return scm_from_double (dx ? dy / dx : 0); |
59 } | 57 } |
60 else | 58 else |
61 /* down stems with flags should have more sloped trems (helps avoid | 59 /* down stems with flags should have more sloped trems (helps avoid |
62 flag/stem collisions without making the stem very long) */ | 60 flag/stem collisions without making the stem very long) */ |
63 return scm_from_double ( | 61 return scm_from_double ((Stem::duration_log (stem) >= 3 |
64 (Stem::duration_log (stem) >= 3 && get_grob_direction (stem) == DOWN) ? | 62 && get_grob_direction (stem) == DOWN && !beam) |
65 0.40 : 0.25); | 63 ? 0.40 : 0.25); |
66 } | 64 } |
67 | 65 |
68 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_width, 1) | 66 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_width, 1) |
69 SCM | 67 SCM |
70 Stem_tremolo::calc_width (SCM smob) | 68 Stem_tremolo::calc_width (SCM smob) |
71 { | 69 { |
72 Grob *me = unsmob_grob (smob); | 70 Grob *me = unsmob_grob (smob); |
73 Grob *stem = unsmob_grob (me->get_object ("stem")); | 71 Grob *stem = unsmob_grob (me->get_object ("stem")); |
74 Direction stemdir = get_grob_direction (stem); | 72 Direction stemdir = get_grob_direction (stem); |
75 bool beam = Stem::get_beam (stem); | 73 bool beam = Stem::get_beam (stem); |
76 bool flag = Stem::duration_log (stem) >= 3 && !beam; | 74 bool flag = Stem::duration_log (stem) >= 3 && !beam; |
77 | 75 |
78 /* beamed stems and up-stems with flags have shorter tremolos */ | 76 /* beamed stems and up-stems with flags have shorter tremolos */ |
79 return scm_from_double (((stemdir == UP && flag) || beam)? 1.0 : 1.5); | 77 return scm_from_double (((stemdir == UP && flag) || beam) ? 1.0 : 1.5); |
80 } | 78 } |
81 | 79 |
82 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_shape, 1) | 80 MAKE_SCHEME_CALLBACK (Stem_tremolo, calc_shape, 1) |
83 SCM | 81 SCM |
84 Stem_tremolo::calc_shape (SCM smob) | 82 Stem_tremolo::calc_shape (SCM smob) |
85 { | 83 { |
86 Grob *me = unsmob_grob (smob); | 84 Grob *me = unsmob_grob (smob); |
87 Grob *stem = unsmob_grob (me->get_object ("stem")); | 85 Grob *stem = unsmob_grob (me->get_object ("stem")); |
88 Direction stemdir = get_grob_direction (stem); | 86 Direction stemdir = get_grob_direction (stem); |
89 bool beam = Stem::get_beam (stem); | 87 bool beam = Stem::get_beam (stem); |
90 bool flag = Stem::duration_log (stem) >= 3 && !beam; | 88 bool flag = Stem::duration_log (stem) >= 3 && !beam; |
91 SCM style = me->get_property ("style"); | 89 SCM style = me->get_property ("style"); |
92 if (!scm_is_symbol (style)) | 90 |
93 style = ly_symbol2scm ("default"); | 91 return ly_symbol2scm (style != ly_symbol2scm ("constant") |
94 | 92 && ((stemdir == UP && flag) || beam) |
95 if (style == ly_symbol2scm ("default")) | 93 ? "rectangle" : "beam-like"); |
96 return ly_symbol2scm (((stemdir == UP && flag) || beam) ? "rectangle" : "def
ault"); | |
97 else | |
98 return ly_symbol2scm ("default"); | |
99 } | 94 } |
100 | 95 |
101 Real | 96 Real |
102 Stem_tremolo::get_beam_translation (Grob *me) | 97 Stem_tremolo::get_beam_translation (Grob *me) |
103 { | 98 { |
104 Grob *stem = unsmob_grob (me->get_object ("stem")); | 99 Grob *stem = unsmob_grob (me->get_object ("stem")); |
105 Spanner *beam = Stem::get_beam (stem); | 100 Spanner *beam = Stem::get_beam (stem); |
106 | 101 |
107 return (beam && beam->is_live ()) | 102 return (beam && beam->is_live ()) |
108 ? Beam::get_beam_translation (beam) | 103 ? Beam::get_beam_translation (beam) |
109 : (Staff_symbol_referencer::staff_space (me) | 104 : (Staff_symbol_referencer::staff_space (me) |
110 * robust_scm2double (me->get_property ("length-fraction"), 1.0) * 0.81); | 105 * robust_scm2double (me->get_property ("length-fraction"), 1.0) * 0.
81); |
111 } | 106 } |
112 | 107 |
113 Stencil | 108 Stencil |
114 Stem_tremolo::raw_stencil (Grob *me, Real slope, Direction stemdir) | 109 Stem_tremolo::raw_stencil (Grob *me, Real slope, Direction stemdir) |
115 { | 110 { |
116 Real ss = Staff_symbol_referencer::staff_space (me); | 111 Real ss = Staff_symbol_referencer::staff_space (me); |
117 Real thick = robust_scm2double (me->get_property ("beam-thickness"), 1); | 112 Real thick = robust_scm2double (me->get_property ("beam-thickness"), 1); |
118 Real width = robust_scm2double (me->get_property ("beam-width"), 1); | 113 Real width = robust_scm2double (me->get_property ("beam-width"), 1); |
119 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); | 114 Real blot = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); |
120 | 115 |
121 SCM shape = me->get_property ("shape"); | 116 SCM shape = me->get_property ("shape"); |
122 if (!scm_is_symbol (shape)) | 117 if (!scm_is_symbol (shape)) |
123 shape = ly_symbol2scm ("default"); | 118 shape = ly_symbol2scm ("beam-like"); |
124 | 119 |
125 width *= ss; | 120 width *= ss; |
126 thick *= ss; | 121 thick *= ss; |
127 | 122 |
128 Stencil a; | 123 Stencil a; |
129 if (shape == ly_symbol2scm ("rectangle")) | 124 if (shape == ly_symbol2scm ("rectangle")) |
130 a = Lookup::rotated_box (slope, width, thick, blot); | 125 a = Lookup::rotated_box (slope, width, thick, blot); |
131 else | 126 else |
132 a = Lookup::beam (slope, width, thick, blot); | 127 a = Lookup::beam (slope, width, thick, blot); |
133 | 128 |
(...skipping 14 matching lines...) Expand all Loading... |
148 Stencil mol; | 143 Stencil mol; |
149 for (int i = 0; i < tremolo_flags; i++) | 144 for (int i = 0; i < tremolo_flags; i++) |
150 { | 145 { |
151 Stencil b (a); | 146 Stencil b (a); |
152 b.translate_axis (beam_translation * i * stemdir * -1, Y_AXIS); | 147 b.translate_axis (beam_translation * i * stemdir * -1, Y_AXIS); |
153 mol.add_stencil (b); | 148 mol.add_stencil (b); |
154 } | 149 } |
155 return mol; | 150 return mol; |
156 } | 151 } |
157 | 152 |
158 | 153 MAKE_SCHEME_CALLBACK (Stem_tremolo, pure_height, 3); |
159 | 154 SCM |
160 MAKE_SCHEME_CALLBACK (Stem_tremolo, height, 1); | 155 Stem_tremolo::pure_height (SCM smob, SCM, SCM) |
161 SCM | |
162 Stem_tremolo::height (SCM smob) | |
163 { | |
164 Grob *me = unsmob_grob (smob); | |
165 | |
166 /* | |
167 Cannot use the real slope, since it looks at the Beam. | |
168 */ | |
169 Stencil s1 (translated_stencil (me, 0.35)); | |
170 | |
171 return ly_interval2scm (s1.extent (Y_AXIS)); | |
172 } | |
173 | |
174 MAKE_SCHEME_CALLBACK (Stem_tremolo, width, 1); | |
175 SCM | |
176 Stem_tremolo::width (SCM smob) | |
177 { | 156 { |
178 Grob *me = unsmob_grob (smob); | 157 Grob *me = unsmob_grob (smob); |
179 | 158 |
180 /* | 159 /* |
181 Cannot use the real slope, since it looks at the Beam. | 160 Cannot use the real slope, since it looks at the Beam. |
182 */ | 161 */ |
183 Stencil s1 (untranslated_stencil (me, 0.35)); | 162 Stencil s1 (untranslated_stencil (me, 0.35)); |
184 | 163 |
| 164 return ly_interval2scm (s1.extent (Y_AXIS)); |
| 165 } |
| 166 |
| 167 MAKE_SCHEME_CALLBACK (Stem_tremolo, width, 1); |
| 168 SCM |
| 169 Stem_tremolo::width (SCM smob) |
| 170 { |
| 171 Grob *me = unsmob_grob (smob); |
| 172 |
| 173 /* |
| 174 Cannot use the real slope, since it looks at the Beam. |
| 175 */ |
| 176 Stencil s1 (untranslated_stencil (me, 0.35)); |
| 177 |
185 return ly_interval2scm (s1.extent (X_AXIS)); | 178 return ly_interval2scm (s1.extent (X_AXIS)); |
186 } | 179 } |
187 | 180 |
188 Real | 181 Real |
189 Stem_tremolo::vertical_length (Grob *me) | 182 Stem_tremolo::vertical_length (Grob *me) |
190 { | 183 { |
191 return untranslated_stencil (me, 0.35).extent (Y_AXIS).length (); | 184 return untranslated_stencil (me, 0.35).extent (Y_AXIS).length (); |
192 } | 185 } |
193 | 186 |
194 Stencil | 187 Stencil |
195 Stem_tremolo::untranslated_stencil (Grob *me, Real slope) | 188 Stem_tremolo::untranslated_stencil (Grob *me, Real slope) |
196 { | 189 { |
197 Grob *stem = unsmob_grob (me->get_object ("stem")); | 190 Grob *stem = unsmob_grob (me->get_object ("stem")); |
198 if (!stem) | 191 if (!stem) |
199 { | 192 { |
200 programming_error ("no stem for stem-tremolo"); | 193 programming_error ("no stem for stem-tremolo"); |
201 return Stencil (); | 194 return Stencil (); |
202 } | 195 } |
203 | 196 |
204 Direction stemdir = get_grob_direction (stem); | 197 Direction stemdir = get_grob_direction (stem); |
205 if (!stemdir) | 198 if (!stemdir) |
206 stemdir = UP; | 199 stemdir = UP; |
207 | 200 |
208 bool whole_note = Stem::duration_log (stem) <= 0; | 201 bool whole_note = Stem::duration_log (stem) <= 0; |
209 | 202 |
210 /* for a whole note, we position relative to the notehead, so we want the | 203 /* for a whole note, we position relative to the notehead, so we want the |
211 stencil aligned on the flag closest to the head */ | 204 stencil aligned on the flag closest to the head */ |
212 Direction stencil_dir = whole_note ? -stemdir : stemdir; | 205 Direction stencil_dir = whole_note ? -stemdir : stemdir; |
213 return raw_stencil (me, slope, stencil_dir); | 206 return raw_stencil (me, slope, stencil_dir); |
214 } | 207 } |
215 | 208 |
216 ·· | |
217 Stencil | 209 Stencil |
218 Stem_tremolo::translated_stencil (Grob *me, Real slope) | 210 Stem_tremolo::translated_stencil (Grob *me, Real slope) |
219 { | 211 { |
220 Stencil mol = untranslated_stencil (me, slope); | 212 Stencil mol = untranslated_stencil (me, slope); |
221 | 213 |
222 Grob *stem = unsmob_grob (me->get_object ("stem")); | 214 Grob *stem = unsmob_grob (me->get_object ("stem")); |
223 if (!stem) | 215 if (!stem) |
224 return Stencil (); | 216 return Stencil (); |
225 | 217 |
226 Direction stemdir = get_grob_direction (stem); | 218 Direction stemdir = get_grob_direction (stem); |
227 if (stemdir == 0) | 219 if (stemdir == 0) |
228 stemdir = UP; | 220 stemdir = UP; |
229 | 221 |
230 Spanner *beam = Stem::get_beam (stem); | 222 Spanner *beam = Stem::get_beam (stem); |
231 Real beam_translation = get_beam_translation (me); | 223 Real beam_translation = get_beam_translation (me); |
232 | 224 |
233 int beam_count = beam ? (Stem::beam_multiplicity (stem).length () + 1) : 0; | 225 int beam_count = beam ? (Stem::beam_multiplicity (stem).length () + 1) : 0; |
234 Real ss = Staff_symbol_referencer::staff_space (me); | 226 Real ss = Staff_symbol_referencer::staff_space (me); |
235 | 227 |
236 Real end_y | 228 Real end_y |
237 = Stem::stem_end_position (stem) * ss / 2 | 229 = Stem::stem_end_position (stem) * ss / 2 |
238 - stemdir * max (beam_count, 1) * beam_translation; | 230 - stemdir * max (beam_count, 1) * beam_translation; |
239 | 231 |
240 if (!beam && Stem::duration_log (stem) >= 3) | 232 if (!beam && Stem::duration_log (stem) >= 3) |
241 { | 233 { |
242 end_y -= stemdir * (Stem::duration_log (stem) - 2) * beam_translation; | 234 end_y -= stemdir * (Stem::duration_log (stem) - 2) * beam_translation; |
243 if (stemdir == UP) | 235 if (stemdir == UP) |
244 end_y -= stemdir * beam_translation * 0.5; | 236 end_y -= stemdir * beam_translation * 0.5; |
245 } | 237 } |
246 | 238 |
247 bool whole_note = Stem::duration_log (stem) <= 0; | 239 bool whole_note = Stem::duration_log (stem) <= 0; |
248 if (whole_note) | 240 if (whole_note) |
249 { | 241 { |
250 /* we shouldn't position relative to the end of the stem since the stem | 242 /* we shouldn't position relative to the end of the stem since the stem |
251 is invisible */ | 243 is invisible */ |
252 vector<int> nhp = Stem::note_head_positions (stem); | 244 vector<int> nhp = Stem::note_head_positions (stem); |
253 Real note_head = (stemdir == UP ? nhp.back () : nhp[0]) * ss / 2; | 245 Real note_head = (stemdir == UP ? nhp.back () : nhp[0]) * ss / 2; |
254 end_y = note_head + stemdir * 1.5; | 246 end_y = note_head + stemdir * 1.5; |
255 } | 247 } |
256 mol.translate_axis (end_y, Y_AXIS); | 248 mol.translate_axis (end_y, Y_AXIS); |
257 | 249 |
258 return mol; | 250 return mol; |
259 } | 251 } |
260 | 252 |
261 MAKE_SCHEME_CALLBACK (Stem_tremolo, print, 1); | 253 MAKE_SCHEME_CALLBACK (Stem_tremolo, print, 1); |
262 SCM | 254 SCM |
263 Stem_tremolo::print (SCM grob) | 255 Stem_tremolo::print (SCM grob) |
264 { | 256 { |
265 Grob *me = unsmob_grob (grob); | 257 Grob *me = unsmob_grob (grob); |
266 | 258 |
267 Stencil s = translated_stencil (me, robust_scm2double (me->get_property ("slop
e"), 0.25)); | 259 Stencil s = translated_stencil (me, robust_scm2double (me->get_property ("slop
e"), 0.25)); |
268 return s.smobbed_copy (); | 260 return s.smobbed_copy (); |
269 } | 261 } |
270 | 262 |
271 ADD_INTERFACE (Stem_tremolo, | 263 ADD_INTERFACE (Stem_tremolo, |
272 » "A beam slashing a stem to indicate a tremolo. The property" | 264 "A beam slashing a stem to indicate a tremolo. The property" |
273 » " @code{shape} can be @code{default} or @code{rectangle}.", | 265 " @code{shape} can be @code{beam-like} or @code{rectangle}.", |
274 | 266 |
275 /* properties */ | 267 /* properties */ |
276 » "beam-thickness " | 268 "beam-thickness " |
277 » "beam-width " | 269 "beam-width " |
278 » "flag-count " | 270 "flag-count " |
279 » "length-fraction " | 271 "length-fraction " |
280 » "stem " | 272 "stem " |
281 "shape " | 273 "shape " |
282 "style " | 274 "style " |
283 » "slope " | 275 "slope " |
284 » ); | 276 ); |
LEFT | RIGHT |