+MAKE_SCHEME_CALLBACK (Align_interface,fixed_distance_alignment_callback,2);
+SCM
+Align_interface::fixed_distance_alignment_callback (SCM element_smob, SCM axis)
+{
+ Grob * me = unsmob_grob (element_smob);
+ Axis ax = (Axis)gh_scm2int (axis);
+ Grob * par = me->parent_l (ax);
+ if (par && !to_boolean (par->get_grob_property ("alignment-done")))
+ {
+ Align_interface::align_to_fixed_distance (par, ax);
+ }
+ return gh_double2scm (0.0);
+}
+
+/*
+ merge with align-to-extents?
+ */
+void
+Align_interface::align_to_fixed_distance (Grob *me , Axis a)
+{
+ me->set_grob_property ("alignment-done", SCM_BOOL_T);
+
+ SCM d = me->get_grob_property ("stacking-dir");
+
+
+ Direction stacking_dir = gh_number_p (d) ? to_dir (d) : CENTER;
+ if (!stacking_dir)
+ stacking_dir = DOWN;
+
+
+ SCM force = me->get_grob_property ("forced-distance");
+
+ Real dy = 0.0;
+ if (gh_number_p (force))
+ {
+ dy = gh_scm2double (force);
+ }
+
+ Link_array<Grob> elems
+ = Pointer_group_interface__extract_elements (me, (Grob*) 0, "elements");
+
+ Real where_f=0;
+
+ Interval v;
+ v.set_empty ();
+ Array<Real> translates;
+
+ for (int j=0 ; j < elems.size (); j++)
+ {
+ where_f += stacking_dir * dy;
+ translates.push (where_f);
+ v.unite (Interval (where_f, where_f));
+ }
+
+ /*
+ TODO: support self-alignment-{Y,X}
+ */
+ for (int i = 0; i < translates.size (); i++)
+ {
+ elems[i]->translate_axis (translates[i] - v.center (), a);
+ }
+}