2 slur-scoring.cc -- Score based slur formatting
4 source file of the GNU LilyPond music typesetter
6 (c) 1996--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
12 #include "slur-scoring.hh"
13 #include "libc-extension.hh"
14 #include "slur-configuration.hh"
16 #include "directional-element-interface.hh"
17 #include "pointer-group-interface.hh"
19 #include "note-column.hh"
20 #include "output-def.hh"
23 #include "staff-symbol-referencer.hh"
24 #include "staff-symbol.hh"
27 #include "paper-column.hh"
28 #include "accidental-interface.hh"
33 - curve around flag for y coordinate
35 - short-cut: try a smaller region first.
37 - handle non-visible stems better.
39 - try to prune number of scoring criteria
41 - take encompass-objects more into account when determining
44 - calculate encompass scoring directly after determining slur shape.
48 struct Slur_score_state
;
50 Slur_score_state::Slur_score_state ()
54 edge_has_beams_
= false;
55 has_same_beam_
= false;
63 Slur_score_state::~Slur_score_state ()
65 junk_pointers (configurations_
);
69 get_detail (SCM alist
, SCM sym
)
71 SCM entry
= scm_assq (sym
, alist
);
72 return robust_scm2double (scm_is_pair (entry
)
79 Slur_score_parameters::fill (Grob
*me
)
81 SCM details
= me
->get_property ("slur-details");
84 = (int) get_detail (details
, ly_symbol2scm ("region-size"));
85 head_encompass_penalty_
86 = get_detail (details
, ly_symbol2scm ("head-encompass-penalty"));
87 stem_encompass_penalty_
88 = get_detail (details
, ly_symbol2scm ("stem-encompass-penalty"));
90 = get_detail (details
, ly_symbol2scm ("closeness-factor"));
91 edge_attraction_factor_
92 = get_detail (details
, ly_symbol2scm ("edge-attraction-factor"));
94 = get_detail (details
, ly_symbol2scm ("same-slope-penalty"));
96 = get_detail (details
, ly_symbol2scm ("steeper-slope-factor"));
97 non_horizontal_penalty_
98 = get_detail (details
, ly_symbol2scm ("non-horizontal-penalty"));
100 = get_detail (details
, ly_symbol2scm ("max-slope"));
102 = get_detail (details
, ly_symbol2scm ("max-slope-factor"));
104 = get_detail (details
, ly_symbol2scm ("free-head-distance"));
105 absolute_closeness_measure_
106 = get_detail (details
, ly_symbol2scm ("absolute-closeness-measure"));
107 extra_object_collision_
108 = get_detail (details
, ly_symbol2scm ("extra-object-collision"));
109 accidental_collision_
110 = get_detail (details
, ly_symbol2scm ("accidental-collision"));
111 extra_encompass_free_distance_
112 = get_detail (details
, ly_symbol2scm ("extra-encompass-free-distance"));
113 head_slur_distance_factor_
114 = get_detail (details
, ly_symbol2scm ("head-slur-distance-factor"));
115 head_slur_distance_max_ratio_
116 = get_detail (details
, ly_symbol2scm ("head-slur-distance-max-ratio"));
118 = get_detail (details
, ly_symbol2scm ("free-slur-distance"));
120 = get_detail (details
, ly_symbol2scm ("edge-slope-exponent"));
124 broken_trend_y (Slur_score_state
const &state
, Direction hdir
)
126 /* A broken slur should maintain the same vertical trend
127 the unbroken slur would have had. */
129 if (Spanner
*mother
= dynamic_cast<Spanner
*> (state
.slur_
->original_
))
131 int k
= broken_spanner_index (state
.slur_
);
133 if (j
< 0 || j
>= mother
->broken_intos_
.size ())
136 Grob
*neighbor
= mother
->broken_intos_
[j
];
137 Spanner
*common_mother
138 = dynamic_cast<Spanner
*> (state
.common_
[Y_AXIS
]->original_
);
140 = broken_spanner_index (dynamic_cast<Spanner
*> (state
.common_
[Y_AXIS
]));
141 int common_j
= common_k
+ hdir
;
143 if (common_j
< 0 || common_j
>= common_mother
->broken_intos_
.size ())
146 Grob
*common_next_system
= common_mother
->broken_intos_
[common_j
];
148 SCM last_point
= scm_car (scm_last_pair (neighbor
->get_property ("control-points")));
150 return scm_to_double (scm_cdr (last_point
))
151 + neighbor
->relative_coordinate (common_next_system
, Y_AXIS
);
157 copy slur dir forwards across line break.
160 Slur_score_state::set_next_direction ()
162 if (extremes_
[RIGHT
].note_column_
)
165 if (Spanner
*mother
= dynamic_cast<Spanner
*> (slur_
->original_
))
167 int k
= broken_spanner_index (slur_
);
169 if (j
< 0 || j
>= mother
->broken_intos_
.size ())
172 Grob
*neighbor
= mother
->broken_intos_
[j
];
173 set_grob_direction (neighbor
, dir_
);
178 Slur_score_state::get_encompass_info (Grob
*col
) const
180 Grob
*stem
= unsmob_grob (col
->get_object ("stem"));
185 programming_error ("no stem for note column");
186 ei
.x_
= col
->relative_coordinate (common_
[X_AXIS
], X_AXIS
);
187 ei
.head_
= ei
.stem_
= col
->extent (common_
[Y_AXIS
],
191 Direction stem_dir
= get_grob_direction (stem
);
193 if (Grob
*head
= Note_column::first_head (col
))
194 ei
.x_
= head
->extent (common_
[X_AXIS
], X_AXIS
).center ();
196 ei
.x_
= col
->extent (common_
[X_AXIS
], X_AXIS
).center ();
198 Grob
*h
= Stem::extremal_heads (stem
)[Direction (dir_
)];
201 ei
.head_
= ei
.stem_
= col
->extent (common_
[Y_AXIS
], Y_AXIS
)[dir_
];
205 ei
.head_
= h
->extent (common_
[Y_AXIS
], Y_AXIS
)[dir_
];
207 if ((stem_dir
== dir_
)
208 && !stem
->extent (stem
, Y_AXIS
).is_empty ())
210 ei
.stem_
= stem
->extent (common_
[Y_AXIS
], Y_AXIS
)[dir_
];
211 if (Grob
*b
= Stem::get_beam (stem
))
212 ei
.stem_
+= stem_dir
* 0.5 * Beam::get_thickness (b
);
214 Interval x
= stem
->extent (common_
[X_AXIS
], X_AXIS
);
215 ei
.x_
= x
.is_empty ()
216 ? stem
->relative_coordinate (common_
[X_AXIS
], X_AXIS
)
225 Drul_array
<Bound_info
>
226 Slur_score_state::get_bound_info () const
228 Drul_array
<Bound_info
> extremes
;
231 Direction dir
= dir_
;
235 extremes
[d
].bound_
= slur_
->get_bound (d
);
236 if (Note_column::has_interface (extremes
[d
].bound_
))
238 extremes
[d
].note_column_
= extremes
[d
].bound_
;
239 extremes
[d
].stem_
= Note_column::get_stem (extremes
[d
].note_column_
);
240 extremes
[d
].stem_dir_
= get_grob_direction (extremes
[d
].stem_
);
242 for (int a
= X_AXIS
; a
< NO_AXES
; a
++)
245 Interval s
= extremes
[d
].stem_
->extent (common_
[ax
], ax
);
249 do not issue warning. This happens for rests and
253 + extremes
[d
].stem_
->relative_coordinate (common_
[ax
], ax
);
255 extremes
[d
].stem_extent_
[ax
] = s
;
258 extremes
[d
].slur_head_
259 = Stem::extremal_heads (extremes
[d
].stem_
)[dir
];
260 if (!extremes
[d
].slur_head_
261 && Note_column::has_rests (extremes
[d
].bound_
))
262 extremes
[d
].slur_head_
= Note_column::get_rest (extremes
[d
].bound_
);
264 if (extremes
[d
].slur_head_
)
265 extremes
[d
].slur_head_extent_
266 = extremes
[d
].slur_head_
->extent (common_
[X_AXIS
], X_AXIS
);
268 extremes
[d
].staff_
= Staff_symbol_referencer
269 ::get_staff_symbol (extremes
[d
].stem_
);
270 extremes
[d
].staff_space_
= Staff_symbol_referencer
271 ::staff_space (extremes
[d
].stem_
);
274 while (flip (&d
) != LEFT
);
280 Slur_score_state::fill (Grob
*me
)
282 slur_
= dynamic_cast<Spanner
*> (me
);
284 = internal_extract_grob_array (me
, ly_symbol2scm ("note-columns"));
286 if (columns_
.is_empty ())
292 staff_space_
= Staff_symbol_referencer::staff_space (me
);
293 Real lt
= me
->get_layout ()->get_dimension (ly_symbol2scm ("linethickness"));
294 thickness_
= robust_scm2double (me
->get_property ("thickness"), 1.0) * lt
;
296 dir_
= get_grob_direction (me
);
297 parameters_
.fill (me
);
299 extract_grob_set (me
, "note-columns", columns
);
300 extract_grob_set (me
, "encompass-objects", extra_objects
);
302 Spanner
*sp
= dynamic_cast<Spanner
*> (me
);
304 for (int i
= X_AXIS
; i
< NO_AXES
; i
++)
307 common_
[a
] = common_refpoint_of_array (columns
, me
, a
);
308 common_
[a
] = common_refpoint_of_array (extra_objects
, common_
[a
], a
);
314 If bound is not in note-columns, we don't want to know about
318 common_
[a
] = common_
[a
]->common_refpoint (sp
->get_bound (d
), a
);
320 while (flip (&d
) != LEFT
);
323 extremes_
= get_bound_info ();
324 is_broken_
= (!extremes_
[LEFT
].note_column_
325 || !extremes_
[RIGHT
].note_column_
);
328 = (extremes_
[LEFT
].stem_
&& extremes_
[RIGHT
].stem_
329 && Stem::get_beam (extremes_
[LEFT
].stem_
) == Stem::get_beam (extremes_
[RIGHT
].stem_
));
331 base_attachments_
= get_base_attachments ();
333 Drul_array
<Real
> end_ys
334 = get_y_attachment_range ();
336 configurations_
= enumerate_attachments (end_ys
);
337 for (int i
= 0; i
< columns_
.size (); i
++)
338 encompass_infos_
.push (get_encompass_info (columns_
[i
]));
340 extra_encompass_infos_
= get_extra_encompass_infos ();
349 * extremes_
[d
].slur_head_
->relative_coordinate (common_
[Y_AXIS
], Y_AXIS
);
351 while (flip (&d
) != LEFT
);
354 = (extremes_
[LEFT
].stem_
&& Stem::get_beam (extremes_
[LEFT
].stem_
))
355 || (extremes_
[RIGHT
].stem_
&& Stem::get_beam (extremes_
[RIGHT
].stem_
));
357 set_next_direction ();
364 set_slur_control_points (Grob
*me
)
366 Slur_score_state state
;
372 state
.generate_curves ();
374 SCM end_ys
= me
->get_property ("positions");
377 if (is_number_pair (end_ys
))
378 best
= state
.configurations_
[state
.get_closest_index (end_ys
)]->curve_
;
380 best
= state
.get_best_curve ();
382 SCM controls
= SCM_EOL
;
383 for (int i
= 4; i
--;)
385 Offset o
= best
.control_
[i
]
386 - Offset (me
->relative_coordinate (state
.common_
[X_AXIS
], X_AXIS
),
387 me
->relative_coordinate (state
.common_
[Y_AXIS
], Y_AXIS
));
388 controls
= scm_cons (ly_offset2scm (o
), controls
);
390 me
->set_property ("control-points", controls
);
394 Slur_score_state::get_best_curve ()
399 #if DEBUG_SLUR_SCORING
400 SCM inspect_quants
= slur_
->get_property ("inspect-quants");
401 if (to_boolean (slur_
->get_layout ()
402 ->lookup_variable (ly_symbol2scm ("debug-slur-scoring")))
403 && scm_is_pair (inspect_quants
))
405 opt_idx
= get_closest_index (inspect_quants
);
406 configurations_
[opt_idx
]->score (*this);
407 opt
= configurations_
[opt_idx
]->score_
;
412 for (int i
= 0; i
< configurations_
.size (); i
++)
413 configurations_
[i
]->score (*this);
414 for (int i
= 0; i
< configurations_
.size (); i
++)
416 if (configurations_
[i
]->score_
< opt
)
418 opt
= configurations_
[i
]->score_
;
424 #if DEBUG_SLUR_SCORING
425 configurations_
[opt_idx
]->score_card_
+= to_string ("=%.2f", opt
);
426 configurations_
[opt_idx
]->score_card_
+= to_string ("i%d", opt_idx
);
429 slur_
->set_property ("quant-score",
430 scm_makfrom0str (configurations_
[opt_idx
]->score_card_
.to_str0 ()));
434 return configurations_
[opt_idx
]->curve_
;
438 Slur_score_state::get_closest_index (SCM inspect_quants
) const
440 Drul_array
<Real
> ins
= ly_scm2interval (inspect_quants
);
444 for (int i
= 0; i
< configurations_
.size (); i
++)
446 Real d
= fabs (configurations_
[i
]->attachment_
[LEFT
][Y_AXIS
] - ins
[LEFT
])
447 + fabs (configurations_
[i
]->attachment_
[RIGHT
][Y_AXIS
] - ins
[RIGHT
]);
455 programming_error ("can't not find quant");
460 TODO: should analyse encompasses to determine sensible region, and
461 should limit slopes available.
465 Slur_score_state::get_y_attachment_range () const
467 Drul_array
<Real
> end_ys
;
471 if (extremes_
[d
].note_column_
)
474 * max (max (dir_
* (base_attachments_
[d
][Y_AXIS
] + parameters_
.region_size_
* dir_
),
475 dir_
* (dir_
+ extremes_
[d
].note_column_
->extent (common_
[Y_AXIS
], Y_AXIS
)[dir_
])),
476 dir_
* base_attachments_
[-d
][Y_AXIS
]);
479 end_ys
[d
] = base_attachments_
[d
][Y_AXIS
] + parameters_
.region_size_
* dir_
;
481 while (flip (&d
) != LEFT
);
487 spanner_less (Spanner
*s1
, Spanner
*s2
)
493 b1
[d
] = s1
->get_bound (d
)->get_column ()->get_rank ();
494 b2
[d
] = s2
->get_bound (d
)->get_column ()->get_rank ();
496 while (flip (&d
) != LEFT
);
498 return b2
[LEFT
] <= b1
[LEFT
] && b2
[RIGHT
] >= b1
[RIGHT
]
499 && (b2
[LEFT
] != b1
[LEFT
] || b2
[RIGHT
] != b1
[RIGHT
]);
503 Slur_score_state::get_base_attachments () const
505 Drul_array
<Offset
> base_attachment
;
509 Grob
*stem
= extremes_
[d
].stem_
;
510 Grob
*head
= extremes_
[d
].slur_head_
;
514 if (extremes_
[d
].note_column_
)
518 fixme: X coord should also be set in this case.
521 && !Stem::is_invisible (stem
)
522 && extremes_
[d
].stem_dir_
== dir_
523 && Stem::get_beaming (stem
, -d
)
524 && (!spanner_less (slur_
, Stem::get_beam (stem
))
526 y
= extremes_
[d
].stem_extent_
[Y_AXIS
][dir_
];
528 y
= head
->extent (common_
[Y_AXIS
], Y_AXIS
)[dir_
];
529 y
+= dir_
* 0.5 * staff_space_
;
531 y
= move_away_from_staffline (y
, head
);
533 Grob
*fh
= Note_column::first_head (extremes_
[d
].note_column_
);
535 = (fh
? fh
->extent (common_
[X_AXIS
], X_AXIS
)
536 : extremes_
[d
].bound_
->extent (common_
[X_AXIS
], X_AXIS
))
537 .linear_combination (CENTER
);
539 base_attachment
[d
] = Offset (x
, y
);
541 while (flip (&d
) != LEFT
);
545 if (!extremes_
[d
].note_column_
)
549 x
= extremes_
[d
].bound_
->extent (common_
[X_AXIS
], X_AXIS
)[d
];
551 x
= slur_
->get_broken_left_end_align ();
552 Grob
*col
= (d
== LEFT
) ? columns_
[0] : columns_
.top ();
554 if (extremes_
[-d
].bound_
!= col
)
556 y
= robust_relative_extent (col
, common_
[Y_AXIS
], Y_AXIS
)[dir_
];
557 y
+= dir_
* 0.5 * staff_space_
;
559 if (get_grob_direction (col
) == dir_
560 && Note_column::get_stem (col
)
561 && !Stem::is_invisible (Note_column::get_stem (col
)))
562 y
-= dir_
* 1.5 * staff_space_
;
565 y
= base_attachment
[-d
][Y_AXIS
];
567 y
= move_away_from_staffline (y
, col
);
569 base_attachment
[d
] = Offset (x
, y
);
572 while (flip (&d
) != LEFT
);
576 for (int a
= X_AXIS
; a
< NO_AXES
; a
++)
578 Real
&b
= base_attachment
[d
][Axis (a
)];
580 if (isinf (b
) || isnan (b
))
582 programming_error ("slur attachment is inf/nan");
587 while (flip (&d
) != LEFT
);
589 return base_attachment
;
593 Slur_score_state::move_away_from_staffline (Real y
,
594 Grob
*on_staff
) const
596 Grob
*staff_symbol
= Staff_symbol_referencer::get_staff_symbol (on_staff
);
601 = (y
- staff_symbol
->relative_coordinate (common_
[Y_AXIS
],
603 * 2.0 / staff_space_
;
605 if (fabs (pos
- my_round (pos
)) < 0.2
606 && Staff_symbol_referencer::on_staffline (on_staff
, (int) rint (pos
))
607 && Staff_symbol_referencer::line_count (on_staff
) - 1 >= rint (pos
))
608 y
+= 1.5 * staff_space_
* dir_
/ 10;
614 Slur_score_state::generate_avoid_offsets () const
617 Link_array
<Grob
> encompasses
= columns_
;
619 for (int i
= 0; i
< encompasses
.size (); i
++)
621 if (extremes_
[LEFT
].note_column_
== encompasses
[i
]
622 || extremes_
[RIGHT
].note_column_
== encompasses
[i
])
625 Encompass_info
inf (get_encompass_info (encompasses
[i
]));
626 Real y
= dir_
* (max (dir_
* inf
.head_
, dir_
* inf
.stem_
));
628 avoid
.push (Offset (inf
.x_
, y
+ dir_
* parameters_
.free_head_distance_
));
631 extract_grob_set (slur_
, "encompass-objects", extra_encompasses
);
632 for (int i
= 0; i
< extra_encompasses
.size (); i
++)
633 if (Slur::has_interface (extra_encompasses
[i
]))
635 Grob
*small_slur
= extra_encompasses
[i
];
636 Bezier b
= Slur::get_curve (small_slur
);
638 Offset z
= b
.curve_point (0.5);
639 z
+= Offset (small_slur
->relative_coordinate (common_
[X_AXIS
], X_AXIS
),
640 small_slur
->relative_coordinate (common_
[Y_AXIS
], Y_AXIS
));
642 z
[Y_AXIS
] += dir_
* parameters_
.free_slur_distance_
;
650 Slur_score_state::generate_curves () const
652 Real r_0
= robust_scm2double (slur_
->get_property ("ratio"), 0.33);
653 Real h_inf
= staff_space_
* scm_to_double (slur_
->get_property ("height-limit"));
655 Array
<Offset
> avoid
= generate_avoid_offsets ();
656 for (int i
= 0; i
< configurations_
.size (); i
++)
657 configurations_
[i
]->generate_curve (*this, r_0
, h_inf
, avoid
);
660 Link_array
<Slur_configuration
>
661 Slur_score_state::enumerate_attachments (Drul_array
<Real
> end_ys
) const
663 Link_array
<Slur_configuration
> scores
;
665 Drul_array
<Offset
> os
;
666 os
[LEFT
] = base_attachments_
[LEFT
];
667 Real minimum_length
= staff_space_
668 * robust_scm2double (slur_
->get_property ("minimum-length"), 2.0);
670 for (int i
= 0; dir_
* os
[LEFT
][Y_AXIS
] <= dir_
* end_ys
[LEFT
]; i
++)
672 os
[RIGHT
] = base_attachments_
[RIGHT
];
673 for (int j
= 0; dir_
* os
[RIGHT
][Y_AXIS
] <= dir_
* end_ys
[RIGHT
]; j
++)
675 Slur_configuration s
;
677 Drul_array
<bool> attach_to_stem (false, false);
680 os
[d
][X_AXIS
] = base_attachments_
[d
][X_AXIS
];
681 if (extremes_
[d
].stem_
682 && !Stem::is_invisible (extremes_
[d
].stem_
)
683 && extremes_
[d
].stem_dir_
== dir_
)
685 Interval stem_y
= extremes_
[d
].stem_extent_
[Y_AXIS
];
686 stem_y
.widen (0.25 * staff_space_
);
687 if (stem_y
.contains (os
[d
][Y_AXIS
]))
689 os
[d
][X_AXIS
] = extremes_
[d
].stem_extent_
[X_AXIS
][-d
]
691 attach_to_stem
[d
] = true;
693 else if (dir_
* extremes_
[d
].stem_extent_
[Y_AXIS
][dir_
]
694 < dir_
* os
[d
][Y_AXIS
]
695 && !extremes_
[d
].stem_extent_
[X_AXIS
].is_empty ())
697 os
[d
][X_AXIS
] = extremes_
[d
].stem_extent_
[X_AXIS
].center ();
700 while (flip (&d
) != LEFT
);
703 dz
= os
[RIGHT
] - os
[LEFT
];
704 if (dz
[X_AXIS
] < minimum_length
705 || fabs (dz
[Y_AXIS
] / dz
[X_AXIS
]) > parameters_
.max_slope_
)
709 if (extremes_
[d
].slur_head_
)
711 os
[d
][X_AXIS
] = extremes_
[d
].slur_head_extent_
.center ();
712 attach_to_stem
[d
] = false;
715 while (flip (&d
) != LEFT
);
718 dz
= os
[RIGHT
] - os
[LEFT
];
721 if (extremes_
[d
].slur_head_
722 && !attach_to_stem
[d
])
724 /* Horizontally move tilted slurs a little. Move
725 more for bigger tilts.
729 -= dir_
* extremes_
[d
].slur_head_extent_
.length ()
730 * sin (dz
.arg ()) / 3;
733 while (flip (&d
) != LEFT
);
736 s
.index_
= scores
.size ();
738 scores
.push (new Slur_configuration (s
));
740 os
[RIGHT
][Y_AXIS
] += dir_
* staff_space_
/ 2;
743 os
[LEFT
][Y_AXIS
] += dir_
* staff_space_
/ 2;
746 assert (scores
.size () > 0);
750 Array
<Extra_collision_info
>
751 Slur_score_state::get_extra_encompass_infos () const
753 extract_grob_set (slur_
, "encompass-objects", encompasses
);
754 Array
<Extra_collision_info
> collision_infos
;
755 for (int i
= encompasses
.size (); i
--;)
757 if (Slur::has_interface (encompasses
[i
]))
759 Spanner
*small_slur
= dynamic_cast<Spanner
*> (encompasses
[i
]);
760 Bezier b
= Slur::get_curve (small_slur
);
762 Offset
relative (small_slur
->relative_coordinate (common_
[X_AXIS
], X_AXIS
),
763 small_slur
->relative_coordinate (common_
[Y_AXIS
], Y_AXIS
));
765 for (int k
= 0; k
< 3; k
++)
767 Direction hdir
= Direction (k
/ 2 - 1);
770 Only take bound into account if small slur starts
771 together with big slur.
773 if (hdir
&& small_slur
->get_bound (hdir
) != slur_
->get_bound (hdir
))
776 Offset z
= b
.curve_point (k
/ 2.0);
781 yext
[dir_
] = z
[Y_AXIS
] + dir_
* thickness_
* 1.0;
783 Interval
xext (-1, 1);
784 xext
= xext
* (thickness_
* 2) + z
[X_AXIS
];
785 Extra_collision_info
info (small_slur
,
789 parameters_
.extra_object_collision_
);
790 collision_infos
.push (info
);
795 Grob
*g
= encompasses
[i
];
796 Interval xe
= g
->extent (common_
[X_AXIS
], X_AXIS
);
797 Interval ye
= g
->extent (common_
[Y_AXIS
], Y_AXIS
);
800 Real penalty
= parameters_
.extra_object_collision_
;
801 if (Accidental_interface::has_interface (g
))
803 penalty
= parameters_
.accidental_collision_
;
804 /* Begin copy accidental.cc */
806 if (to_boolean (g
->get_property ("cautionary")))
808 SCM cstyle
= g
->get_property ("cautionary-style");
809 parens
= ly_is_equal (cstyle
, ly_symbol2scm ("parentheses"));
812 SCM accs
= g
->get_property ("accidentals");
813 SCM scm_style
= g
->get_property ("style");
814 if (!scm_is_symbol (scm_style
)
816 && scm_ilength (accs
) == 1)
818 /* End copy accidental.cc */
819 switch (scm_to_int (scm_car (accs
)))
835 ye
.widen (thickness_
* 0.5);
836 xe
.widen (thickness_
* 1.0);
837 Extra_collision_info
info (g
, xp
, xe
, ye
, penalty
);
838 collision_infos
.push (info
);
842 return collision_infos
;