X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Faxis-group-interface.cc;h=946db34a8b4c0fc83f30b817784df8f112152d74;hb=47db9a3883d726ca53e2133a3b2298f78dd6a32e;hp=9389236d1feb6b366a1b2cba7e42088555e9004b;hpb=8d96001e14317b93c68a749c2ec270b3738e7ad9;p=lilypond.git diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 9389236d1f..946db34a8b 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--2015 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 @@ -51,19 +51,6 @@ Axis_group_interface::get_default_outside_staff_padding () return default_outside_staff_padding_; } -MAKE_SCHEME_CALLBACK (Axis_group_interface, cross_staff, 1); -SCM -Axis_group_interface::cross_staff (SCM smob) -{ - Grob *me = unsmob_grob (smob); - extract_grob_set (me, "elements", elts); - for (vsize i = 0; i < elts.size (); i++) - if (to_boolean (elts[i]->get_property ("cross-staff"))) - return SCM_BOOL_T; - - return SCM_BOOL_F; -} - void Axis_group_interface::add_element (Grob *me, Grob *e) { @@ -112,8 +99,7 @@ Axis_group_interface::relative_maybe_bound_group_extent (vector const &e for (vsize i = 0; i < elts.size (); i++) { Grob *se = elts[i]; - if (has_interface (se) - || !to_boolean (se->get_property ("cross-staff"))) + if (!to_boolean (se->get_property ("cross-staff"))) { Interval dims = (bound && has_interface (se) ? generic_bound_extent (se, common, a) @@ -235,9 +221,9 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, adjacent_pure_heights, 1) SCM Axis_group_interface::adjacent_pure_heights (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); - Grob *common = unsmob_grob (me->get_object ("pure-Y-common")); + Grob *common = Grob::unsmob (me->get_object ("pure-Y-common")); extract_grob_set (me, "pure-relevant-grobs", elts); Paper_score *ps = get_root_system (me)->paper_score (); @@ -254,8 +240,7 @@ Axis_group_interface::adjacent_pure_heights (SCM smob) { Grob *g = elts[i]; - if (to_boolean (g->get_property ("cross-staff")) - && !has_interface (g)) + if (to_boolean (g->get_property ("cross-staff"))) continue; if (!g->is_live ()) @@ -346,7 +331,7 @@ Axis_group_interface::relative_pure_height (Grob *me, int start, int end) if (p && Align_interface::has_interface (p)) return Axis_group_interface::sum_partial_pure_heights (me, start, end); - Grob *common = unsmob_grob (me->get_object ("pure-Y-common")); + Grob *common = Grob::unsmob (me->get_object ("pure-Y-common")); extract_grob_set (me, "pure-relevant-grobs", elts); Interval r; @@ -371,7 +356,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, width, 1); SCM Axis_group_interface::width (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); return generic_group_extent (me, X_AXIS); } @@ -379,7 +364,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, height, 1); SCM Axis_group_interface::height (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); return generic_group_extent (me, Y_AXIS); } @@ -389,7 +374,7 @@ Axis_group_interface::pure_height (SCM smob, SCM start_scm, SCM end_scm) { int start = robust_scm2int (start_scm, 0); int end = robust_scm2int (end_scm, INT_MAX); - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); /* Maybe we are in the second pass of a two-pass spacing run. In that case, the Y-extent of a system is already given to us */ @@ -409,7 +394,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_skylines, 1); SCM Axis_group_interface::calc_skylines (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); Skyline_pair skylines = skyline_spacing (me); return skylines.smobbed_copy (); } @@ -424,7 +409,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, combine_skylines, 1); SCM Axis_group_interface::combine_skylines (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); extract_grob_set (me, "elements", elements); Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS); Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS); @@ -436,7 +421,7 @@ Axis_group_interface::combine_skylines (SCM smob) for (vsize i = 0; i < elements.size (); i++) { SCM skyline_scm = elements[i]->get_property ("vertical-skylines"); - if (Skyline_pair::unsmob (skyline_scm)) + if (Skyline_pair::is_smob (skyline_scm)) { Real offset = elements[i]->relative_coordinate (y_common, Y_AXIS); Skyline_pair other = *Skyline_pair::unsmob (skyline_scm); @@ -456,7 +441,9 @@ Axis_group_interface::generic_group_extent (Grob *me, Axis a) /* trigger the callback to do skyline-spacing on the children */ if (a == Y_AXIS) for (vsize i = 0; i < elts.size (); i++) - (void) elts[i]->get_property ("vertical-skylines"); + if (!(Stem::has_interface (elts[i]) + && to_boolean (elts[i]->get_property ("cross-staff")))) + (void) elts[i]->get_property ("vertical-skylines"); Grob *common = common_refpoint_of_array (elts, me, a); @@ -486,12 +473,19 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_relevant_grobs, 1); SCM Axis_group_interface::calc_pure_relevant_grobs (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (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); @@ -500,23 +494,33 @@ Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, string grob_s for (vsize i = 0; i < elts.size (); i++) { 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])) { - relevant_grobs.push_back (elts[i]); - if (Item *it = dynamic_cast (elts[i])) + for (LEFT_and_RIGHT (d)) { - for (LEFT_and_RIGHT (d)) - { - Item *piece = it->find_prebroken_piece (d); - if (piece && piece->is_live ()) - relevant_grobs.push_back (piece); - } + Item *piece = it->find_prebroken_piece (d); + if (piece && piece->is_live ()) + relevant_grobs.push_back (piece); } } } vector_sort (relevant_grobs, pure_staff_priority_less); SCM grobs_scm = Grob_array::make_array (); - unsmob_grob_array (grobs_scm)->set_array (relevant_grobs); + Grob_array::unsmob (grobs_scm)->set_array (relevant_grobs); return grobs_scm; } @@ -525,10 +529,16 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_y_common, 1); SCM Axis_group_interface::calc_pure_y_common (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (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."); @@ -556,20 +566,20 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_x_common, 1); SCM Axis_group_interface::calc_x_common (SCM grob) { - return calc_common (unsmob_grob (grob), X_AXIS); + return calc_common (Grob::unsmob (grob), X_AXIS); } MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_y_common, 1); SCM Axis_group_interface::calc_y_common (SCM grob) { - return calc_common (unsmob_grob (grob), Y_AXIS); + return calc_common (Grob::unsmob (grob), Y_AXIS); } Interval Axis_group_interface::pure_group_height (Grob *me, int start, int end) { - Grob *common = unsmob_grob (me->get_object ("pure-Y-common")); + Grob *common = Grob::unsmob (me->get_object ("pure-Y-common")); if (!common) { @@ -634,7 +644,7 @@ pure_staff_priority_less (Grob *const &g1, Grob *const &g2) static void add_interior_skylines (Grob *me, Grob *x_common, Grob *y_common, vector *skylines) { - if (Grob_array *elements = unsmob_grob_array (me->get_object ("elements"))) + if (Grob_array *elements = Grob_array::unsmob (me->get_object ("elements"))) { for (vsize i = 0; i < elements->size (); i++) add_interior_skylines (elements->grob (i), x_common, y_common, skylines); @@ -672,17 +682,15 @@ 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 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]); - Interval collision; - // We need to push elt by at least this much to be outside v_other. - collision[dir] = ((*v_skyline)[-dir].distance (v_other[dir], horizon_pad) - + padding) * dir; - // We need to pull elt by at least this much to be inside v_other. - collision[-dir] = ((*v_skyline)[dir].distance (v_other[-dir], horizon_pad) - + other_padding[j]) * -dir; + // 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; + // We need to push elt down by at least this much to be below v_other. + Real down = (*v_skyline)[UP].distance (v_other[DOWN], horizon_pad) + pad; - forbidden_intervals.push_back (collision); + forbidden_intervals.push_back (Interval (-down, up)); } Interval_set allowed_shifts @@ -765,7 +773,8 @@ add_grobs_of_one_priority (Grob *me, Grob *elt = elements[i]; Real padding = robust_scm2double (elt->get_property ("outside-staff-padding"), - Axis_group_interface::get_default_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); @@ -885,7 +894,12 @@ Axis_group_interface::skyline_spacing (Grob *me) 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. @@ -899,7 +913,7 @@ Axis_group_interface::skyline_spacing (Grob *me) { Grob *elt = elements[i]; Grob *ancestor = outside_staff_ancestor (elt); - if (!ancestor) + if (!(to_boolean (elt->get_property ("cross-staff")) || ancestor)) add_interior_skylines (elt, x_common, y_common, &inside_staff_skylines); if (ancestor) riders.insert (pair (ancestor, elt)); @@ -967,7 +981,7 @@ Axis_group_interface::print (SCM smob) if (!debug_skylines) return SCM_BOOL_F; - Grob *me = unsmob_grob (smob); + Grob *me = Grob::unsmob (smob); Stencil ret; if (Skyline_pair *s = Skyline_pair::unsmob (me->get_property ("vertical-skylines"))) { @@ -983,7 +997,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_staff_staff_spacing, 3) SCM Axis_group_interface::calc_pure_staff_staff_spacing (SCM smob, SCM start, SCM end) { - return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob), + return calc_maybe_pure_staff_staff_spacing (Grob::unsmob (smob), true, scm_to_int (start), scm_to_int (end)); @@ -993,7 +1007,7 @@ MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_staff_staff_spacing, 1) SCM Axis_group_interface::calc_staff_staff_spacing (SCM smob) { - return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob), + return calc_maybe_pure_staff_staff_spacing (Grob::unsmob (smob), false, 0, INT_MAX); @@ -1002,7 +1016,7 @@ Axis_group_interface::calc_staff_staff_spacing (SCM smob) SCM Axis_group_interface::calc_maybe_pure_staff_staff_spacing (Grob *me, bool pure, int start, int end) { - Grob *grouper = unsmob_grob (me->get_object ("staff-grouper")); + Grob *grouper = Grob::unsmob (me->get_object ("staff-grouper")); if (grouper) { @@ -1032,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 " @@ -1041,7 +1054,6 @@ ADD_INTERFACE (Axis_group_interface, "staff-grouper " "staff-staff-spacing " "system-Y-offset " - "vertical-skyline-elements " "X-common " "Y-common " );