+static Skyline
+build_heads_skyline (vector<Grob *> const &heads_and_stems,
+ Grob **common)
+{
+ vector<Box> head_extents;
+ for (vsize i = heads_and_stems.size (); i--;)
+ head_extents.push_back (Box (heads_and_stems[i]->extent (common[X_AXIS], X_AXIS),
+ heads_and_stems[i]->pure_y_extent (common[Y_AXIS], 0, INT_MAX)));
+
+ return Skyline (head_extents, Y_AXIS, LEFT);
+}
+
+/*
+ Position the apes, starting from the right, so that they don't collide.
+ Return the total width.
+*/
+static Interval
+position_apes (Grob *me,
+ vector<Accidental_placement_entry *> const &apes,
+ Skyline const &heads_skyline)
+{
+ Real padding = robust_scm2double (me->get_property ("padding"), 0.2);
+ Skyline left_skyline = heads_skyline;
+ left_skyline.raise (-robust_scm2double (me->get_property ("right-padding"), 0));
+
+ /*
+ Add accs entries right-to-left.
+ */
+ Interval width;
+ Real last_offset = 0.0;
+ for (vsize i = apes.size (); i-- > 0;)
+ {
+ Accidental_placement_entry *ape = apes[i];
+
+ Real offset = -ape->horizontal_skylines_[RIGHT]
+ .distance (left_skyline, 0.1);
+ if (isinf (offset))
+ offset = last_offset;
+ else
+ offset -= padding;
+
+ Skyline new_left_skyline = ape->horizontal_skylines_[LEFT];
+ new_left_skyline.raise (offset);
+ new_left_skyline.merge (left_skyline);
+ left_skyline = new_left_skyline;
+
+ /* Shift all of the accidentals in this ape */
+ for (vsize j = ape->grobs_.size (); j--;)
+ ape->grobs_[j]->translate_axis (offset, X_AXIS);
+
+ for (LEFT_and_RIGHT (d))
+ {
+ Real mh = ape->horizontal_skylines_[d].max_height ();
+ if (!isinf (mh))
+ width.add_point (mh + offset);
+ }
+
+ last_offset = offset;
+ }
+
+ return width;
+}