return pure_group_height (me, start, end);
}
+
+MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_skylines, 1);
+SCM
+Axis_group_interface::calc_skylines (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ extract_grob_set (me, "elements", elts);
+ return skyline_spacing (me, elts).smobbed_copy ();
+}
+
+/* whereas calc_skylines calculates skylines for axis-groups with a lot of
+ visible children, combine_skylines is designed for axis-groups whose only
+ children are other axis-groups (ie. VerticalAlignment). Rather than
+ calculating all the skylines from scratch, we just merge the skylines
+ of the children.
+*/
+MAKE_SCHEME_CALLBACK (Axis_group_interface, combine_skylines, 1);
+SCM
+Axis_group_interface::combine_skylines (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ extract_grob_set (me, "elements", elements);
+ Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
+
+ assert (y_common == me);
+
+ Skyline_pair ret;
+ for (vsize i = 0; i < elements.size (); i++)
+ {
+ SCM skyline_scm = elements[i]->get_property ("skylines");
+ if (Skyline_pair::unsmob (skyline_scm))
+ {
+ Real offset = elements[i]->relative_coordinate (y_common, Y_AXIS);
+ Skyline_pair other = *Skyline_pair::unsmob (skyline_scm);
+ other.raise (offset);
+ ret.merge (other);
+ }
+ }
+ return ret.smobbed_copy ();
+}
SCM
Axis_group_interface::generic_group_extent (Grob *me, Axis a)
{
+ /* trigger the callback to do skyline-spacing on the children */
+ (void) me->get_property ("skylines");
+
extract_grob_set (me, "elements", elts);
- if (a == Y_AXIS && to_boolean (me->get_property ("skyline-spacing")))
- skyline_spacing (me, elts);
Grob *common = common_refpoint_of_array (elts, me, a);
Real my_coord = me->relative_coordinate (common, a);
bool
staff_priority_less (Grob * const &g1, Grob * const &g2)
{
- int priority_1 = robust_scm2int (g1->get_property ("outside-staff-priority"), INT_MIN);
- int priority_2 = robust_scm2int (g2->get_property ("outside-staff-priority"), INT_MIN);
+ Real priority_1 = robust_scm2double (g1->get_property ("outside-staff-priority"), -infinity_f);
+ Real priority_2 = robust_scm2double (g2->get_property ("outside-staff-priority"), -infinity_f);
if (priority_1 < priority_2)
return true;
edge of the just-placed grob). Otherwise, we skip it until the next pass.
*/
static void
-add_grobs_of_one_priority (Drul_array<Skyline> *const skylines,
+add_grobs_of_one_priority (Skyline_pair *const skylines,
vector<Grob*> elements,
Grob *x_common,
Grob *y_common)
elements[i]->translate_axis (dir*dist, Y_AXIS);
}
(*skylines)[dir].insert (b, 0, X_AXIS);
- elements[i]->del_property ("outside-staff-padding");
+ elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F);
last_affected_position[dir] = b[X_AXIS][RIGHT];
}
elements.erase (elements.begin () + i);
}
}
-void
+Skyline_pair
Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
{
vector_sort (elements, staff_priority_less);
Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS);
Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
+ assert (y_common == me);
+
vsize i = 0;
vector<Box> boxes;
&& !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++)
add_boxes (elements[i], x_common, y_common, &boxes);
- Drul_array<Skyline> skylines (Skyline (boxes, 0, X_AXIS, DOWN),
- Skyline (boxes, 0, X_AXIS, UP));
+ Skyline_pair skylines (boxes, 0, X_AXIS);
for (; i < elements.size (); i++)
{
SCM priority = elements[i]->get_property ("outside-staff-priority");
add_grobs_of_one_priority (&skylines, current_elts, x_common, y_common);
}
+ return skylines;
}
ADD_INTERFACE (Axis_group_interface,
"elements "
"common-refpoint-of-elements "
"pure-relevant-elements "
- "skyline-spacing "
+ "skylines "
"cached-pure-extents "
);