+ SCM extents = me->get_property ("cached-pure-extents");
+ if (!scm_is_vector (extents))
+ {
+ extents = scm_c_make_vector (breaks.size () - 1, SCM_EOL);
+ for (vsize i = 0; i < breaks.size () - 1; i++)
+ {
+ int st = Paper_column::get_rank (cols[breaks[i]]);
+ int ed = Paper_column::get_rank (cols[breaks[i+1]]);
+ Interval iv = relative_pure_height (me, elts, common, st, ed, false);
+ scm_vector_set_x (extents, scm_from_int (i), ly_interval2scm (iv));
+ }
+ me->set_property ("cached-pure-extents", extents);
+ }
+
+ Interval ext (0, 0);
+ for (vsize i = start_index; i < end_index; i++)
+ ext.unite (ly_scm2interval (scm_c_vector_ref (extents, i)));
+ return ext;
+}
+
+Interval
+Axis_group_interface::relative_pure_height (Grob *me,
+ vector<Grob*> const &elts,
+ Grob *common,
+ int start, int end,
+ bool use_cache)
+{
+ /* It saves a _lot_ of time if we assume a VerticalAxisGroup is additive
+ (ie. height (i, k) = height (i, j) + height (j, k) for all i <= j <= k).
+ Unfortunately, it isn't always true, particularly if there is a
+ VerticalAlignment somewhere in the descendants.
+
+ Apart from PianoStaff, which has a fixed VerticalAlignment so it doesn't
+ count, the only VerticalAlignment comes from Score. This makes it
+ reasonably safe to assume that if our parent is a VerticalAlignment,
+ we can assume additivity and cache things nicely. */
+ Grob *p = me->get_parent (Y_AXIS);
+ if (use_cache && p && Align_interface::has_interface (p))
+ return Axis_group_interface::cached_pure_height (me, elts, common, start, end);
+
+ Interval r;
+
+ for (vsize i = 0; i < elts.size (); i++)
+ {
+ Interval_t<int> rank_span = elts[i]->spanned_rank_iv ();
+ Item *it = dynamic_cast<Item*> (elts[i]);
+ if (rank_span[LEFT] <= end && rank_span[RIGHT] >= start && (!it || it->pure_is_visible (start, end)))
+ {
+ Interval dims = elts[i]->pure_height (common, start, end);
+ if (!dims.is_empty ())
+ r.unite (dims);
+ }
+ }
+ return r;
+}
+
+MAKE_SCHEME_CALLBACK (Axis_group_interface, width, 1);
+SCM
+Axis_group_interface::width (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ return generic_group_extent (me, X_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Axis_group_interface, height, 1);
+SCM
+Axis_group_interface::height (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ return generic_group_extent (me, Y_AXIS);
+}