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) 2012--2020 Mike Solomon <mike@mikesolomon.org> | 4 Copyright (C) 2012--2020 Mike Solomon <mike@mikesolomon.org> |
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 } | 104 } |
105 SCM res = get_path_list (head); | 105 SCM res = get_path_list (head); |
106 if (scm_is_true (res)) | 106 if (scm_is_true (res)) |
107 return res; | 107 return res; |
108 } | 108 } |
109 return SCM_BOOL_F; | 109 return SCM_BOOL_F; |
110 } | 110 } |
111 | 111 |
112 //// END UTILITY FUNCTIONS | 112 //// END UTILITY FUNCTIONS |
113 | 113 |
114 /* | |
115 below, for all of the functions make_X_boxes, the expression | |
116 is always unpacked into variables. | |
117 then, after a line of /////, there are manipulations of these variables | |
118 (there may be no manipulations necessary depending on the function) | |
119 afterwards, there is another ///// followed by the creation of points | |
120 and boxes | |
121 */ | |
122 | |
123 void | 114 void |
124 make_draw_line_boxes (Lazy_skyline_pair *skyline, Transform const &transform, | 115 make_draw_line_boxes (Lazy_skyline_pair *skyline, Transform const &transform, |
125 SCM expr) | 116 SCM expr) |
126 { | 117 { |
127 Real thick = robust_scm2double (scm_car (expr), 0.0); | 118 Real thick = robust_scm2double (scm_car (expr), 0.0); |
128 expr = scm_cdr (expr); | 119 expr = scm_cdr (expr); |
129 Real x0 = robust_scm2double (scm_car (expr), 0.0); | 120 Real x0 = robust_scm2double (scm_car (expr), 0.0); |
130 expr = scm_cdr (expr); | 121 expr = scm_cdr (expr); |
131 Real y0 = robust_scm2double (scm_car (expr), 0.0); | 122 Real y0 = robust_scm2double (scm_car (expr), 0.0); |
132 expr = scm_cdr (expr); | 123 expr = scm_cdr (expr); |
133 Real x1 = robust_scm2double (scm_car (expr), 0.0); | 124 Real x1 = robust_scm2double (scm_car (expr), 0.0); |
134 expr = scm_cdr (expr); | 125 expr = scm_cdr (expr); |
135 Real y1 = robust_scm2double (scm_car (expr), 0.0); | 126 Real y1 = robust_scm2double (scm_car (expr), 0.0); |
136 | 127 |
137 ////////////////////// | |
138 Offset left (x0, y0); | 128 Offset left (x0, y0); |
139 Offset right (x1, y1); | 129 Offset right (x1, y1); |
140 | 130 |
141 skyline->add_segment (transform, left, right, thick); | 131 skyline->add_segment (transform, left, right, thick); |
142 } | 132 } |
143 | 133 |
144 void | 134 void |
145 make_partial_ellipse_boxes_scm (Lazy_skyline_pair *skyline, | 135 make_partial_ellipse_boxes_scm (Lazy_skyline_pair *skyline, |
146 Transform const &transform, SCM expr) | 136 Transform const &transform, SCM expr) |
147 { | 137 { |
(...skipping 15 matching lines...) Expand all Loading... |
163 fill); | 153 fill); |
164 } | 154 } |
165 | 155 |
166 void | 156 void |
167 make_partial_ellipse_boxes (Lazy_skyline_pair *skyline, | 157 make_partial_ellipse_boxes (Lazy_skyline_pair *skyline, |
168 Transform const &transform, Offset rad, Real start, | 158 Transform const &transform, Offset rad, Real start, |
169 Real end, Real th, bool connect, bool fill) | 159 Real end, Real th, bool connect, bool fill) |
170 { | 160 { |
171 if (end == start) | 161 if (end == start) |
172 end += 360; | 162 end += 360; |
173 Offset sp (offset_directed (start).scale (rad)); | 163 |
174 Offset ep (offset_directed (end).scale (rad)); | |
175 Real x_scale = sqrt (sqr (transform.get_xx ()) + sqr (transform.get_yx ())); | 164 Real x_scale = sqrt (sqr (transform.get_xx ()) + sqr (transform.get_yx ())); |
176 Real y_scale = sqrt (sqr (transform.get_xy ()) + sqr (transform.get_yy ())); | 165 Real y_scale = sqrt (sqr (transform.get_xy ()) + sqr (transform.get_yy ())); |
177 ////////////////////// | 166 |
178 vector<Offset> points; | 167 vector<Offset> points; |
179 int quantization | 168 int quantization |
180 = std::max (1, (int) (((rad[X_AXIS] * x_scale) + (rad[Y_AXIS] * y_scale)) | 169 = std::max (1, (int) (((rad[X_AXIS] * x_scale) + (rad[Y_AXIS] * y_scale)) |
181 * M_PI / QUANTIZATION_UNIT)); | 170 * M_PI / QUANTIZATION_UNIT)); |
| 171 |
| 172 Offset last; |
| 173 Offset first; |
182 for (vsize i = 0; i <= (vsize) quantization; i++) | 174 for (vsize i = 0; i <= (vsize) quantization; i++) |
183 { | 175 { |
184 Real ang = linear_interpolate (static_cast<Real> (i), 0, quantization, | 176 Real ang = linear_interpolate (static_cast<Real> (i), 0, quantization, |
185 start, end); | 177 start, end); |
186 Offset pt (offset_directed (ang).scale (rad)); | 178 Offset pt (offset_directed (ang).scale (rad)); |
| 179 if (i > 0) |
| 180 skyline->add_segment (transform, last, pt, th); |
| 181 else |
| 182 first = pt; |
187 points.push_back (pt); | 183 points.push_back (pt); |
188 } | 184 last = pt; |
189 | |
190 for (vsize i = 0; i < points.size () - 1; i++) | |
191 { | |
192 skyline->add_segment (transform, points[i], points[i + 1], th); | |
193 } | 185 } |
194 | 186 |
195 if (connect || fill) | 187 if (connect || fill) |
196 { | 188 { |
197 skyline->add_segment (transform, sp, ep, th); | 189 skyline->add_segment (transform, first, last, th); |
198 } | 190 } |
199 } | 191 } |
200 | 192 |
201 void | 193 void |
202 make_round_filled_box_boxes (Lazy_skyline_pair *skyline, | 194 make_round_filled_box_boxes (Lazy_skyline_pair *skyline, |
203 Transform const &transform, SCM expr) | 195 Transform const &transform, SCM expr) |
204 { | 196 { |
205 Real left = robust_scm2double (scm_car (expr), 0.0); | 197 Real left = robust_scm2double (scm_car (expr), 0.0); |
206 expr = scm_cdr (expr); | 198 expr = scm_cdr (expr); |
207 Real right = robust_scm2double (scm_car (expr), 0.0); | 199 Real right = robust_scm2double (scm_car (expr), 0.0); |
208 expr = scm_cdr (expr); | 200 expr = scm_cdr (expr); |
209 Real bottom = robust_scm2double (scm_car (expr), 0.0); | 201 Real bottom = robust_scm2double (scm_car (expr), 0.0); |
210 expr = scm_cdr (expr); | 202 expr = scm_cdr (expr); |
211 Real top = robust_scm2double (scm_car (expr), 0.0); | 203 Real top = robust_scm2double (scm_car (expr), 0.0); |
212 expr = scm_cdr (expr); | 204 expr = scm_cdr (expr); |
213 Real diameter = robust_scm2double (scm_car (expr), 0.0); | 205 Real diameter = robust_scm2double (scm_car (expr), 0.0); |
214 ////////////////////// | |
215 | 206 |
216 Real x_scale = sqrt (sqr (transform.get_xx ()) + sqr (transform.get_yx ())); | 207 Real x_scale = sqrt (sqr (transform.get_xx ()) + sqr (transform.get_yx ())); |
217 Real y_scale = sqrt (sqr (transform.get_xy ()) + sqr (transform.get_yy ())); | 208 Real y_scale = sqrt (sqr (transform.get_xy ()) + sqr (transform.get_yy ())); |
218 bool rounded = (diameter * std::max (x_scale, y_scale) > 0.5); | 209 bool rounded = (diameter * std::max (x_scale, y_scale) > 0.5); |
219 bool rotated = (transform.get_yx () || transform.get_xy ()); | 210 bool rotated = (transform.get_yx () || transform.get_xy ()); |
220 ////////////////////// | |
221 | 211 |
222 vector<Box> boxes; | 212 vector<Box> boxes; |
223 if (!rotated && !rounded) | 213 if (!rotated && !rounded) |
224 { | 214 { |
225 /* simple box */ | 215 /* simple box */ |
226 Box b (Interval (-left, right), Interval (-bottom, top)); | 216 Box b (Interval (-left, right), Interval (-bottom, top)); |
227 skyline->add_box (transform, b); | 217 skyline->add_box (transform, b); |
228 } | 218 } |
229 else | 219 else |
230 { | 220 { |
231 int quantization = (int) (rounded * diameter * (x_scale + y_scale) | 221 int quantization = (int) (rounded * diameter * (x_scale + y_scale) |
232 * M_PI / QUANTIZATION_UNIT / 8); | 222 * M_PI / QUANTIZATION_UNIT / 8); |
233 /* if there is no quantization, there is no need to draw | 223 /* if there is no quantization, there is no need to draw |
234 rounded corners. >>> Set the effective skyline radius to 0 */ | 224 rounded corners. >>> Set the effective skyline radius to 0 */ |
235 Real radius = (quantization ? diameter / 2 : 0.); | 225 Real radius = (quantization ? diameter / 2 : 0.); |
236 | 226 |
237 /* draw straight lines */ | 227 /* draw straight lines */ |
238 vector<Offset> points; | 228 Offset points[] = { |
239 | 229 Offset (-left, -bottom + radius), Offset (-left, top - radius), |
240 points.push_back (Offset (-left, -bottom + radius)); | 230 Offset (-left + radius, top), Offset (right - radius, top), |
241 points.push_back (Offset (-left, top - radius)); | 231 Offset (right, top - radius), Offset (right, -bottom + radius), |
242 points.push_back (Offset (-left + radius, -bottom)); | 232 Offset (right - radius, -bottom), Offset (-left + radius, -bottom), |
243 points.push_back (Offset (right - radius, -bottom)); | 233 }; |
244 points.push_back (Offset (right, -bottom + radius)); | 234 for (vsize i = 0; i < ARRAYSIZE (points); i += 2) |
245 points.push_back (Offset (right, top - radius)); | 235 { |
246 points.push_back (Offset (-left + radius, top)); | 236 skyline->add_contour_segment (transform, CW, points[i], |
247 points.push_back (Offset (right - radius, top)); | 237 points[i + 1]); |
248 | |
249 for (vsize i = 0; i < (vsize) points.size () - 1; i += 2) | |
250 { | |
251 skyline->add_segment (transform, points[i], points[i + 1]); | |
252 } | 238 } |
253 | 239 |
254 /* draw rounded corners */ | 240 /* draw rounded corners */ |
255 if (radius) | 241 if (radius) |
256 { | 242 { |
257 vector<Offset> points; | 243 Offset rad (radius, 0); |
258 Offset rad (radius, radius); | |
259 Drul_array<Real> cx; | 244 Drul_array<Real> cx; |
260 Drul_array<Real> cy; | 245 Drul_array<Real> cy; |
261 | 246 |
262 cx[LEFT] = -left + radius; | 247 cx[LEFT] = -left + radius; |
263 cx[RIGHT] = right - radius; | 248 cx[RIGHT] = right - radius; |
264 cy[DOWN] = -bottom + radius; | 249 cy[DOWN] = -bottom + radius; |
265 cy[UP] = top - radius; | 250 cy[UP] = top - radius; |
266 | 251 |
267 for (vsize i = 0; i <= (vsize) quantization; i++) | 252 for (DOWN_and_UP (v)) |
268 for (DOWN_and_UP (v)) | 253 for (LEFT_and_RIGHT (h)) |
269 for (LEFT_and_RIGHT (h)) | 254 { |
270 { | 255 Offset last; |
271 Real ang = linear_interpolate (static_cast<Real> (i), 0, | 256 for (vsize i = 0; i <= (vsize) quantization; i++) |
272 quantization, 0., 90.); | 257 { |
273 Offset pt (offset_directed (ang).scale (rad)); | 258 Real ang = linear_interpolate (static_cast<Real> (i), 0, |
274 Offset inter (cx[h] + h * pt[X_AXIS], | 259 quantization, 0., 90.); |
275 cy[v] + v * pt[Y_AXIS]); | 260 Offset pt (offset_directed (ang).scale (rad)); |
276 points.push_back (inter); | 261 Offset inter (cx[h] + h * pt[X_AXIS], |
277 } | 262 cy[v] + v * pt[Y_AXIS]); |
278 | 263 |
279 for (vsize i = 0; i < points.size () - 4; i++) | 264 if (i > 0) |
280 { | 265 { |
281 skyline->add_segment (transform, points[i], points[i + 4]); | 266 skyline->add_segment (transform, last, inter); |
282 } | 267 } |
| 268 last = inter; |
| 269 } |
| 270 } |
283 } | 271 } |
284 } | 272 } |
285 } | 273 } |
286 | 274 |
287 void | 275 void |
288 make_draw_bezier_boxes_scm (Lazy_skyline_pair *skyline, | 276 make_draw_bezier_boxes_scm (Lazy_skyline_pair *skyline, |
289 Transform const &transform, SCM expr) | 277 Transform const &transform, SCM expr) |
290 { | 278 { |
291 Real th = robust_scm2double (scm_car (expr), 0.0); | 279 Real th = robust_scm2double (scm_car (expr), 0.0); |
292 expr = scm_cdr (expr); | 280 expr = scm_cdr (expr); |
293 Real x0 = robust_scm2double (scm_car (expr), 0.0); | 281 Real x0 = robust_scm2double (scm_car (expr), 0.0); |
294 expr = scm_cdr (expr); | 282 expr = scm_cdr (expr); |
295 Real y0 = robust_scm2double (scm_car (expr), 0.0); | 283 Real y0 = robust_scm2double (scm_car (expr), 0.0); |
296 expr = scm_cdr (expr); | 284 expr = scm_cdr (expr); |
297 Real x1 = robust_scm2double (scm_car (expr), 0.0); | 285 Real x1 = robust_scm2double (scm_car (expr), 0.0); |
298 expr = scm_cdr (expr); | 286 expr = scm_cdr (expr); |
299 Real y1 = robust_scm2double (scm_car (expr), 0.0); | 287 Real y1 = robust_scm2double (scm_car (expr), 0.0); |
300 expr = scm_cdr (expr); | 288 expr = scm_cdr (expr); |
301 Real x2 = robust_scm2double (scm_car (expr), 0.0); | 289 Real x2 = robust_scm2double (scm_car (expr), 0.0); |
302 expr = scm_cdr (expr); | 290 expr = scm_cdr (expr); |
303 Real y2 = robust_scm2double (scm_car (expr), 0.0); | 291 Real y2 = robust_scm2double (scm_car (expr), 0.0); |
304 expr = scm_cdr (expr); | 292 expr = scm_cdr (expr); |
305 Real x3 = robust_scm2double (scm_car (expr), 0.0); | 293 Real x3 = robust_scm2double (scm_car (expr), 0.0); |
306 expr = scm_cdr (expr); | 294 expr = scm_cdr (expr); |
307 Real y3 = robust_scm2double (scm_car (expr), 0.0); | 295 Real y3 = robust_scm2double (scm_car (expr), 0.0); |
308 ////////////////////// | 296 |
309 | 297 Offset ps[] = { |
310 Offset ps[4] = { | |
311 Offset (x0, y0), | 298 Offset (x0, y0), |
312 Offset (x1, y1), | 299 Offset (x1, y1), |
313 Offset (x2, y2), | 300 Offset (x2, y2), |
314 Offset (x3, y3), | 301 Offset (x3, y3), |
315 }; | 302 }; |
316 make_draw_bezier_boxes (skyline, transform, th, ps); | 303 make_draw_bezier_boxes (skyline, transform, th, ps); |
317 } | 304 } |
318 | 305 |
319 void | 306 void |
320 make_draw_bezier_boxes (Lazy_skyline_pair *skyline, Transform const &transform, | 307 make_draw_bezier_boxes (Lazy_skyline_pair *skyline, Transform const &transform, |
321 Real th, Offset control[4]) | 308 Real th, Offset control[4]) |
322 { | 309 { |
323 Bezier curve; | 310 Bezier curve; |
| 311 |
| 312 Real len = 0.0; |
| 313 Offset last; |
324 for (int i = 0; i < 4; i++) | 314 for (int i = 0; i < 4; i++) |
325 curve.control_[i] = control[i]; | 315 { |
326 | 316 curve.control_[i] = control[i]; |
327 Offset temp0 (transform (curve.control_[0])); | 317 Offset transformed = transform (control[i]); |
328 Offset temp1 (transform (curve.control_[1])); | 318 if (i > 0) |
329 Offset temp2 (transform (curve.control_[2])); | 319 { |
330 Offset temp3 (transform (curve.control_[3])); | 320 len += (transformed - last).length (); |
| 321 } |
| 322 last = transformed; |
| 323 } |
331 | 324 |
332 ////////////////////// | 325 ////////////////////// |
| 326 int quantization = int (len / QUANTIZATION_UNIT); |
| 327 |
333 vector<Offset> points; | 328 vector<Offset> points; |
334 int quantization = int (((temp1 - temp0).length () | 329 points.reserve (quantization + 1); |
335 + (temp2 - temp1).length () | 330 |
336 + (temp3 - temp2).length ()) | 331 last = curve.control_[0]; |
337 / QUANTIZATION_UNIT); | |
338 | |
339 points.push_back (curve.control_[0]); | |
340 for (vsize i = 1; i < (vsize) quantization; i++) | 332 for (vsize i = 1; i < (vsize) quantization; i++) |
341 { | 333 { |
342 Real pt = static_cast<Real> (i) / quantization; | 334 Real t = static_cast<Real> (i) / quantization; |
343 points.push_back (curve.curve_point (pt)); | 335 Offset pt = curve.curve_point (t); |
344 } | 336 skyline->add_segment (transform, last, pt, th); |
345 points.push_back (curve.control_[3]); | 337 last = pt; |
346 | 338 } |
347 for (vsize i = 0; i < points.size () - 1; i++) | 339 |
348 { | 340 skyline->add_segment (transform, last, curve.control_[3], th); |
349 skyline->add_segment (transform, points[i], points[i + 1], th); | |
350 } | |
351 } | 341 } |
352 | 342 |
353 /* | 343 /* |
354 converts a path into lists of 4 (line) or 8 (curve) absolute coordinates | 344 converts a path into lists of 4 (line) or 8 (curve) absolute coordinates |
355 for example: | 345 for example: |
356 '(moveto 1 2 lineto 3 4 rlineto -1 -1 curveto | 346 '(moveto 1 2 lineto 3 4 rlineto -1 -1 curveto |
357 3 3 5 5 6 6 rcurveto -1 -1 -1 -1 -1 -1 closepath) | 347 3 3 5 5 6 6 rcurveto -1 -1 -1 -1 -1 -1 closepath) |
358 becomes | 348 becomes |
359 '((1 2 3 4) | 349 '((1 2 3 4) |
360 (3 4 2 3) | 350 (3 4 2 3) |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 scm_cons (scm_car (expr), get_path_list (scm_cdr (expr)))); | 507 scm_cons (scm_car (expr), get_path_list (scm_cdr (expr)))); |
518 } | 508 } |
519 | 509 |
520 void | 510 void |
521 make_polygon_boxes (Lazy_skyline_pair *skyline, Transform const &transform, | 511 make_polygon_boxes (Lazy_skyline_pair *skyline, Transform const &transform, |
522 SCM expr) | 512 SCM expr) |
523 { | 513 { |
524 SCM coords = get_number_list (scm_car (expr)); | 514 SCM coords = get_number_list (scm_car (expr)); |
525 expr = scm_cdr (expr); | 515 expr = scm_cdr (expr); |
526 SCM blot_diameter = scm_car (expr); | 516 SCM blot_diameter = scm_car (expr); |
527 ////////////////////// | 517 |
528 bool first = true; | 518 bool first = true; |
529 SCM l = SCM_EOL; | 519 SCM l = SCM_EOL; |
530 for (SCM s = coords; scm_is_pair (s); s = scm_cddr (s)) | 520 for (SCM s = coords; scm_is_pair (s); s = scm_cddr (s)) |
531 { | 521 { |
532 l = scm_cons (first ? ly_symbol2scm ("moveto") : ly_symbol2scm ("lineto"),
l); | 522 l = scm_cons (first ? ly_symbol2scm ("moveto") : ly_symbol2scm ("lineto"),
l); |
533 l = scm_cons (scm_car (s), l); | 523 l = scm_cons (scm_car (s), l); |
534 l = scm_cons (scm_cadr (s), l); | 524 l = scm_cons (scm_cadr (s), l); |
535 first = false; | 525 first = false; |
536 } | 526 } |
537 l = scm_cons (ly_symbol2scm ("closepath"), l); | 527 l = scm_cons (ly_symbol2scm ("closepath"), l); |
538 internal_make_path_boxes ( | 528 internal_make_path_boxes ( |
539 skyline, transform, scm_cons (blot_diameter, scm_reverse_x (l, SCM_EOL))); | 529 skyline, transform, scm_cons (blot_diameter, scm_reverse_x (l, SCM_EOL))); |
540 } | 530 } |
541 | 531 |
542 void | 532 void |
543 make_named_glyph_boxes (Lazy_skyline_pair *skyline, Transform const &transform, | 533 make_named_glyph_boxes (Lazy_skyline_pair *skyline, Transform const &transform, |
544 SCM expr) | 534 SCM expr) |
545 { | 535 { |
546 SCM fm_scm = scm_car (expr); | 536 SCM fm_scm = scm_car (expr); |
547 Font_metric *fm = unsmob<Font_metric> (fm_scm); | 537 Font_metric *fm = unsmob<Font_metric> (fm_scm); |
548 expr = scm_cdr (expr); | 538 expr = scm_cdr (expr); |
549 SCM glyph = scm_car (expr); | 539 SCM glyph = scm_car (expr); |
550 string glyph_s = ly_scm2string (glyph); | 540 string glyph_s = ly_scm2string (glyph); |
551 | 541 |
552 ////////////////////// | |
553 Open_type_font *open_fm | 542 Open_type_font *open_fm |
554 = dynamic_cast<Open_type_font *> | 543 = dynamic_cast<Open_type_font *> |
555 (dynamic_cast<Modified_font_metric *>(fm)->original_font ()); | 544 (dynamic_cast<Modified_font_metric *>(fm)->original_font ()); |
556 SCM_ASSERT_TYPE (open_fm, fm_scm, SCM_ARG1, __FUNCTION__, "OpenType font"); | 545 SCM_ASSERT_TYPE (open_fm, fm_scm, SCM_ARG1, __FUNCTION__, "OpenType font"); |
557 | 546 |
558 size_t gidx = open_fm->name_to_index (glyph_s); | 547 size_t gidx = open_fm->name_to_index (glyph_s); |
559 // Bbox is the best approximation of the width based on how it would be | 548 // Bbox is the best approximation of the width based on how it would be |
560 // calculated in open-type-font.cc if it were based on real extents | 549 // calculated in open-type-font.cc if it were based on real extents |
561 Box bbox = open_fm->get_unscaled_indexed_char_dimensions (gidx); | 550 Box bbox = open_fm->get_unscaled_indexed_char_dimensions (gidx); |
562 bbox.scale (dynamic_cast<Modified_font_metric *> (fm)->get_magnification () | 551 bbox.scale (dynamic_cast<Modified_font_metric *> (fm)->get_magnification () |
(...skipping 18 matching lines...) Expand all Loading... |
581 expr = scm_cdr (expr); | 570 expr = scm_cdr (expr); |
582 expr = scm_cdr (expr); // font-name | 571 expr = scm_cdr (expr); // font-name |
583 expr = scm_cdr (expr); // size | 572 expr = scm_cdr (expr); // size |
584 expr = scm_cdr (expr); // cid? | 573 expr = scm_cdr (expr); // cid? |
585 SCM whxy = scm_cadar (expr); | 574 SCM whxy = scm_cadar (expr); |
586 vector<Real> widths; | 575 vector<Real> widths; |
587 vector<Interval> heights; | 576 vector<Interval> heights; |
588 vector<Real> xos; | 577 vector<Real> xos; |
589 vector<Real> yos; | 578 vector<Real> yos; |
590 vector<string> char_ids; | 579 vector<string> char_ids; |
591 ////////////////////// | 580 |
592 Pango_font *pango_fm = dynamic_cast<Pango_font *> (fm); | 581 Pango_font *pango_fm = dynamic_cast<Pango_font *> (fm); |
593 SCM_ASSERT_TYPE (pango_fm, fm_scm, SCM_ARG1, __FUNCTION__, "Pango font"); | 582 SCM_ASSERT_TYPE (pango_fm, fm_scm, SCM_ARG1, __FUNCTION__, "Pango font"); |
594 | 583 |
595 for (SCM s = whxy; scm_is_pair (s); s = scm_cdr (s)) | 584 for (SCM s = whxy; scm_is_pair (s); s = scm_cdr (s)) |
596 { | 585 { |
597 SCM now = scm_car (s); | 586 SCM now = scm_car (s); |
598 widths.push_back (robust_scm2double (scm_car (now), 0.0)); | 587 widths.push_back (robust_scm2double (scm_car (now), 0.0)); |
599 now = scm_cdr (now); | 588 now = scm_cdr (now); |
600 heights.push_back (robust_scm2interval (scm_car (now), Interval (0, 0))); | 589 heights.push_back (robust_scm2interval (scm_car (now), Interval (0, 0))); |
601 now = scm_cdr (now); | 590 now = scm_cdr (now); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 .translate (-Offset (bbox[X_AXIS][LEFT], bbox[Y_AXIS][DOWN])); | 646 .translate (-Offset (bbox[X_AXIS][LEFT], bbox[Y_AXIS][DOWN])); |
658 pango_fm->add_outline_to_skyline (skyline, transcopy, gidx); | 647 pango_fm->add_outline_to_skyline (skyline, transcopy, gidx); |
659 } | 648 } |
660 } | 649 } |
661 } | 650 } |
662 | 651 |
663 /* | 652 /* |
664 receives a stencil expression and a transform matrix | 653 receives a stencil expression and a transform matrix |
665 depending on the stencil name, dispatches it to the appropriate function | 654 depending on the stencil name, dispatches it to the appropriate function |
666 */ | 655 */ |
667 | 656 static void |
668 void | 657 interpret_stencil_for_skyline (Lazy_skyline_pair *skyline, |
669 stencil_dispatcher (Lazy_skyline_pair *skyline, Transform const &transform, | 658 Transform const &transform, SCM expr) |
670 SCM expr) | 659 { |
671 { | 660 if (scm_is_null (expr) |
672 if (not scm_is_pair (expr)) | 661 || (scm_is_string (expr) && scm_is_true (scm_string_null_p (expr)))) |
673 return; | 662 return; |
674 | 663 |
675 SCM head = scm_car (expr); | 664 SCM head = scm_car (expr); |
676 if (scm_is_eq (head, ly_symbol2scm ("draw-line"))) | 665 if (scm_is_eq (head, ly_symbol2scm ("combine-stencil"))) |
| 666 { |
| 667 for (SCM s = scm_cdr (expr); scm_is_pair (s); s = scm_cdr (s)) |
| 668 interpret_stencil_for_skyline (skyline, transform, scm_car (s)); |
| 669 } |
| 670 else if (scm_is_eq (head, ly_symbol2scm ("translate-stencil"))) |
| 671 { |
| 672 Offset p = robust_scm2offset (scm_cadr (expr), Offset (0.0, 0.0)); |
| 673 Transform local = transform; |
| 674 local.translate (p); |
| 675 interpret_stencil_for_skyline (skyline, local, scm_caddr (expr)); |
| 676 } |
| 677 else if (scm_is_eq (head, ly_symbol2scm ("scale-stencil"))) |
| 678 { |
| 679 Real x = robust_scm2double (scm_caadr (expr), 0.0); |
| 680 Real y = robust_scm2double (scm_cadadr (expr), 0.0); |
| 681 Transform local = transform; |
| 682 local.scale (x, y); |
| 683 interpret_stencil_for_skyline (skyline, local, scm_caddr (expr)); |
| 684 } |
| 685 else if (scm_is_eq (head, ly_symbol2scm ("rotate-stencil"))) |
| 686 { |
| 687 Real ang = robust_scm2double (scm_caadr (expr), 0.0); |
| 688 Offset center = robust_scm2offset (scm_cadadr (expr), Offset (0.0, 0.0)); |
| 689 Transform local = transform; |
| 690 local.rotate (ang, center); |
| 691 interpret_stencil_for_skyline (skyline, local, scm_caddr (expr)); |
| 692 } |
| 693 else if (scm_is_eq (head, ly_symbol2scm ("grob-cause"))) |
| 694 interpret_stencil_for_skyline (skyline, transform, scm_caddr (expr)); |
| 695 else if (scm_is_eq (head, ly_symbol2scm ("color"))) |
| 696 interpret_stencil_for_skyline (skyline, transform, scm_caddr (expr)); |
| 697 else if (scm_is_eq (head, ly_symbol2scm ("output-attributes"))) |
| 698 interpret_stencil_for_skyline (skyline, transform, scm_caddr (expr)); |
| 699 else if (scm_is_eq (head, ly_symbol2scm ("utf-8-string"))) |
| 700 { |
| 701 // 4th element, strip the (quote ..) |
| 702 SCM orig = scm_cadar (scm_cdddr (expr)); |
| 703 interpret_stencil_for_skyline (skyline, transform, orig); |
| 704 } |
| 705 else if (scm_is_eq (head, ly_symbol2scm ("with-outline"))) |
| 706 interpret_stencil_for_skyline (skyline, transform, scm_cadr (expr)); |
| 707 else if (scm_is_eq (head, ly_symbol2scm ("draw-line"))) |
677 make_draw_line_boxes (skyline, transform, scm_cdr (expr)); | 708 make_draw_line_boxes (skyline, transform, scm_cdr (expr)); |
678 else if (scm_is_eq (head, ly_symbol2scm ("dashed-line"))) | 709 else if (scm_is_eq (head, ly_symbol2scm ("dashed-line"))) |
679 { | 710 { |
680 expr = scm_cdr (expr); | 711 expr = scm_cdr (expr); |
681 SCM th = scm_car (expr); | 712 SCM th = scm_car (expr); |
682 expr = scm_cdr (expr); | 713 expr = scm_cdr (expr); |
683 expr = scm_cdr (expr); // on | 714 expr = scm_cdr (expr); // on |
684 expr = scm_cdr (expr); // off | 715 expr = scm_cdr (expr); // off |
685 SCM x1 = scm_car (expr); | 716 SCM x1 = scm_car (expr); |
686 expr = scm_cdr (expr); | 717 expr = scm_cdr (expr); |
687 SCM x2 = scm_car (expr); | 718 SCM x2 = scm_car (expr); |
688 make_draw_line_boxes ( | 719 |
689 skyline, transform, | 720 skyline->add_segment ( |
690 scm_list_5 (th, scm_from_double (0.0), scm_from_double (0.0), x1, x2)); | 721 transform, Offset (0.0, 0.0), |
| 722 Offset (robust_scm2double (x1, 0.0), robust_scm2double (x2, 0.0)), |
| 723 robust_scm2double (th, 0.0)); |
691 } | 724 } |
692 else if (scm_is_eq (head, ly_symbol2scm ("circle"))) | 725 else if (scm_is_eq (head, ly_symbol2scm ("circle"))) |
693 { | 726 { |
694 expr = scm_cdr (expr); | 727 expr = scm_cdr (expr); |
695 SCM rad = scm_car (expr); | 728 Real rad = robust_scm2double (scm_car (expr), 0); |
696 expr = scm_cdr (expr); | 729 expr = scm_cdr (expr); |
697 SCM th = scm_car (expr); | 730 Real th = robust_scm2double (scm_car (expr), 0); |
698 make_partial_ellipse_boxes_scm ( | 731 make_partial_ellipse_boxes (skyline, transform, Offset (rad, rad), 0.0, |
699 skyline, transform, | 732 360.0, th, false, true); |
700 scm_list_n (rad, rad, scm_from_double (0.0), scm_from_double (360.0), | |
701 th, SCM_BOOL_F, SCM_BOOL_T, SCM_UNDEFINED)); | |
702 } | 733 } |
703 else if (scm_is_eq (head, ly_symbol2scm ("ellipse"))) | 734 else if (scm_is_eq (head, ly_symbol2scm ("ellipse"))) |
704 { | 735 { |
705 expr = scm_cdr (expr); | 736 expr = scm_cdr (expr); |
706 SCM x_rad = scm_car (expr); | 737 Real x_rad = robust_scm2double (scm_car (expr), 0); |
| 738 |
707 expr = scm_cdr (expr); | 739 expr = scm_cdr (expr); |
708 SCM y_rad = scm_car (expr); | 740 Real y_rad = robust_scm2double (scm_car (expr), 0); |
| 741 |
709 expr = scm_cdr (expr); | 742 expr = scm_cdr (expr); |
710 SCM th = scm_car (expr); | 743 Real th = robust_scm2double (scm_car (expr), 0); |
711 make_partial_ellipse_boxes_scm ( | 744 make_partial_ellipse_boxes (skyline, transform, Offset (x_rad, y_rad), 0, |
712 skyline, transform, | 745 360, th, false, true); |
713 scm_list_n (x_rad, y_rad, scm_from_double (0.0), | |
714 scm_from_double (360.0), th, SCM_BOOL_F, SCM_BOOL_T, | |
715 SCM_UNDEFINED)); | |
716 } | 746 } |
717 else if (scm_is_eq (head, ly_symbol2scm ("partial-ellipse"))) | 747 else if (scm_is_eq (head, ly_symbol2scm ("partial-ellipse"))) |
718 make_partial_ellipse_boxes_scm (skyline, transform, scm_cdr (expr)); | 748 make_partial_ellipse_boxes_scm (skyline, transform, scm_cdr (expr)); |
719 else if (scm_is_eq (head, ly_symbol2scm ("round-filled-box"))) | 749 else if (scm_is_eq (head, ly_symbol2scm ("round-filled-box"))) |
720 make_round_filled_box_boxes (skyline, transform, scm_cdr (expr)); | 750 make_round_filled_box_boxes (skyline, transform, scm_cdr (expr)); |
721 else if (scm_is_eq (head, ly_symbol2scm ("named-glyph"))) | 751 else if (scm_is_eq (head, ly_symbol2scm ("named-glyph"))) |
722 make_named_glyph_boxes (skyline, transform, scm_cdr (expr)); | 752 make_named_glyph_boxes (skyline, transform, scm_cdr (expr)); |
723 else if (scm_is_eq (head, ly_symbol2scm ("polygon"))) | 753 else if (scm_is_eq (head, ly_symbol2scm ("polygon"))) |
724 make_polygon_boxes (skyline, transform, scm_cdr (expr)); | 754 make_polygon_boxes (skyline, transform, scm_cdr (expr)); |
725 else if (scm_is_eq (head, ly_symbol2scm ("path"))) | 755 else if (scm_is_eq (head, ly_symbol2scm ("path"))) |
726 make_path_boxes (skyline, transform, scm_cdr (expr)); | 756 make_path_boxes (skyline, transform, scm_cdr (expr)); |
727 else if (scm_is_eq (head, ly_symbol2scm ("glyph-string"))) | 757 else if (scm_is_eq (head, ly_symbol2scm ("glyph-string"))) |
728 make_glyph_string_boxes (skyline, transform, scm_cdr (expr)); | 758 make_glyph_string_boxes (skyline, transform, scm_cdr (expr)); |
729 else | 759 else |
730 { | 760 { |
731 /* | 761 /* |
732 We don't issue a warning here, as we assume that stencil-expression.cc | 762 We don't issue a warning here, as we assume that stencil-expression.cc |
733 is doing stencil-checking correctly. | 763 is doing stencil-checking correctly. |
734 */ | 764 */ |
735 } | 765 } |
736 } | 766 } |
737 | 767 |
738 /* | |
739 traverses a stencil expression, returning a reversed list of Scheme | |
740 pairs, consisting of a Transform indicating where to move a stencil | |
741 and the stencil expression to show how to construct the stencil | |
742 | |
743 The given "tail" is appended. | |
744 */ | |
745 SCM | |
746 stencil_traverser (Transform const &transform, SCM expr, SCM tail) | |
747 { | |
748 if (scm_is_null (expr) | |
749 || (scm_is_string (expr) && scm_is_true (scm_string_null_p (expr)))) | |
750 return tail; | |
751 | |
752 SCM head = scm_car (expr); | |
753 if (scm_is_eq (head, ly_symbol2scm ("combine-stencil"))) | |
754 { | |
755 for (SCM s = scm_cdr (expr); scm_is_pair (s); s = scm_cdr (s)) | |
756 tail = stencil_traverser (transform, scm_car (s), tail); | |
757 return tail; | |
758 } | |
759 else if (scm_is_eq (head, ly_symbol2scm ("footnote"))) | |
760 return tail; | |
761 else if (scm_is_eq (head, ly_symbol2scm ("translate-stencil"))) | |
762 { | |
763 Offset p = robust_scm2offset (scm_cadr (expr), Offset (0.0, 0.0)); | |
764 Transform local = transform; | |
765 local.translate (p); | |
766 return stencil_traverser (local, scm_caddr (expr), tail); | |
767 } | |
768 else if (scm_is_eq (head, ly_symbol2scm ("scale-stencil"))) | |
769 { | |
770 Real x = robust_scm2double (scm_caadr (expr), 0.0); | |
771 Real y = robust_scm2double (scm_cadadr (expr), 0.0); | |
772 Transform local = transform; | |
773 local.scale (x, y); | |
774 return stencil_traverser (local, scm_caddr (expr), tail); | |
775 } | |
776 else if (scm_is_eq (head, ly_symbol2scm ("rotate-stencil"))) | |
777 { | |
778 Real ang = robust_scm2double (scm_caadr (expr), 0.0); | |
779 Offset center = robust_scm2offset (scm_cadadr (expr), Offset (0.0, 0.0)); | |
780 Transform local = transform; | |
781 local.rotate (ang, center); | |
782 return stencil_traverser (local, scm_caddr (expr), tail); | |
783 } | |
784 else if (scm_is_eq (head, ly_symbol2scm ("delay-stencil-evaluation"))) | |
785 // should not use the place-holder text, but no need for the warning below | |
786 return tail; | |
787 else if (scm_is_eq (head, ly_symbol2scm ("grob-cause"))) | |
788 return stencil_traverser (transform, scm_caddr (expr), tail); | |
789 else if (scm_is_eq (head, ly_symbol2scm ("color"))) | |
790 return stencil_traverser (transform, scm_caddr (expr), tail); | |
791 else if (scm_is_eq (head, ly_symbol2scm ("output-attributes"))) | |
792 return stencil_traverser (transform, scm_caddr (expr), tail); | |
793 else if (scm_is_eq (head, ly_symbol2scm ("with-outline"))) | |
794 return stencil_traverser (transform, scm_cadr (expr), tail); | |
795 else | |
796 { | |
797 return scm_acons (transform.smobbed_copy (), expr, tail); | |
798 } | |
799 warning ("Stencil expression not supported by the vertical skylines."); | |
800 return tail; | |
801 } | |
802 | |
803 SCM | 768 SCM |
804 Grob::maybe_pure_internal_simple_skylines_from_extents (Grob *me, Axis a, bool p
ure, int beg, int end, bool ignore_x, bool ignore_y) | 769 Grob::maybe_pure_internal_simple_skylines_from_extents (Grob *me, Axis a, bool p
ure, int beg, int end, bool ignore_x, bool ignore_y) |
805 { | 770 { |
806 vector<Box> boxes; | 771 vector<Box> boxes; |
807 // we don't know how far spanners stretch along the X axis before | 772 // we don't know how far spanners stretch along the X axis before |
808 // line breaking. better have them take up the whole thing | 773 // line breaking. better have them take up the whole thing |
809 Interval xex = ignore_x | 774 Interval xex = ignore_x |
810 ? Interval (-infinity_f, infinity_f) | 775 ? Interval (-infinity_f, infinity_f) |
811 : me->extent (me, X_AXIS); | 776 : me->extent (me, X_AXIS); |
812 | 777 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 MAKE_SCHEME_CALLBACK (Grob, pure_simple_horizontal_skylines_from_extents, 3); | 812 MAKE_SCHEME_CALLBACK (Grob, pure_simple_horizontal_skylines_from_extents, 3); |
848 SCM | 813 SCM |
849 Grob::pure_simple_horizontal_skylines_from_extents (SCM smob, SCM begscm, SCM en
dscm) | 814 Grob::pure_simple_horizontal_skylines_from_extents (SCM smob, SCM begscm, SCM en
dscm) |
850 { | 815 { |
851 Grob *me = unsmob<Grob> (smob); | 816 Grob *me = unsmob<Grob> (smob); |
852 int beg = robust_scm2int (begscm, 0); | 817 int beg = robust_scm2int (begscm, 0); |
853 int end = robust_scm2int (endscm, INT_MAX); | 818 int end = robust_scm2int (endscm, INT_MAX); |
854 // If the grob is cross staff, we cannot measure its Y-extent before | 819 // If the grob is cross staff, we cannot measure its Y-extent before |
855 // wayyyy downstream (after spacing of axis groups is done). | 820 // wayyyy downstream (after spacing of axis groups is done). |
856 // Thus, we assume that the Y extent is infinite for cross staff grobs. | 821 // Thus, we assume that the Y extent is infinite for cross staff grobs. |
857 return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, true, beg
, end, false, to_boolean (me->get_property ("cross-staff"))); | 822 return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, true, beg
, end, false, to_boolean (get_property (me, "cross-staff"))); |
858 } | 823 } |
859 | 824 |
860 MAKE_SCHEME_CALLBACK (Grob, simple_horizontal_skylines_from_extents, 1); | 825 MAKE_SCHEME_CALLBACK (Grob, simple_horizontal_skylines_from_extents, 1); |
861 SCM | 826 SCM |
862 Grob::simple_horizontal_skylines_from_extents (SCM smob) | 827 Grob::simple_horizontal_skylines_from_extents (SCM smob) |
863 { | 828 { |
864 Grob *me = unsmob<Grob> (smob); | 829 Grob *me = unsmob<Grob> (smob); |
865 // See comment in function above. | 830 // See comment in function above. |
866 return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, false, 0,
0, false, to_boolean (me->get_property ("cross-staff"))); | 831 return maybe_pure_internal_simple_skylines_from_extents (me, Y_AXIS, false, 0,
0, false, to_boolean (get_property (me, "cross-staff"))); |
867 } | 832 } |
868 | 833 |
869 SCM | 834 SCM |
870 Stencil::skylines_from_stencil (SCM sten, Real pad, SCM rot, Axis a) | 835 Stencil::skylines_from_stencil (SCM sten, Real pad, SCM rot, Axis a) |
871 { | 836 { |
872 Stencil *s = unsmob<Stencil> (sten); | 837 Stencil *s = unsmob<Stencil> (sten); |
873 | 838 |
874 if (!s) | 839 if (!s) |
875 return Skyline_pair ().smobbed_copy (); | 840 return Skyline_pair ().smobbed_copy (); |
876 | 841 |
| 842 Transform transform = Transform::identity; |
877 if (scm_is_pair (rot)) | 843 if (scm_is_pair (rot)) |
878 { | 844 { |
879 Real angle = robust_scm2double (scm_car (rot), 0.0); | 845 Real angle = robust_scm2double (scm_car (rot), 0.0); |
880 Real x = robust_scm2double (scm_cadr (rot), 0.0); | 846 Real x = robust_scm2double (scm_cadr (rot), 0.0); |
881 Real y = robust_scm2double (scm_caddr (rot), 0.0); | 847 Real y = robust_scm2double (scm_caddr (rot), 0.0); |
882 | 848 |
883 // incorporate rotation into a stencil copy | 849 transform.rotate (angle, Offset (x, y)); |
884 sten = s->smobbed_copy (); | 850 } |
885 s = unsmob<Stencil> (sten); | |
886 s->rotate_degrees (angle, Offset (x, y)); | |
887 } | |
888 | |
889 SCM data = scm_reverse_x ( | |
890 stencil_traverser (Transform::identity, s->expr (), SCM_EOL), SCM_EOL); | |
891 | 851 |
892 Lazy_skyline_pair lazy (a); | 852 Lazy_skyline_pair lazy (a); |
893 for (SCM s = scm_reverse_x (data, SCM_EOL); scm_is_pair (s); s = scm_cdr (s)) | 853 interpret_stencil_for_skyline (&lazy, transform, s->expr ()); |
894 stencil_dispatcher (&lazy, robust_scm2transform (scm_caar (s)), | |
895 scm_cdar (s)); | |
896 | 854 |
897 Skyline_pair out; | 855 Skyline_pair out; |
898 for (DOWN_and_UP (d)) | 856 for (DOWN_and_UP (d)) |
899 out[d] = lazy.to_pair ()[d].padded (pad); | 857 out[d] = lazy.to_pair ()[d].padded (pad); |
900 | 858 |
901 return out.smobbed_copy (); | 859 return out.smobbed_copy (); |
902 } | 860 } |
903 | 861 |
904 MAKE_SCHEME_CALLBACK (Grob, vertical_skylines_from_stencil, 1); | 862 MAKE_SCHEME_CALLBACK (Grob, vertical_skylines_from_stencil, 1); |
905 SCM | 863 SCM |
906 Grob::vertical_skylines_from_stencil (SCM smob) | 864 Grob::vertical_skylines_from_stencil (SCM smob) |
907 { | 865 { |
908 Grob *me = unsmob<Grob> (smob); | 866 Grob *me = unsmob<Grob> (smob); |
909 Real pad = robust_scm2double (me->get_property ("skyline-horizontal-padding"),
0.0); | 867 Real pad = robust_scm2double (get_property (me, "skyline-horizontal-padding"),
0.0); |
910 SCM rot = me->get_property ("rotation"); | 868 SCM rot = get_property (me, "rotation"); |
911 SCM out = Stencil::skylines_from_stencil (me->get_property ("stencil"), | 869 SCM out = Stencil::skylines_from_stencil (get_property (me, "stencil"), |
912 pad, rot, X_AXIS); | 870 pad, rot, X_AXIS); |
913 return out; | 871 return out; |
914 } | 872 } |
915 | 873 |
916 MAKE_SCHEME_CALLBACK (Grob, horizontal_skylines_from_stencil, 1); | 874 MAKE_SCHEME_CALLBACK (Grob, horizontal_skylines_from_stencil, 1); |
917 SCM | 875 SCM |
918 Grob::horizontal_skylines_from_stencil (SCM smob) | 876 Grob::horizontal_skylines_from_stencil (SCM smob) |
919 { | 877 { |
920 Grob *me = unsmob<Grob> (smob); | 878 Grob *me = unsmob<Grob> (smob); |
921 Real pad = robust_scm2double (me->get_property ("skyline-vertical-padding"), 0
.0); | 879 Real pad = robust_scm2double (get_property (me, "skyline-vertical-padding"), 0
.0); |
922 SCM rot = me->get_property ("rotation"); | 880 SCM rot = get_property (me, "rotation"); |
923 SCM out = Stencil::skylines_from_stencil (me->get_property ("stencil"), | 881 SCM out = Stencil::skylines_from_stencil (get_property (me, "stencil"), |
924 pad, rot, Y_AXIS); | 882 pad, rot, Y_AXIS); |
925 | 883 |
926 return out; | 884 return out; |
927 } | 885 } |
928 | 886 |
929 SCM | 887 SCM |
930 Grob::internal_skylines_from_element_stencils (Grob *me, Axis a, bool pure, int
beg, int end) | 888 Grob::internal_skylines_from_element_stencils (Grob *me, Axis a, bool pure, int
beg, int end) |
931 { | 889 { |
932 | 890 |
933 extract_grob_set (me, "elements", elts); | 891 extract_grob_set (me, "elements", elts); |
934 vector<Real> x_pos; | 892 vector<Real> x_pos; |
935 vector<Real> y_pos; | 893 vector<Real> y_pos; |
936 Grob *x_common = common_refpoint_of_array (elts, me, X_AXIS); | 894 Grob *x_common = common_refpoint_of_array (elts, me, X_AXIS); |
937 Grob *y_common = common_refpoint_of_array (elts, me, Y_AXIS); | 895 Grob *y_common = common_refpoint_of_array (elts, me, Y_AXIS); |
938 for (vsize i = 0; i < elts.size (); i++) | 896 for (vsize i = 0; i < elts.size (); i++) |
939 { | 897 { |
940 x_pos.push_back (elts[i]->relative_coordinate (x_common, X_AXIS)); | 898 x_pos.push_back (elts[i]->relative_coordinate (x_common, X_AXIS)); |
941 y_pos.push_back (elts[i]->maybe_pure_coordinate (y_common, Y_AXIS, pure, b
eg, end)); | 899 y_pos.push_back (elts[i]->maybe_pure_coordinate (y_common, Y_AXIS, pure, b
eg, end)); |
942 } | 900 } |
943 Real my_x = me->relative_coordinate (x_common, X_AXIS); | 901 Real my_x = me->relative_coordinate (x_common, X_AXIS); |
944 Real my_y = me->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end); | 902 Real my_y = me->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end); |
945 | 903 |
946 Skyline_pair res; | 904 Skyline_pair res; |
947 for (vsize i = 0; i < elts.size (); i++) | 905 for (vsize i = 0; i < elts.size (); i++) |
948 { | 906 { |
949 Skyline_pair *skyp = unsmob<Skyline_pair> (elts[i]->get_maybe_pure_propert
y (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines", pure, beg, end)); | 907 Skyline_pair *skyp = unsmob<Skyline_pair> (get_maybe_pure_property (elts[i
], a == X_AXIS ? "vertical-skylines" : "horizontal-skylines", pure, beg, end)); |
950 if (skyp) | 908 if (skyp) |
951 { | 909 { |
952 /* | 910 /* |
953 Here, copying is essential. Otherwise, the skyline pair will | 911 Here, copying is essential. Otherwise, the skyline pair will |
954 get doubly shifted! | 912 get doubly shifted! |
955 */ | 913 */ |
| 914 Skyline_pair copy = Skyline_pair (*skyp); |
956 /* | 915 /* |
957 It took Mike about 6 months of his life to add the `else' clause | 916 It took Mike about 6 months of his life to flip the |
958 below. For horizontal skylines, the raise and shift calls need | 917 coordinates below. This is what was causing the problems |
959 to be reversed. This is what was causing the problems in the | 918 in the shifting with all of the tests. RIP 6 months! |
960 shifting with all of the tests. RIP 6 months! | |
961 */ | 919 */ |
962 Skyline_pair copy = Skyline_pair (*skyp); | 920 Offset off (x_pos[i] - my_x, y_pos[i] - my_y); |
963 if (a == X_AXIS) | 921 copy.shift (off[a]); |
964 { | 922 copy.raise (off[other_axis (a)]); |
965 copy.shift (x_pos[i] - my_x); | |
966 copy.raise (y_pos[i] - my_y); | |
967 } | |
968 else | |
969 { | |
970 copy.raise (x_pos[i] - my_x); | |
971 copy.shift (y_pos[i] - my_y); | |
972 } | |
973 res.merge (copy); | 923 res.merge (copy); |
974 } | 924 } |
975 } | 925 } |
976 return res.smobbed_copy (); | 926 return res.smobbed_copy (); |
977 } | 927 } |
978 | 928 |
979 MAKE_SCHEME_CALLBACK (Grob, vertical_skylines_from_element_stencils, 1); | 929 MAKE_SCHEME_CALLBACK (Grob, vertical_skylines_from_element_stencils, 1); |
980 SCM | 930 SCM |
981 Grob::vertical_skylines_from_element_stencils (SCM smob) | 931 Grob::vertical_skylines_from_element_stencils (SCM smob) |
982 { | 932 { |
(...skipping 21 matching lines...) Expand all Loading... |
1004 | 954 |
1005 MAKE_SCHEME_CALLBACK (Grob, pure_horizontal_skylines_from_element_stencils, 3); | 955 MAKE_SCHEME_CALLBACK (Grob, pure_horizontal_skylines_from_element_stencils, 3); |
1006 SCM | 956 SCM |
1007 Grob::pure_horizontal_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM
end_scm) | 957 Grob::pure_horizontal_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM
end_scm) |
1008 { | 958 { |
1009 Grob *me = unsmob<Grob> (smob); | 959 Grob *me = unsmob<Grob> (smob); |
1010 int beg = robust_scm2int (beg_scm, 0); | 960 int beg = robust_scm2int (beg_scm, 0); |
1011 int end = robust_scm2int (end_scm, 0); | 961 int end = robust_scm2int (end_scm, 0); |
1012 return internal_skylines_from_element_stencils (me, Y_AXIS, true, beg, end); | 962 return internal_skylines_from_element_stencils (me, Y_AXIS, true, beg, end); |
1013 } | 963 } |
LEFT | RIGHT |