]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/axis-group-interface.cc
Merge branch 'master' of git://git.savannah.gnu.org/lilypond.git
[lilypond.git] / lily / axis-group-interface.cc
index 25952d6783d026593379f480bd3a8d4cc0ba14b3..e0bd31663f89d1134018b224976ffc237adfb7d8 100644 (file)
@@ -90,7 +90,7 @@ Axis_group_interface::relative_group_extent (vector<Grob*> 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));
@@ -99,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<Spanner*> (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);
+
+      if (scm_is_vector (these_pure_heights))
+       ret = combine_pure_heights (me, these_pure_heights, start, end);
+      else
+       ret = Interval (0, 0);
+    }
 
-  return combine_pure_heights (me, scm_cdr (adjacent_pure_heights), start, end);
+  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
@@ -260,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);
@@ -646,6 +666,15 @@ add_grobs_of_one_priority (Skyline_pair *const skylines,
     }
 }
 
+bool
+Axis_group_interface::has_outside_staff_parent (Grob *me)
+{
+  return (me
+          ? (scm_is_number (me->get_property ("outside-staff-priority"))
+             || has_outside_staff_parent (me->get_parent (Y_AXIS)))
+          : false);
+}
+
 // TODO: it is tricky to correctly handle skyline placement of cross-staff grobs.
 // For example, cross-staff beams cannot be formatted until the distance between
 // staves is known and therefore any grobs that depend on the beam cannot be placed
@@ -679,7 +708,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector<Grob*> elements)
   Skyline_pair skylines;
   for (i = 0; i < elements.size ()
         && !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++)
-    if (!to_boolean (elements[i]->get_property ("cross-staff")))
+    if (!(to_boolean (elements[i]->get_property ("cross-staff")) || has_outside_staff_parent (elements[i])))
       add_boxes (elements[i], x_common, y_common, &boxes, &skylines);
 
   SCM padding_scm = me->get_property ("skyline-horizontal-padding");
@@ -753,11 +782,11 @@ Axis_group_interface::calc_maybe_pure_staff_staff_spacing (Grob *me, bool pure,
 
   if (grouper)
     {
-      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 ("staffgroup-staff-spacing", pure, start, end);
-      else
+      bool within_group = Staff_grouper_interface::maybe_pure_within_group (grouper, me, pure, start, end);
+      if (within_group)
        return grouper->get_maybe_pure_property ("staff-staff-spacing", pure, start, end);
+      else
+       return grouper->get_maybe_pure_property ("staffgroup-staff-spacing", pure, start, end);
     }
   return me->get_maybe_pure_property ("default-staff-staff-spacing", pure, start, end);
 }