]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add regression test
authorCarl Sorensen <c_sorensen@byu.edu>
Fri, 17 Dec 2010 23:14:02 +0000 (16:14 -0700)
committerCarl Sorensen <c_sorensen@byu.edu>
Tue, 11 Jan 2011 18:27:54 +0000 (11:27 -0700)
Fix issue 1290

Add optional horizontal-padding argument to Skyline::distance call
If horizontal padding is non-zero, the padding will be added
for making the distance comparison.  Padding is added during
System comparison, so Systems can be farther apart than staves
within systems.

Add default value of skyline-horizontal-padding to the System grob.

Add regression test for this behavior, which includes an override.

input/regression/skyline-horizontal-padding.ly [new file with mode: 0644]
lily/include/skyline.hh
lily/page-layout-problem.cc
lily/skyline.cc
scm/define-grobs.scm

diff --git a/input/regression/skyline-horizontal-padding.ly b/input/regression/skyline-horizontal-padding.ly
new file mode 100644 (file)
index 0000000..1bb47de
--- /dev/null
@@ -0,0 +1,27 @@
+\version "2.13.46"
+
+\header {
+  texidoc = "
+The skyline-horizontal-padding property can be set for System
+in order to keep systems from being spaced too closely together.
+In this example, the low notes from a system should not be
+interleaved with the high notes from the next system.
+"
+}
+
+\book {
+  \score {
+    {
+      \override Staff.TimeSignature #'stencil =  ##f
+      \repeat unfold 3 { <c'''-1 e'''-3 g'''-5> c' <c,-1 e,-3 g,-5> c' \break}
+    }
+    \layout {
+      indent = 0
+      ragged-right = ##t
+      \context {
+        \Score
+       \override System #'skyline-horizontal-padding = #1.5
+      }
+    }
+  }
+}
index a11b21dde6ce27d06a3e54b177e32940da779589..93b6e1155605d4c03fb8d8b566c40bf8ce80bd6e 100644 (file)
@@ -53,7 +53,7 @@ class Skyline
 private:
   list<Building> buildings_;
   Direction sky_;
-  
+
   void internal_merge_skyline (list<Building>*, list<Building>*,
                               list<Building> *const result);
   list<Building> internal_build_skyline (list<Box>*, Real, Axis, Direction);
@@ -63,10 +63,11 @@ private:
 public:
   Skyline ();
   Skyline (Skyline const &src);
+  Skyline (Skyline const &src, Real horizon_padding, Axis a);
   Skyline (Direction sky);
   Skyline (vector<Box> const &bldgs, Real horizon_padding, Axis a, Direction sky);
   Skyline (Box const &b, Real horizon_padding, Axis a, Direction sky);
-  
+
   vector<Offset> to_points (Axis) const;
   void merge (Skyline const &);
   void insert (Box const &, Real horizon_padding, Axis);
@@ -74,7 +75,7 @@ public:
   void print_points () const;
   void raise (Real);
   void shift (Real);
-  Real distance (Skyline const &) const;
+  Real distance (Skyline const &, Real horizon_padding = 0) const;
   Real height (Real airplane) const;
   Real max_height () const;
   void set_minimum_height (Real height);
index 673278f69c6fc9490ab118d406610531064b6d9e..8be181ae950a135b7fc76b0d45c796aec8233671 100644 (file)
@@ -201,7 +201,13 @@ Page_layout_problem::append_system (System *sys, Spring const& spring, Real inde
   up_skyline.shift (indent);
   down_skyline.shift (indent);
 
-  Real minimum_distance = up_skyline.distance (bottom_skyline_) + padding;
+  /*
+    We need to call distance with skyline-horizontal-padding because
+    the system skyline-horizontal-padding is not added during the creation
+    of an individual staff.  So we add the padding for the distance check
+    at the time of adding in the system.
+  */
+  Real minimum_distance = up_skyline.distance (bottom_skyline_, robust_scm2double (sys->get_property ("skyline-horizontal-padding"), 0)) + padding;
 
   Spring spring_copy = spring;
   spring_copy.ensure_min_distance (minimum_distance);
index d8105e669b910eaadc3fe8e34286ae9d613c8e50..b28c6ff6622aae51d5f135027b5670ea749d813c 100644 (file)
@@ -119,7 +119,7 @@ Building::precompute (Real start, Real start_height, Real end_height, Real end)
     y_intercept_ = start_height - slope_ * start;
 }
 
-Real 
+Real
 Building::height (Real x) const
 {
   return isinf (x) ? y_intercept_ : slope_*x + y_intercept_;
@@ -248,7 +248,7 @@ single_skyline (Building b, Real start, Real horizon_padding, list<Building> *co
                               -infinity_f, infinity_f));
   if (sloped_neighbours)
     ret->push_front (b.sloped_neighbour (start, horizon_padding, RIGHT));
-  
+
   if (b.end_ > start + EPS)
     ret->push_front (b);
 
@@ -367,7 +367,7 @@ Skyline::Skyline ()
 Skyline::Skyline (Skyline const &src)
 {
   sky_ = src.sky_;
+
   /* doesn't a list's copy constructor do this? -- jneem */
   for (list<Building>::const_iterator i = src.buildings_.begin ();
        i != src.buildings_.end (); i++)
@@ -382,6 +382,37 @@ Skyline::Skyline (Direction sky)
   empty_skyline (&buildings_);
 }
 
+/*
+  build padded skyline from an existing skyline with padding
+  added to it.
+*/
+
+Skyline::Skyline (Skyline const &src, Real horizon_padding, Axis a)
+{
+  /*
+     We extract boxes from the skyline, then build a new skyline from
+     the boxes.
+     A box is created for every horizontal portion of the skyline
+     Because skylines are defined positive, and then inverted if they
+     are to be down-facing, we create the new skyline in the UP
+     direction, then give it the down direction if needed.
+  */
+  Real start = -infinity_f;
+  list<Box> boxes;
+
+  // establish a baseline box
+  boxes.push_back (Box (Interval (-infinity_f, infinity_f),
+                       Interval (0, 0)));
+  list<Building>::const_iterator end = src.buildings_.end ();
+  for (list<Building>::const_iterator i = src.buildings_.begin (); i != end; start=i->end_, i++ )
+    if ((i->slope_ == 0) && !isinf (i->y_intercept_))
+      boxes.push_back (Box (Interval (start, i->end_),
+                           Interval (-infinity_f , i->y_intercept_)));
+  buildings_ = internal_build_skyline (&boxes, horizon_padding, X_AXIS, UP);
+  sky_ = src.sky_;
+}
+
+
 /*
   build skyline from a set of boxes. If horizon_padding > 0, expand all the boxes
   by that amount and add 45-degree sloped boxes to the edges of each box (of
@@ -404,7 +435,7 @@ Skyline::Skyline (vector<Box> const &boxes, Real horizon_padding, Axis horizon_a
       if (iv.length () > EPS && !boxes[i][vert_axis].is_empty ())
        filtered_boxes.push_front (boxes[i]);
     }
-  
+
   buildings_ = internal_build_skyline (&filtered_boxes, horizon_padding, horizon_axis, sky);
 }
 
@@ -470,15 +501,31 @@ Skyline::shift (Real s)
 }
 
 Real
-Skyline::distance (Skyline const &other) const
+Skyline::distance (Skyline const &other, Real horizon_padding) const
 {
   assert (sky_ == -other.sky_);
-  list<Building>::const_iterator i = buildings_.begin ();
-  list<Building>::const_iterator j = other.buildings_.begin ();
+
+  Skyline const *padded_this = this;
+  Skyline const *padded_other = &other;
+
+  /*
+    For systems, padding is not added at creation time.  Padding is
+    added to AxisGroup objects when outside-staff objects are added.
+    Thus, when we want to place systems with horizontal padding,
+    we do it at distance calculation time.
+  */
+  if (horizon_padding != 0.0)
+    {
+      padded_this = new Skyline (*padded_this, horizon_padding, X_AXIS);
+      padded_other = new Skyline (*padded_other, horizon_padding, X_AXIS);
+    }
+
+  list<Building>::const_iterator i = padded_this->buildings_.begin ();
+  list<Building>::const_iterator j = padded_other->buildings_.begin ();
 
   Real dist = -infinity_f;
   Real start = -infinity_f;
-  while (i != buildings_.end () && j != other.buildings_.end ())
+  while (i != padded_this->buildings_.end () && j != padded_other->buildings_.end ())
     {
       Real end = min (i->end_, j->end_);
       Real start_dist = i->height (start) + j->height (start);
index ff076f8d1566510c16a10bf5846b848725c0fab0..01a07313b41200803d8dab1529b395ebf77ffc92 100644 (file)
      . (
        (adjacent-pure-heights . ,ly:axis-group-interface::adjacent-pure-heights)
        (axes . (,X ,Y))
+       (skyline-horizontal-padding . 0.5)
        (vertical-skylines . ,ly:axis-group-interface::calc-skylines)
        (X-extent . ,ly:axis-group-interface::width)
        (Y-extent . ,ly:system::height)