]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/system.cc
Merge branch 'master' of ssh+git://jneem@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / lily / system.cc
index 54562cdc04be4608b83f0a4c8e48f6ff0772f8f2..90eb463c44932ac307902bd3e8a7e5e210b7984f 100644 (file)
@@ -24,6 +24,8 @@
 #include "tweak-registration.hh"
 #include "warn.hh"
 
+extern bool debug_skylines;
+
 System::System (System const &src, int count)
   : Spanner (src, count)
 {
@@ -186,6 +188,13 @@ System::get_paper_systems ()
       System *system = dynamic_cast<System *> (broken_intos_[i]);
 
       system->post_processing ();
+      system->build_skylines ();
+      if (i > 0)
+       {
+         System *prev = dynamic_cast<System*> (broken_intos_[i-1]);
+         Real r = prev->skylines_[DOWN].distance (system->skylines_[UP]);
+         system->set_property ("skyline-distance", scm_from_double (r));
+       }
       scm_vector_set_x (lines, scm_from_int (i),
                        system->get_paper_system ());
 
@@ -317,7 +326,7 @@ System::post_processing ()
      anyway. */
 
   vector<Grob*> all_elts_sorted (all_elements_->array ());
-  vector_sort (all_elts_sorted, default_compare);
+  vector_sort (all_elts_sorted, std::less<Grob*> ());
   uniq (all_elts_sorted);
   this->get_stencil ();
   for (vsize i = all_elts_sorted.size (); i--;)
@@ -357,7 +366,7 @@ System::get_paper_system ()
       entries.push_back (e); 
     }
 
-  vector_sort (entries, default_compare);
+  vector_sort (entries, std::less<Layer_entry> ());
   for (vsize j = 0; j < entries.size (); j++)
     {
       Grob *g = entries[j].grob_;
@@ -391,6 +400,11 @@ System::get_paper_system ()
   Stencil sys_stencil (Box (x, y),
                       scm_cons (ly_symbol2scm ("combine-stencil"),
                                 exprs));
+  if (debug_skylines)
+    {
+      sys_stencil.add_stencil (points_to_line_stencil (skylines_[UP].to_points ()).in_color (255, 0, 0));
+      sys_stencil.add_stencil (points_to_line_stencil (skylines_[DOWN].to_points ()).in_color (0, 255, 0));
+    }
 
   Grob *left_bound = this->get_bound (LEFT);
   SCM prop_init = left_bound->get_property ("line-break-system-details");
@@ -399,11 +413,12 @@ System::get_paper_system ()
 
   /* information that the page breaker might need */
   Grob *right_bound = this->get_bound (RIGHT);
+  pl->set_property ("skyline-distance", get_property ("skyline-distance"));
   pl->set_property ("page-break-permission", right_bound->get_property ("page-break-permission"));
   pl->set_property ("page-turn-permission", right_bound->get_property ("page-turn-permission"));
   pl->set_property ("page-break-penalty", right_bound->get_property ("page-break-penalty"));
   pl->set_property ("page-turn-penalty", right_bound->get_property ("page-turn-penalty"));
-  
+
   if (!scm_is_pair (pl->get_property ("refpoint-Y-extent")))
     {
       Interval staff_refpoints;
@@ -430,17 +445,18 @@ System::broken_col_range (Item const *left, Item const *right) const
   left = left->get_column ();
   right = right->get_column ();
 
+  
   extract_grob_set (this, "columns", cols);
-  vsize i = 0;
-  while (i < cols.size ()
-        && cols[i] != left)
-    i++;
 
+  vsize i = binary_search (cols, (Grob *) left,
+                          Paper_column::less_than);
+
+  int end_rank = Paper_column::get_rank (right);
   if (i < cols.size ())
     i++;
 
   while (i < cols.size ()
-        && cols[i] != right)
+        && Paper_column::get_rank (cols[i]) < end_rank)
     {
       Paper_column *c = dynamic_cast<Paper_column *> (cols[i]);
       if (Paper_column::is_breakable (c) && !c->system_)
@@ -451,6 +467,7 @@ System::broken_col_range (Item const *left, Item const *right) const
   return ret;
 }
 
+
 /** Return all columns, but filter out any unused columns , since they might
     disrupt the spacing problem. */
 vector<Grob*>
@@ -499,9 +516,30 @@ get_root_system (Grob *me)
   return dynamic_cast<System*> (system_grob); 
 }
 
+void
+System::build_skylines ()
+{
+  vector<Box> boxes;
+  for (vsize i = 0; i < all_elements_->size (); i++)
+    {
+      Grob *g = all_elements_->grob (i);
+      if (!unsmob_stencil (g->get_property ("stencil")))
+       continue;
+
+      Interval xiv = g->extent (this, X_AXIS);
+      Interval yiv = g->extent (this, Y_AXIS);
+      if (!xiv.is_empty () && !yiv.is_empty ())
+       boxes.push_back (Box (xiv, yiv));
+    }
+
+  SCM horizon_padding_scm = get_property ("skyline-horizontal-padding");
+  Real horizon_padding = robust_scm2double (horizon_padding_scm, 0);
+  skylines_[UP] = Skyline (boxes, horizon_padding, X_AXIS, UP);
+  skylines_[DOWN] = Skyline (boxes, horizon_padding, X_AXIS, DOWN);
+}
 
 
-ADD_INTERFACE (System, "system-interface",
+ADD_INTERFACE (System,
               "This is the toplevel object: each object in a score "
               "ultimately has a System object as its X and Y parent. ",
 
@@ -510,4 +548,6 @@ ADD_INTERFACE (System, "system-interface",
               "columns "
               "pure-Y-extent "
               "spaceable-staves "
+              "skyline-distance "
+              "skyline-horizontal-padding "
               )