+ /* FIXME: 1000 should relate to paper size. */
+ if (fabs (total_off) > 1000)
+ {
+ string msg
+ = String_convert::form_string ("Improbable offset for grob %s: %f",
+ me->name ().c_str (), total_off);
+
+ programming_error (msg);
+ if (strict_infinity_checking)
+ scm_misc_error (__FUNCTION__, "Improbable offset.", SCM_EOL);
+ }
+
+ /*
+ Ensure 'staff-padding' from my refpoint to the staff. This is similar to
+ side-position with padding, but it will put adjoining objects on a row if
+ stuff sticks out of the staff a little.
+ */
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (staff && a == Y_AXIS)
+ {
+ if (quantize_position)
+ {
+ Grob *common = me->common_refpoint (staff, Y_AXIS);
+ Real my_off = me->get_parent (Y_AXIS)->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
+ Real staff_off = staff->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
+ Real ss = Staff_symbol::staff_space (staff);
+ Real position = 2 * (my_off + total_off - staff_off) / ss;
+ Real rounded = directed_round (position, dir);
+ Grob *head = me->get_parent (X_AXIS);
+
+ Interval staff_span = Staff_symbol::line_span (staff);
+ staff_span.widen (1);
+ if (staff_span.contains (position)
+ /* In case of a ledger lines, quantize even if we're outside the staff. */
+ || (Note_head::has_interface (head)
+
+ && abs (Staff_symbol_referencer::get_position (head)) > abs (position)))
+ {
+ total_off += (rounded - position) * 0.5 * ss;
+ if (Staff_symbol_referencer::on_line (me, int (rounded)))
+ total_off += dir * 0.5 * ss;
+ }
+ }
+ else if (scm_is_number (me->get_maybe_pure_property ("staff-padding", pure, start, end)) && dir)
+ {
+ Real staff_padding
+ = Staff_symbol_referencer::staff_space (me)
+ * scm_to_double (me->get_maybe_pure_property ("staff-padding", pure, start, end));
+
+ Grob *parent = me->get_parent (Y_AXIS);
+ Grob *common = me->common_refpoint (staff, Y_AXIS);
+ Real parent_position = parent->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
+ Real staff_position = staff->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
+ Interval staff_extent = staff->maybe_pure_extent (staff, a, pure, start, end);
+ Real diff = (dir * staff_extent[dir] + staff_padding
+ - dir * total_off
+ + dir * (staff_position - parent_position));
+ total_off += dir * max (diff, 0.0);
+ }
+ }
+ return scm_from_double (total_off);