From 587186e70d21624cff1d1a7956ef7f37cb11dd3e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sat, 6 Jan 2007 04:08:12 +0100 Subject: [PATCH] Cache common refpoint of VerticalAxisGroup using object-callback. --- lily/align-interface.cc | 19 ++++++- lily/axis-group-interface.cc | 85 ++++++++++++++++++---------- lily/include/axis-group-interface.hh | 2 + scm/define-grob-properties.scm | 5 +- scm/define-grobs.scm | 2 + 5 files changed, 78 insertions(+), 35 deletions(-) diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 89d2648ae2..87b354a5f4 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -146,8 +146,23 @@ get_skylines (Grob *me, vector child_refpoints; for (vsize i = 0; i < elements->size (); i++) { - extract_grob_set ((*elements)[i], "elements", child_elts); - Grob *child_common = common_refpoint_of_array (child_elts, (*elements)[i], other_axis (a)); + Grob *elt = (*elements)[i]; + Grob *child_common = 0; + + /* + should consider whether to restrict to Y_AXIS. + */ + if (a == Y_AXIS) + child_common = unsmob_grob (elt->get_object ("Y-common")); + else + child_common = unsmob_grob (elt->get_object ("X-common")); + + if (!child_common) + { + extract_grob_set (elt, "elements", child_elts); + child_common = common_refpoint_of_array (child_elts, elt, other_axis (a)); + } + child_refpoints.push_back (child_common); } Grob *common_refpoint = common_refpoint_of_array (child_refpoints, me, other_axis (a)); diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 3f4da03c93..9fbfdf3193 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -235,44 +235,61 @@ Axis_group_interface::generic_group_extent (Grob *me, Axis a) return ly_interval2scm (r - my_coord); } -SCM -Axis_group_interface::pure_group_height (Grob *me, int start, int end) + +Grob * +Axis_group_interface::calc_pure_elts_and_common (Grob *me) { - Grob *common = unsmob_grob (me->get_object ("common-refpoint-of-elements")); + if (Grob *c = unsmob_grob (me->get_object ("pure-Y-common"))) + return c; + + extract_grob_set (me, "elements", elts); + + vector relevant_elts; + SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?"); - if (!common) + for (vsize i = 0; i < elts.size (); i++) { - extract_grob_set (me, "elements", elts); + if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL))) + relevant_elts.push_back (elts[i]); - vector relevant_elts; - SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?"); + Item *it = dynamic_cast (elts[i]); + Direction d = LEFT; + if (it) + do + { + Item *piece = it->find_prebroken_piece (d); + if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL))) + relevant_elts.push_back (piece); + } + while (flip (&d) != LEFT); + } - for (vsize i = 0; i < elts.size (); i++) - { - if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL))) - relevant_elts.push_back (elts[i]); - - Item *it = dynamic_cast (elts[i]); - Direction d = LEFT; - if (it) - do - { - Item *piece = it->find_prebroken_piece (d); - if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL))) - relevant_elts.push_back (piece); - } - while (flip (&d) != LEFT); - } + Grob *common = common_refpoint_of_array (relevant_elts, me, Y_AXIS); + me->set_object ("pure-Y-common", common->self_scm ()); + + SCM ga_scm = Grob_array::make_array (); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->set_array (relevant_elts); + me->set_object ("pure-relevant-elements", ga_scm); - common = common_refpoint_of_array (relevant_elts, me, Y_AXIS); - me->set_object ("common-refpoint-of-elements", common->self_scm ()); + return common; +} - SCM ga_scm = Grob_array::make_array (); - Grob_array *ga = unsmob_grob_array (ga_scm); - ga->set_array (relevant_elts); - me->set_object ("pure-relevant-elements", ga_scm); - } +MAKE_SCHEME_CALLBACK(Axis_group_interface,calc_y_common, 1); +SCM +Axis_group_interface::calc_y_common (SCM grob) +{ + Grob *me = unsmob_grob (grob); + extract_grob_set (me, "elements", elts); + return common_refpoint_of_array (elts, me, Y_AXIS)->self_scm (); +} + +SCM +Axis_group_interface::pure_group_height (Grob *me, int start, int end) +{ + Grob *common = calc_pure_elts_and_common (me); + extract_grob_set (me, "pure-relevant-elements", elts); Real my_coord = me->relative_coordinate (common, Y_AXIS); Interval r (relative_pure_height (me, elts, common, start, end, true)); @@ -398,6 +415,10 @@ add_grobs_of_one_priority (Skyline_pair *const skylines, elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F); last_affected_position[dir] = b[X_AXIS][RIGHT]; } + + /* + Ugh: quadratic. --hwn + */ elements.erase (elements.begin () + i); } } @@ -439,9 +460,11 @@ ADD_INTERFACE (Axis_group_interface, "An object that groups other layout objects.", /* properties */ + "X-common " + "Y-common " "axes " "elements " - "common-refpoint-of-elements " + "pure-Y-common " "pure-relevant-elements " "skylines " "cached-pure-extents " diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index 4272b1a890..c634b52bb3 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -19,6 +19,7 @@ struct Axis_group_interface static SCM generic_group_extent (Grob *me, Axis a); static SCM pure_group_height (Grob *me, int start, int end); DECLARE_SCHEME_CALLBACK (width, (SCM smob)); + DECLARE_SCHEME_CALLBACK (calc_y_common, (SCM smob)); DECLARE_SCHEME_CALLBACK (height, (SCM smob)); DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end)); DECLARE_SCHEME_CALLBACK (calc_skylines, (SCM smob)); @@ -31,6 +32,7 @@ struct Axis_group_interface static Interval cached_pure_height (Grob *me, vector const &list, Grob *common, int, int); + static Grob *calc_pure_elts_and_common (Grob*); static Skyline_pair skyline_spacing (Grob *me, vector elements); static void add_element (Grob *me, Grob *); static void set_axes (Grob *, Axis, Axis); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 9d354b8d22..07dd64b3c4 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -451,9 +451,9 @@ glissando line can be constructed from a whole number of squiggles.") ;;;;;;;;;;;;;;;; ;; grobs & grob arrays. (alphabetical) - + (Y-common ,ly:grob? "See X-common") + (X-common ,ly:grob? "Common refpoint for axis group.") (cached-pure-extents ,vector? "Used by a VerticalAxisGroup to cache the Y-extents of different column ranges.") - (common-refpoint-of-elements ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set") (axis-group-parent-X ,ly:grob? "Containing X axis group") (axis-group-parent-Y ,ly:grob? "Containing Y axis group") (accidental-grobs ,list? "Alist with (NOTENAME . GROBLIST) entries") @@ -482,6 +482,7 @@ columns. (left-items ,ly:grob-array? "") (pedal-text ,ly:grob? "Pointer to the text of a mixed-style piano pedal.") + (pure-Y-common ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set") (pure-relevant-elements ,ly:grob-array? "The subset of elements that are relevant for finding the pure-Y-extent.") (stem ,ly:grob? "pointer to Stem object.") (tremolo-flag ,ly:grob? "The tremolo object on a stem.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 34618b9b77..149b80a99a 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1998,6 +1998,7 @@ (padding . 0.5) (skylines . ,ly:axis-group-interface::combine-skylines) (meta . ((class . Spanner) + (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common))) (interfaces . (align-interface axis-group-interface)))))) (VerticalAxisGroup @@ -2008,6 +2009,7 @@ (X-extent . ,ly:axis-group-interface::width) (skylines . ,ly:axis-group-interface::calc-skylines); (meta . ((class . Spanner) + (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common))) (interfaces . (axis-group-interface hara-kiri-group-spanner-interface vertically-spaceable-interface)))))) -- 2.39.5