]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix drastic overestimation of staff heights.
authorJoe Neeman <joeneeman@gmail.com>
Fri, 1 Oct 2010 23:10:54 +0000 (16:10 -0700)
committerJoe Neeman <joeneeman@gmail.com>
Fri, 1 Oct 2010 23:16:03 +0000 (16:16 -0700)
The outside-staff simulation in f530eeb5bba has severe problems
when there many outside-staff objects per bar. This patch
mitigates the problems by assuming that outside-staff objects
don't intersect with each other (but only with the staff).

flower/include/interval.hh
flower/include/interval.tcc
input/regression/page-breaking-outside-staff-estimation2.ly [new file with mode: 0644]
lily/axis-group-interface.cc

index 4a08e278137a10be63df24f957943f389e265327..512200f6cf035b70f6f97a83318c469b2a0c04ac 100644 (file)
@@ -73,6 +73,7 @@ struct Interval_t : public Drul_array<T>
   void set_full ();
 
   void unite_disjoint (Interval_t<T> h, T padding, Direction d);
+  Interval_t<T> union_disjoint (Interval_t<T> h, T padding, Direction d) const;
 
   bool is_empty () const
   {
index 7a1440a31986b55a6bff52cd7df734f0665da8b0..35dd8ebb29013f348905f84726833ebcf02b52c3 100644 (file)
@@ -123,6 +123,15 @@ Interval_t<T>::unite_disjoint (Interval_t<T> h, T padding, Direction d)
   unite (h);
 }
 
+template<class T>
+Interval_t<T>
+Interval_t<T>::union_disjoint (Interval_t<T> h, T padding, Direction d) const
+{
+  Interval_t<T> iv = *this;
+  iv.unite_disjoint (h, padding, d);
+  return iv;
+}
+
 template<class T>
 void
 Interval_t<T>::intersect (Interval_t<T> h)
diff --git a/input/regression/page-breaking-outside-staff-estimation2.ly b/input/regression/page-breaking-outside-staff-estimation2.ly
new file mode 100644 (file)
index 0000000..6a33ca7
--- /dev/null
@@ -0,0 +1,12 @@
+\version "2.13.35"
+
+\header {
+  texidoc = "The height-estimation routine doesn't get confused
+by multiple outside-staff grobs in the same measure."
+}
+
+#(set-default-paper-size "a7")
+
+\book {
+  \repeat unfold 4 { \repeat unfold 4 {g'''4^"Text"} \break}
+}
index 1ec518feff52bd95ed7ac0a7d5e86590539291d0..85d2d3658889ffc806d823984d7c29d2c8c1b61a 100644 (file)
@@ -143,14 +143,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)
@@ -165,6 +163,8 @@ Axis_group_interface::adjacent_pure_heights (SCM smob)
 
   vector<Interval> begin_line_heights;
   vector<Interval> mid_line_heights;
+  vector<Interval> begin_line_staff_heights;
+  vector<Interval> mid_line_staff_heights;
   begin_line_heights.resize (ranks.size () - 1);
   mid_line_heights.resize (ranks.size () - 1);
 
@@ -178,6 +178,18 @@ Axis_group_interface::adjacent_pure_heights (SCM smob)
       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;
@@ -205,14 +217,16 @@ Axis_group_interface::adjacent_pure_heights (SCM smob)
                  if (rank_span[LEFT] <= start)
                    {
                      if (outside_staff)
-                       begin_line_heights[j].unite_disjoint (dims, padding, d);
+                       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_disjoint (dims, padding, d);
+                       mid_line_heights[j].unite (
+                            mid_line_staff_heights[j].union_disjoint (dims, padding, d));
                      else
                        mid_line_heights[j].unite (dims);
                    }