X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Faxis-group-interface.cc;h=520d024516a5f350eee316028114e2684f61ab90;hb=7439f9e74f8e33286c8af7f9a51fe4f7a4eb10fd;hp=b4003df2edb7764a008075cfc2ddab5f44496582;hpb=eac874ad80855c7f8372c7893394fd63371a7be1;p=lilypond.git diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index b4003df2ed..520d024516 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--2010 Han-Wen Nienhuys + Copyright (C) 2000--2011 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 @@ -35,6 +35,8 @@ #include "system.hh" #include "warn.hh" +static bool +pure_staff_priority_less (Grob *const &g1, Grob *const &g2); void Axis_group_interface::add_element (Grob *me, Grob *e) @@ -88,7 +90,7 @@ Axis_group_interface::relative_group_extent (vector const &elts, } Interval -Axis_group_interface::cached_pure_height (Grob *me, int start, int end) +Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end) { Interval iv = begin_of_line_pure_height (me, start); iv.unite (rest_of_line_pure_height (me, start, end)); @@ -97,27 +99,47 @@ Axis_group_interface::cached_pure_height (Grob *me, int start, int end) } Interval -Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end) +Axis_group_interface::part_of_line_pure_height (Grob *me, bool begin, int start, int end) { + Spanner *sp = dynamic_cast (me); + SCM cache_symbol = begin + ? ly_symbol2scm ("begin-of-line-pure-height") + : ly_symbol2scm ("rest-of-line-pure-height"); + SCM cached = sp->get_cached_pure_property (cache_symbol, start, end); + if (scm_is_pair (cached)) + return robust_scm2interval (cached, Interval (0, 0)); + SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights"); + Interval ret; - if (!scm_is_pair (adjacent_pure_heights) - || !scm_is_vector (scm_cdr (adjacent_pure_heights))) - return Interval (0, 0); + if (!scm_is_pair (adjacent_pure_heights)) + ret = Interval (0, 0); + else + { + SCM these_pure_heights = begin + ? scm_car (adjacent_pure_heights) + : scm_cdr (adjacent_pure_heights); - return combine_pure_heights (me, scm_cdr (adjacent_pure_heights), start, end); + if (scm_is_vector (these_pure_heights)) + ret = combine_pure_heights (me, these_pure_heights, start, end); + else + ret = Interval (0, 0); + } + + sp->cache_pure_property (cache_symbol, start, end, ly_interval2scm (ret)); + return ret; } Interval Axis_group_interface::begin_of_line_pure_height (Grob *me, int start) { - SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights"); - - if (!scm_is_pair (adjacent_pure_heights) - || !scm_is_vector (scm_car (adjacent_pure_heights))) - return Interval (0, 0); + return part_of_line_pure_height (me, true, start, start + 1); +} - return combine_pure_heights (me, scm_car (adjacent_pure_heights), start, start+1); +Interval +Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end) +{ + return part_of_line_pure_height (me, false, start, end); } Interval @@ -141,14 +163,12 @@ Axis_group_interface::combine_pure_heights (Grob *me, SCM measure_extents, int s return ext; } - // adjacent-pure-heights is a pair of vectors, each of which has one element // for every measure in the score. The first vector stores, for each measure, // the combined height of the elements that are present only when the bar // is at the beginning of a line. The second vector stores, for each measure, // the combined height of the elements that are present only when the bar // is not at the beginning of a line. - MAKE_SCHEME_CALLBACK (Axis_group_interface, adjacent_pure_heights, 1) SCM Axis_group_interface::adjacent_pure_heights (SCM smob) @@ -163,6 +183,8 @@ Axis_group_interface::adjacent_pure_heights (SCM smob) vector begin_line_heights; vector mid_line_heights; + vector begin_line_staff_heights; + vector mid_line_staff_heights; begin_line_heights.resize (ranks.size () - 1); mid_line_heights.resize (ranks.size () - 1); @@ -173,6 +195,25 @@ Axis_group_interface::adjacent_pure_heights (SCM smob) if (to_boolean (g->get_property ("cross-staff"))) continue; + bool outside_staff = scm_is_number (g->get_property ("outside-staff-priority")); + Real padding = robust_scm2double (g->get_property ("outside-staff-padding"), 0.5); + + // When we encounter the first outside-staff grob, make a copy + // of the current heights to use as an estimate for the staff heights. + // Note that the outside-staff approximation that we use here doesn't + // consider any collisions that might occur between outside-staff grobs, + // but only the fact that outside-staff grobs may need to be raised above + // the staff. + if (outside_staff && begin_line_staff_heights.empty ()) + { + begin_line_staff_heights = begin_line_heights; + mid_line_staff_heights = mid_line_heights; + } + + // TODO: consider a pure version of get_grob_direction? + Direction d = to_dir (g->get_property_data ("direction")); + d = (d == CENTER) ? UP : d; + Interval_t rank_span = g->spanned_rank_interval (); vsize first_break = lower_bound (ranks, (vsize)rank_span[LEFT], less ()); if (first_break > 0 && ranks[first_break] >= (vsize)rank_span[LEFT]) @@ -194,9 +235,21 @@ Axis_group_interface::adjacent_pure_heights (SCM smob) if (!dims.is_empty ()) { if (rank_span[LEFT] <= start) - begin_line_heights[j].unite (dims); - if (rank_span[RIGHT] > start) - mid_line_heights[j].unite (dims); + { + if (outside_staff) + begin_line_heights[j].unite ( + begin_line_staff_heights[j].union_disjoint (dims, padding, d)); + else + begin_line_heights[j].unite (dims); + } + if (rank_span[RIGHT] > start) + { + if (outside_staff) + mid_line_heights[j].unite ( + mid_line_staff_heights[j].union_disjoint (dims, padding, d)); + else + mid_line_heights[j].unite (dims); + } } } } @@ -227,7 +280,7 @@ Axis_group_interface::relative_pure_height (Grob *me, int start, int end) we can assume additivity and cache things nicely. */ Grob *p = me->get_parent (Y_AXIS); if (p && Align_interface::has_interface (p)) - return Axis_group_interface::cached_pure_height (me, start, end); + return Axis_group_interface::sum_partial_pure_heights (me, start, end); Grob *common = unsmob_grob (me->get_object ("pure-Y-common")); extract_grob_set (me, "pure-relevant-grobs", elts); @@ -331,7 +384,7 @@ Axis_group_interface::combine_skylines (SCM smob) } return ret.smobbed_copy (); } - + SCM Axis_group_interface::generic_group_extent (Grob *me, Axis a) { @@ -370,7 +423,7 @@ SCM Axis_group_interface::calc_pure_relevant_grobs (SCM smob) { Grob *me = unsmob_grob (smob); - + extract_grob_set (me, "elements", elts); vector relevant_grobs; @@ -394,6 +447,7 @@ Axis_group_interface::calc_pure_relevant_grobs (SCM smob) } } + vector_sort (relevant_grobs, pure_staff_priority_less); SCM grobs_scm = Grob_array::make_array (); unsmob_grob_array (grobs_scm)->set_array (relevant_grobs); @@ -502,6 +556,15 @@ staff_priority_less (Grob * const &g1, Grob * const &g2) return start_1 < start_2; } +static bool +pure_staff_priority_less (Grob * const &g1, Grob * const &g2) +{ + 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); + + return priority_1 < priority_2; +} + static void add_boxes (Grob *me, Grob *x_common, Grob *y_common, vector *const boxes, Skyline_pair *skylines) { @@ -650,7 +713,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector elements) SCM priority = elements[i]->get_property ("outside-staff-priority"); vector current_elts; current_elts.push_back (elements[i]); - while (i + 1 < elements.size () + while (i + 1 < elements.size () && scm_eq_p (elements[i+1]->get_property ("outside-staff-priority"), priority)) { if (!to_boolean (elements[i+1]->get_property ("cross-staff"))) @@ -683,28 +746,28 @@ Axis_group_interface::print (SCM smob) return ret.smobbed_copy (); } -MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_next_staff_spacing, 3) +MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_staff_staff_spacing, 3) SCM -Axis_group_interface::calc_pure_next_staff_spacing (SCM smob, SCM start, SCM end) +Axis_group_interface::calc_pure_staff_staff_spacing (SCM smob, SCM start, SCM end) { - return calc_maybe_pure_next_staff_spacing (unsmob_grob (smob), - true, - scm_to_int (start), - scm_to_int (end)); + return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob), + true, + scm_to_int (start), + scm_to_int (end)); } -MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_next_staff_spacing, 1) +MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_staff_staff_spacing, 1) SCM -Axis_group_interface::calc_next_staff_spacing (SCM smob) +Axis_group_interface::calc_staff_staff_spacing (SCM smob) { - return calc_maybe_pure_next_staff_spacing (unsmob_grob (smob), - false, - 0, - INT_MAX); + return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob), + false, + 0, + INT_MAX); } SCM -Axis_group_interface::calc_maybe_pure_next_staff_spacing (Grob *me, bool pure, int start, int end) +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")); @@ -712,11 +775,11 @@ Axis_group_interface::calc_maybe_pure_next_staff_spacing (Grob *me, bool pure, i { Grob *last_in_group = Staff_grouper_interface::get_maybe_pure_last_grob (grouper, pure, start, end); if (me == last_in_group) - return grouper->get_maybe_pure_property ("after-last-staff-spacing", pure, start, end); + return grouper->get_maybe_pure_property ("staffgroup-staff-spacing", pure, start, end); else - return grouper->get_maybe_pure_property ("between-staff-spacing", pure, start, end); + return grouper->get_maybe_pure_property ("staff-staff-spacing", pure, start, end); } - return me->get_maybe_pure_property ("default-next-staff-spacing", pure, start, end); + return me->get_maybe_pure_property ("default-staff-staff-spacing", pure, start, end); } Real @@ -738,24 +801,24 @@ ADD_INTERFACE (Axis_group_interface, // VerticalAxisGroup. We should split off a // vertical-axis-group-interface. /* properties */ - "X-common " - "Y-common " "adjacent-pure-heights " "axes " - "default-next-staff-spacing " + "default-staff-staff-spacing " "elements " - "inter-loose-line-spacing " - "inter-staff-spacing " "max-stretch " - "non-affinity-spacing " - "next-staff-spacing " "no-alignment " - "pure-Y-common " + "nonstaff-nonstaff-spacing " + "nonstaff-relatedstaff-spacing " + "nonstaff-unrelatedstaff-spacing " "pure-relevant-grobs " "pure-relevant-items " "pure-relevant-spanners " + "pure-Y-common " "staff-affinity " "staff-grouper " + "staff-staff-spacing " "system-Y-offset " "vertical-skylines " + "X-common " + "Y-common " );