+ vector_sort (fingerings, pure_position_less);
+
+ vector<Real> shift(fingerings.size());
+
+ // Try stacking the fingerings top-to-bottom, and then bottom-to-top.
+ // Use the average of the resulting stacked locations as the final positions
+ for (UP_and_DOWN (d))
+ {
+ Real stack_end = -d * infinity_f;
+ Interval prev_x_ext;
+ for (vsize i = (d == UP)? 0 : fingerings.size() - 1;
+ i < fingerings.size ();
+ i += d)
+ {
+ Interval x_ext = fingerings[i]->extent(common[X_AXIS], X_AXIS);
+ Interval y_ext = fingerings[i]->extent(fingerings[i], Y_AXIS);
+ Real parent_y = fingerings[i]->get_parent(Y_AXIS)
+ ->relative_coordinate(common[Y_AXIS], Y_AXIS);
+
+ // Checking only between sequential neighbors, seems good enough
+ if (!intersection(x_ext, prev_x_ext).is_empty())
+ stack_end += d * (y_ext.length() + padding);
+ // minmax() returns whichever is further along in direction d
+ stack_end = minmax(d, stack_end, parent_y);
+
+ shift[i] += 0.5 * (stack_end - y_ext[d] - parent_y);
+
+ prev_x_ext = x_ext;
+ }
+ }