X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Faxis-group-interface.cc;h=6d7074fe98f18152c84e620d6131e6f08cbebc9e;hb=b8f63200f0dde97e6d066e5f1082808e224d9774;hp=02e900164b642b1ba8f358994b7e9884edafa696;hpb=0c5bcc9f980e3dc40b53543a957bbf353d7c2308;p=lilypond.git diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 02e900164b..6d7074fe98 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -9,12 +9,11 @@ #include "axis-group-interface.hh" #include "align-interface.hh" +#include "directional-element-interface.hh" #include "pointer-group-interface.hh" -#include "grob.hh" #include "grob-array.hh" #include "hara-kiri-group-spanner.hh" #include "international.hh" -#include "item.hh" #include "paper-column.hh" #include "paper-score.hh" #include "system.hh" @@ -88,6 +87,8 @@ Axis_group_interface::cached_pure_height (Grob *me, if (end == r) end_index = i; } + if (end == INT_MAX) + end_index = breaks.size () - 1; if (start_index == VPOS || end_index == VPOS) { @@ -182,6 +183,8 @@ SCM Axis_group_interface::generic_group_extent (Grob *me, Axis a) { 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); @@ -251,7 +254,89 @@ Axis_group_interface::get_children (Grob *me, vector *found) } } -ADD_INTERFACE (Axis_group_interface, "axis-group-interface", +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); + + if (priority_1 < priority_2) + return true; + else if (priority_1 > priority_2) + return false; + + /* if there is no preference in staff priority, choose the one with the lower rank */ + int rank_1 = g1->spanned_rank_iv ()[LEFT]; + int rank_2 = g2->spanned_rank_iv ()[LEFT]; + return rank_1 < rank_2; +} + +static void +add_boxes (Grob *me, Grob *x_common, Grob *y_common, vector *const boxes) +{ + if (Axis_group_interface::has_interface (me) + && Axis_group_interface::has_axis (me, Y_AXIS)) + { + Grob_array *elements = unsmob_grob_array (me->get_object ("elements")); + if (elements) + for (vsize i = 0; i < elements->size (); i++) + add_boxes (elements->grob (i), x_common, y_common, boxes); + } + else + boxes->push_back (Box (me->extent (x_common, X_AXIS), + me->extent (y_common, Y_AXIS))); +} + +void +Axis_group_interface::skyline_spacing (Grob *me, vector 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); + Real max_slope = robust_scm2double (me->get_property ("skyline-max-slope"), 4); + + vsize i = 0; + vector boxes; + + for (i = 0; i < elements.size () + && !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++) + add_boxes (elements[i], x_common, y_common, &boxes); + + Drul_array skylines (Skyline (boxes, max_slope, X_AXIS, DOWN), + Skyline (boxes, max_slope, X_AXIS, UP)); + for (; i < elements.size (); i++) + { + Direction dir = get_grob_direction (elements[i]); + if (dir == CENTER) + { + warning (_ ("an outside-staff object should have a direction")); + continue; + } + + Box b (elements[i]->extent (x_common, X_AXIS), + elements[i]->extent (y_common, Y_AXIS)); + if (b[X_AXIS].is_empty () || b[Y_AXIS].is_empty ()) + { + warning (_f ("outside-staff object %s has an empty extent", elements[i]->name ().c_str ())); + continue; + } + + boxes.clear (); + boxes.push_back (b); + Skyline other = Skyline (boxes, max_slope, X_AXIS, -dir); + Real padding = robust_scm2double (elements[i]->get_property ("outside-staff-padding"), 0.5); + Real dist = skylines[dir].distance (other) + padding; + + if (dist > 0) + { + b.translate (Offset (0, dir*dist)); + elements[i]->translate_axis (dir*dist, Y_AXIS); + } + skylines[dir].insert (b, max_slope, X_AXIS); + } +} + +ADD_INTERFACE (Axis_group_interface, "An object that groups other layout objects.", @@ -260,5 +345,7 @@ ADD_INTERFACE (Axis_group_interface, "axis-group-interface", "elements " "common-refpoint-of-elements " "pure-relevant-elements " + "skyline-max-slope " + "skyline-spacing " "cached-pure-extents " );