X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Faxis-group-interface.cc;h=af3ddcb8a310b181e910845d7349e0610bf69f8d;hb=9e781b7dc83b60a543ce218aa1a5f139f74c760f;hp=707e045c9b1a13b3127997d8c1ec05fed81467b7;hpb=f0fe9c843e926066299c1f9a33004649f42e1f24;p=lilypond.git diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 707e045c9b..af3ddcb8a3 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2000--2012 Han-Wen Nienhuys + Copyright (C) 2000--2014 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -243,6 +243,9 @@ Axis_group_interface::adjacent_pure_heights (SCM smob) if (to_boolean (g->get_property ("cross-staff"))) continue; + if (!g->is_live ()) + continue; + bool outside_staff = scm_is_number (g->get_property ("outside-staff-priority")); Real padding = robust_scm2double (g->get_property ("outside-staff-padding"), get_default_outside_staff_padding ()); @@ -392,9 +395,7 @@ SCM Axis_group_interface::calc_skylines (SCM smob) { Grob *me = unsmob_grob (smob); - extract_grob_set (me, Grob_array::unsmob (me->get_object ("vertical-skyline-elements")) ? "vertical-skyline-elements" : "elements", elts); - Skyline_pair skylines = skyline_spacing (me, elts); - + Skyline_pair skylines = skyline_spacing (me); return skylines.smobbed_copy (); } @@ -435,11 +436,15 @@ Axis_group_interface::combine_skylines (SCM smob) SCM Axis_group_interface::generic_group_extent (Grob *me, Axis a) { + extract_grob_set (me, "elements", elts); + /* trigger the callback to do skyline-spacing on the children */ if (a == Y_AXIS) - (void) me->get_property ("vertical-skylines"); + for (vsize i = 0; i < elts.size (); i++) + if (!(Stem::has_interface (elts[i]) + && to_boolean (elts[i]->get_property ("cross-staff")))) + (void) elts[i]->get_property ("vertical-skylines"); - extract_grob_set (me, "elements", elts); Grob *common = common_refpoint_of_array (elts, me, a); Real my_coord = me->relative_coordinate (common, a); @@ -469,28 +474,45 @@ SCM Axis_group_interface::calc_pure_relevant_grobs (SCM smob) { Grob *me = unsmob_grob (smob); + /* TODO: Filter out elements that belong to a different Axis_group, + such as the tie in + << \new Staff=A { c'1~ \change Staff=B c'} + \new Staff=B { \clef bass R1 R } >> + because thier location relative to this Axis_group is not known before + page layout. For now, we need to trap this case in calc_pure_y_common. + */ return internal_calc_pure_relevant_grobs (me, "elements"); } SCM -Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, string grob_set_name) +Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, const string &grob_set_name) { extract_grob_set (me, grob_set_name.c_str (), elts); vector relevant_grobs; - SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?"); for (vsize i = 0; i < elts.size (); i++) { - if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL))) + if (elts[i] && elts[i]->is_live ()) relevant_grobs.push_back (elts[i]); - + /* + TODO (mikesol): it is probably bad that we're reading prebroken + pieces from potentially suicided elements. This behavior + has been in current master since at least 2.16. + + We need to fully suicide all Items, meaning that their + prebroken pieces should not be accessible, which means that + Item::handle_prebroken_dependencies should only be called + AFTER this list is composed. The list composition function + should probably not check for suicided items or NULL pointers + but leave that to the various methods that use it. + */ if (Item *it = dynamic_cast (elts[i])) { for (LEFT_and_RIGHT (d)) { Item *piece = it->find_prebroken_piece (d); - if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL))) + if (piece && piece->is_live ()) relevant_grobs.push_back (piece); } } @@ -511,6 +533,12 @@ Axis_group_interface::calc_pure_y_common (SCM smob) extract_grob_set (me, "pure-relevant-grobs", elts); Grob *common = common_refpoint_of_array (elts, me, Y_AXIS); + if (common != me && Align_interface::has_interface (common)) + { + me->programming_error("My pure_y_common is a VerticalAlignment," + " which might contain several staves."); + common = me; + } if (!common) { me->programming_error ("No common parent found in calc_pure_y_common."); @@ -558,7 +586,7 @@ Axis_group_interface::pure_group_height (Grob *me, int start, int end) programming_error ("no pure Y common refpoint"); return Interval (); } - Real my_coord = me->relative_coordinate (common, Y_AXIS); + Real my_coord = me->pure_relative_y_coordinate (common, start, end); Interval r (relative_pure_height (me, start, end)); return r - my_coord; @@ -654,8 +682,8 @@ avoid_outside_staff_collisions (Grob *elt, for (vsize j = 0; j < other_v_skylines.size (); j++) { Skyline_pair const &v_other = other_v_skylines[j]; - Real pad = (padding + other_padding[j]); - Real horizon_pad = (horizon_padding + other_horizon_padding[j]); + Real pad = max (padding, other_padding[j]); + Real horizon_pad = max (horizon_padding, other_horizon_padding[j]); // We need to push elt up by at least this much to be above v_other. Real up = (*v_skyline)[DOWN].distance (v_other[UP], horizon_pad) + pad; @@ -744,7 +772,9 @@ add_grobs_of_one_priority (Grob *me, { Grob *elt = elements[i]; Real padding - = robust_scm2double (elt->get_property ("outside-staff-padding"), 0.25); + = robust_scm2double (elt->get_property ("outside-staff-padding"), + Axis_group_interface + ::get_default_outside_staff_padding ()); Real horizon_padding = robust_scm2double (elt->get_property ("outside-staff-horizontal-padding"), 0.0); Interval x_extent = elt->extent (x_common, X_AXIS); @@ -834,8 +864,10 @@ Axis_group_interface::outside_staff_ancestor (Grob *me) // that there is no room for the cross-staff grob. It also means, of course, that // we don't get the benefits of skyline placement for cross-staff grobs. Skyline_pair -Axis_group_interface::skyline_spacing (Grob *me, vector elements) +Axis_group_interface::skyline_spacing (Grob *me) { + extract_grob_set (me, Grob_array::unsmob (me->get_object ("vertical-skyline-elements")) ? "vertical-skyline-elements" : "elements", fakeelements); + vector elements (fakeelements); for (vsize i = 0; i < elements.size (); i++) /* As a sanity check, we make sure that no grob with an outside staff priority @@ -862,7 +894,12 @@ Axis_group_interface::skyline_spacing (Grob *me, vector elements) 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); + if (y_common != me) + { + me->programming_error("Some of my vertical-skyline-elements" + " are outside my VerticalAxisGroup."); + y_common = me; + } // A rider is a grob that is not outside-staff, but has an outside-staff // ancestor. In that case, the rider gets moved along with its ancestor. @@ -870,6 +907,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector elements) vsize i = 0; vector inside_staff_skylines; + for (i = 0; i < elements.size () && !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++) { @@ -1008,7 +1046,6 @@ ADD_INTERFACE (Axis_group_interface, "nonstaff-nonstaff-spacing " "nonstaff-relatedstaff-spacing " "nonstaff-unrelatedstaff-spacing " - "outside-staff-placement-directive " "pure-relevant-grobs " "pure-relevant-items " "pure-relevant-spanners " @@ -1017,7 +1054,6 @@ ADD_INTERFACE (Axis_group_interface, "staff-grouper " "staff-staff-spacing " "system-Y-offset " - "vertical-skyline-elements " "X-common " "Y-common " );