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--2012 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1996--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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 if (common_refpoint_of_array (encompasses, me, Y_AXIS) != parent) | 94 if (common_refpoint_of_array (encompasses, me, Y_AXIS) != parent) |
95 /* this could happen if, for example, we are a cross-staff slur. | 95 /* this could happen if, for example, we are a cross-staff slur. |
96 in this case, we want to be ignored */ | 96 in this case, we want to be ignored */ |
97 return ly_interval2scm (Interval ()); | 97 return ly_interval2scm (Interval ()); |
98 | 98 |
99 for (vsize i = 0; i < encompasses.size (); i++) | 99 for (vsize i = 0; i < encompasses.size (); i++) |
100 { | 100 { |
101 Interval d = encompasses[i]->pure_height (parent, start, end); | 101 Interval d = encompasses[i]->pure_height (parent, start, end); |
102 if (!d.is_empty ()) | 102 if (!d.is_empty ()) |
103 { | 103 { |
104 Direction downup = DOWN; | 104 for (DOWN_and_UP (downup)) |
105 do | |
106 ret.add_point (d[dir]); | 105 ret.add_point (d[dir]); |
107 while (flip (&downup) != DOWN); | |
108 | 106 |
109 if (extremal_heights[LEFT] == infinity_f) | 107 if (extremal_heights[LEFT] == infinity_f) |
110 extremal_heights[LEFT] = d[dir]; | 108 extremal_heights[LEFT] = d[dir]; |
111 extremal_heights[RIGHT] = d[dir]; | 109 extremal_heights[RIGHT] = d[dir]; |
112 } | 110 } |
113 } | 111 } |
114 | 112 |
115 if (ret.is_empty ()) | 113 if (ret.is_empty ()) |
116 return ly_interval2scm (Interval ()); | 114 return ly_interval2scm (Interval ()); |
117 | 115 |
118 Interval extremal_span; | 116 Interval extremal_span; |
119 extremal_span.set_empty (); | 117 extremal_span.set_empty (); |
120 Direction d = LEFT; | 118 for (LEFT_and_RIGHT (d)) |
121 do | |
122 extremal_span.add_point (extremal_heights[d]); | 119 extremal_span.add_point (extremal_heights[d]); |
123 while (flip (&d) != LEFT); | |
124 ret[-dir] = minmax (dir, extremal_span[-dir], ret[-dir]); | 120 ret[-dir] = minmax (dir, extremal_span[-dir], ret[-dir]); |
125 | 121 |
126 /* | 122 /* |
127 The +0.5 comes from the fact that we try to place a slur | 123 The +0.5 comes from the fact that we try to place a slur |
128 0.5 staff spaces from the note-head. | 124 0.5 staff spaces from the note-head. |
129 (see Slur_score_state.get_base_attachments ()) | 125 (see Slur_score_state.get_base_attachments ()) |
130 */ | 126 */ |
131 ret += 0.5 * dir; | 127 ret += 0.5 * dir; |
132 return ly_interval2scm (ret); | 128 return ly_interval2scm (ret); |
133 } | 129 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 Interval slur_wid (curve.control_[0][X_AXIS], curve.control_[3][X_AXIS]); | 303 Interval slur_wid (curve.control_[0][X_AXIS], curve.control_[3][X_AXIS]); |
308 | 304 |
309 /* | 305 /* |
310 cannot use is_empty because some 0-extent scripts | 306 cannot use is_empty because some 0-extent scripts |
311 come up with TabStaffs. | 307 come up with TabStaffs. |
312 */ | 308 */ |
313 if (xext.length () <= 0 || yext.length () <= 0) | 309 if (xext.length () <= 0 || yext.length () <= 0) |
314 return offset_scm; | 310 return offset_scm; |
315 | 311 |
316 bool contains = false; | 312 bool contains = false; |
317 Direction d = LEFT; | 313 for (LEFT_and_RIGHT (d)) |
318 do | |
319 contains |= slur_wid.contains (xext[d]); | 314 contains |= slur_wid.contains (xext[d]); |
320 while (flip (&d) != LEFT); | |
321 | 315 |
322 if (!contains) | 316 if (!contains) |
323 return offset_scm; | 317 return offset_scm; |
324 | 318 |
325 Real offset = robust_scm2double (offset_scm, 0); | 319 Real offset = robust_scm2double (offset_scm, 0); |
326 yext.translate (offset); | 320 yext.translate (offset); |
327 | 321 |
328 /* FIXME: slur property, script property? */ | 322 /* FIXME: slur property, script property? */ |
329 Real slur_padding = robust_scm2double (script->get_property ("slur-padding"), | 323 Real slur_padding = robust_scm2double (script->get_property ("slur-padding"), |
330 0.0); | 324 0.0); |
331 yext.widen (slur_padding); | 325 yext.widen (slur_padding); |
332 | 326 |
333 Interval exts[] = {xext, yext}; | 327 Interval exts[] = {xext, yext}; |
334 bool do_shift = false; | 328 bool do_shift = false; |
335 Real EPS = 1.0e-5; | 329 Real EPS = 1.0e-5; |
336 if (avoid == ly_symbol2scm ("outside")) | 330 if (avoid == ly_symbol2scm ("outside")) |
337 { | 331 { |
338 Direction d = LEFT; | 332 for (LEFT_and_RIGHT (d)) |
339 do | |
340 { | 333 { |
341 Real x = minmax (-d, xext[d], curve.control_[d == LEFT ? 0 : 3][X_AXIS
] + -d * EPS); | 334 Real x = minmax (-d, xext[d], curve.control_[d == LEFT ? 0 : 3][X_AXIS
] + -d * EPS); |
342 Real y = curve.get_other_coordinate (X_AXIS, x); | 335 Real y = curve.get_other_coordinate (X_AXIS, x); |
343 do_shift = y == minmax (dir, yext[-dir], y); | 336 do_shift = y == minmax (dir, yext[-dir], y); |
344 if (do_shift) | 337 if (do_shift) |
345 break; | 338 break; |
346 } | 339 } |
347 while (flip (&d) != LEFT); | |
348 } | 340 } |
349 else | 341 else |
350 { | 342 { |
351 for (int a = X_AXIS; a < NO_AXES; a++) | 343 for (int a = X_AXIS; a < NO_AXES; a++) |
352 { | 344 { |
353 Direction d = LEFT; | 345 for (LEFT_and_RIGHT (d)) |
354 do | |
355 { | 346 { |
356 vector<Real> coords = curve.get_other_coordinates (Axis (a), exts[
a][d]); | 347 vector<Real> coords = curve.get_other_coordinates (Axis (a), exts[
a][d]); |
357 for (vsize i = 0; i < coords.size (); i++) | 348 for (vsize i = 0; i < coords.size (); i++) |
358 { | 349 { |
359 do_shift = exts[(a + 1) % NO_AXES].contains (coords[i]); | 350 do_shift = exts[(a + 1) % NO_AXES].contains (coords[i]); |
360 if (do_shift) | 351 if (do_shift) |
361 break; | 352 break; |
362 } | 353 } |
363 if (do_shift) | 354 if (do_shift) |
364 break; | 355 break; |
365 } | 356 } |
366 while (flip (&d) != LEFT); | |
367 if (do_shift) | 357 if (do_shift) |
368 break; | 358 break; |
369 } | 359 } |
370 } | 360 } |
371 | 361 |
372 Real avoidance_offset = do_shift ? curve.minmax (X_AXIS, max (xext[LEFT], curv
e.control_[0][X_AXIS] + EPS), min (xext[RIGHT], curve.control_[3][X_AXIS] - EPS)
, dir) - yext[-dir] : 0.0; | 362 Real avoidance_offset = do_shift ? curve.minmax (X_AXIS, max (xext[LEFT], curv
e.control_[0][X_AXIS] + EPS), min (xext[RIGHT], curve.control_[3][X_AXIS] - EPS)
, dir) - yext[-dir] : 0.0; |
373 | 363 |
374 return scm_from_double (offset + avoidance_offset); | 364 return scm_from_double (offset + avoidance_offset); |
375 } | 365 } |
376 | 366 |
377 MAKE_SCHEME_CALLBACK (Slur, vertical_skylines, 1); | 367 MAKE_SCHEME_CALLBACK (Slur, vertical_skylines, 1); |
378 SCM | 368 SCM |
379 Slur::vertical_skylines (SCM smob) | 369 Slur::vertical_skylines (SCM smob) |
380 { | 370 { |
381 Grob *me = unsmob_grob (smob); | 371 Grob *me = unsmob_grob (smob); |
382 vector<Box> boxes; | 372 vector<Box> boxes; |
383 | 373 |
384 if (!me) | 374 if (!me) |
385 return Skyline_pair (boxes, 0.0, X_AXIS).smobbed_copy (); | 375 return Skyline_pair (boxes, X_AXIS).smobbed_copy (); |
386 | 376 |
387 Bezier curve = Slur::get_curve (me); | 377 Bezier curve = Slur::get_curve (me); |
388 vsize box_count = robust_scm2vsize (me->get_property ("skyline-quantizing"), 1
0); | 378 vsize box_count = robust_scm2vsize (me->get_property ("skyline-quantizing"), 1
0); |
389 for (vsize i = 0; i < box_count; i++) | 379 for (vsize i = 0; i < box_count; i++) |
390 { | 380 { |
391 Box b; | 381 Box b; |
392 b.add_point (curve.curve_point (i * 1.0 / box_count)); | 382 b.add_point (curve.curve_point (i * 1.0 / box_count)); |
393 b.add_point (curve.curve_point ((i + 1) * 1.0 / box_count)); | 383 b.add_point (curve.curve_point ((i + 1) * 1.0 / box_count)); |
394 boxes.push_back (b); | 384 boxes.push_back (b); |
395 } | 385 } |
396 | 386 |
397 return Skyline_pair (boxes, 0.0, X_AXIS).smobbed_copy (); | 387 return Skyline_pair (boxes, X_AXIS).smobbed_copy (); |
398 } | 388 } |
399 | 389 |
400 /* | 390 /* |
401 * Used by Slur_engraver:: and Phrasing_slur_engraver:: | 391 * Used by Slur_engraver:: and Phrasing_slur_engraver:: |
402 */ | 392 */ |
403 void | 393 void |
404 Slur::auxiliary_acknowledge_extra_object (Grob_info const &info, | 394 Slur::auxiliary_acknowledge_extra_object (Grob_info const &info, |
405 vector<Grob *> &slurs, | 395 vector<Grob *> &slurs, |
406 vector<Grob *> &end_slurs) | 396 vector<Grob *> &end_slurs) |
407 { | 397 { |
408 if (slurs.empty () && end_slurs.empty ()) | 398 if (slurs.empty () && end_slurs.empty ()) |
409 return; | 399 return; |
410 | 400 |
411 Grob *e = info.grob (); | 401 Grob *e = info.grob (); |
412 SCM avoid = e->get_property ("avoid-slur"); | 402 SCM avoid = e->get_property ("avoid-slur"); |
| 403 Grob *slur; |
| 404 if (end_slurs.size () && !slurs.size ()) |
| 405 slur = end_slurs[0]; |
| 406 else |
| 407 slur = slurs[0]; |
| 408 |
413 if (Tie::has_interface (e) | 409 if (Tie::has_interface (e) |
414 || avoid == ly_symbol2scm ("inside")) | 410 || avoid == ly_symbol2scm ("inside")) |
415 { | 411 { |
416 for (vsize i = slurs.size (); i--;) | 412 for (vsize i = slurs.size (); i--;) |
417 add_extra_encompass (slurs[i], e); | 413 add_extra_encompass (slurs[i], e); |
418 for (vsize i = end_slurs.size (); i--;) | 414 for (vsize i = end_slurs.size (); i--;) |
419 add_extra_encompass (end_slurs[i], e); | 415 add_extra_encompass (end_slurs[i], e); |
| 416 if (slur) |
| 417 e->set_object ("slur", slur->self_scm ()); |
420 } | 418 } |
421 else if (avoid == ly_symbol2scm ("outside") | 419 else if (avoid == ly_symbol2scm ("outside") |
422 || avoid == ly_symbol2scm ("around")) | 420 || avoid == ly_symbol2scm ("around")) |
423 { | 421 { |
424 Grob *slur; | |
425 if (end_slurs.size () && !slurs.size ()) | |
426 slur = end_slurs[0]; | |
427 else | |
428 slur = slurs[0]; | |
429 | |
430 if (slur) | 422 if (slur) |
431 { | 423 { |
432 chain_offset_callback (e, outside_slur_callback_proc, Y_AXIS); | 424 chain_offset_callback (e, outside_slur_callback_proc, Y_AXIS); |
433 chain_callback (e, outside_slur_cross_staff_proc, ly_symbol2scm ("cros
s-staff")); | 425 chain_callback (e, outside_slur_cross_staff_proc, ly_symbol2scm ("cros
s-staff")); |
434 e->set_object ("slur", slur->self_scm ()); | 426 e->set_object ("slur", slur->self_scm ()); |
435 } | 427 } |
436 } | 428 } |
437 else if (avoid != ly_symbol2scm ("ignore")) | 429 else if (avoid != ly_symbol2scm ("ignore")) |
438 e->warning (_f ("Ignoring grob for slur: %s. avoid-slur not set?", | 430 e->warning (_f ("Ignoring grob for slur: %s. avoid-slur not set?", |
439 e->name ().c_str ())); | 431 e->name ().c_str ())); |
440 } | 432 } |
441 | 433 |
442 /* | 434 /* |
443 A callback that will be chained together with the original cross-staff | 435 A callback that will be chained together with the original cross-staff |
444 value of a grob that is placed 'outside or 'around a slur. This just says | 436 value of a grob that is placed 'outside or 'around a slur. This just says |
445 that any grob becomes cross-staff if it is placed 'outside or 'around a | 437 that any grob becomes cross-staff if it is placed 'outside or 'around a |
446 cross-staff slur. | 438 cross-staff slur. |
447 */ | 439 */ |
448 MAKE_SCHEME_CALLBACK (Slur, outside_slur_cross_staff, 2) | 440 MAKE_SCHEME_CALLBACK (Slur, outside_slur_cross_staff, 2) |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 "height-limit " | 560 "height-limit " |
569 "inspect-quants " | 561 "inspect-quants " |
570 "inspect-index " | 562 "inspect-index " |
571 "line-thickness " | 563 "line-thickness " |
572 "note-columns " | 564 "note-columns " |
573 "positions " | 565 "positions " |
574 "ratio " | 566 "ratio " |
575 "thickness " | 567 "thickness " |
576 ); | 568 ); |
577 | 569 |
LEFT | RIGHT |