+ // Because horizontal skylines need vertical heights, we'd trigger
+ // unpure calculations too soon if this were called before line breaking.
+ // So, we always use pure heights. Given that horizontal skylines are
+ // almost always used before line breaking anyway, this doesn't cause
+ // problems.
+ return axis_aligned_side_helper (smob, X_AXIS, true, 0, 0, current_off);
+}
+
+MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Side_position_interface, y_aligned_side, 2, 1, "");
+SCM
+Side_position_interface::y_aligned_side (SCM smob, SCM current_off)
+{
+ return axis_aligned_side_helper (smob, Y_AXIS, false, 0, 0, current_off);
+}
+
+MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Side_position_interface, pure_y_aligned_side, 4, 1, "");
+SCM
+Side_position_interface::pure_y_aligned_side (SCM smob, SCM start, SCM end, SCM cur_off)
+{
+ return axis_aligned_side_helper (smob, Y_AXIS, true,
+ scm_to_int (start),
+ scm_to_int (end),
+ cur_off);
+}
+
+MAKE_SCHEME_CALLBACK (Side_position_interface, calc_cross_staff, 1)
+SCM
+Side_position_interface::calc_cross_staff (SCM smob)
+{
+ Grob *me = unsmob<Grob> (smob);
+ extract_grob_set (me, "side-support-elements", elts);
+
+ Direction my_dir = get_grob_direction (me) ;
+
+ for (vsize i = 0; i < elts.size (); i++)
+ {
+ /*
+ If 'me' is placed relative to any cross-staff element with a
+ 'direction callback defined, the placement of 'me' is likely
+ to depend on staff-spacing, thus 'me' should be considered
+ cross-staff.
+ */
+ if (to_boolean (elts[i]->get_property ("cross-staff"))
+ && !is_direction (elts[i]->get_property_data ("direction")))
+ return SCM_BOOL_T;
+
+ /*
+ If elts[i] is cross-staff and is pointing in the same
+ direction as 'me', we assume that the alignment
+ of 'me' is influenced the cross-staffitude of elts[i]
+ and thus we mark 'me' as cross-staff.
+ */
+ if (to_boolean (elts[i]->get_property ("cross-staff"))
+ && my_dir == get_grob_direction (elts[i]))
+ return SCM_BOOL_T;
+ }