]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix page layout when system-count is given. Also fixes 325.
authorJoe Neeman <joeneeman@gmail.com>
Fri, 31 Jul 2009 16:31:10 +0000 (09:31 -0700)
committerJoe Neeman <joeneeman@gmail.com>
Fri, 31 Jul 2009 21:32:39 +0000 (14:32 -0700)
input/regression/page-spacing-system-count.ly [new file with mode: 0644]
lily/constrained-breaking.cc
lily/include/constrained-breaking.hh
lily/include/page-breaking.hh
lily/page-breaking.cc

diff --git a/input/regression/page-spacing-system-count.ly b/input/regression/page-spacing-system-count.ly
new file mode 100644 (file)
index 0000000..3758bd4
--- /dev/null
@@ -0,0 +1,22 @@
+\version "2.13.4"
+
+\header {
+  texidoc = "Page layout and stretching work with system-cound enabled."
+}
+
+#(set-default-paper-size "a6")
+
+\paper {
+  system-count = 2
+  ragged-last-bottom = ##f
+}
+
+\book {
+  \score {
+    <<
+      \relative c'' { \repeat unfold 10 c1 }
+      \relative c'' { \repeat unfold 10 c1 }
+      \relative c'' { \repeat unfold 10 c1 }
+    >>
+  }
+}
index 2d081e91ad65d2499ec6a6e7da7bea7428f2e19a..8fb24f1eab90f668b40e7de5eecd034547bf91e3 100644 (file)
@@ -372,6 +372,7 @@ Constrained_breaking::initialize ()
            break;
 
          Grob *c = all_[breaks_[j]];
+         line.last_column_ = c;
          line.break_penalty_ = robust_scm2double (c->get_property ("line-break-penalty"), 0);
          line.page_penalty_ = robust_scm2double (c->get_property ("page-break-penalty"), 0);
          line.turn_penalty_ = robust_scm2double (c->get_property ("page-turn-penalty"), 0);
index 48771545e4c2dfe644a8a23e74caaf3ae6c2f46f..8378a959e297777ed9ae612e4f85128504528b14 100644 (file)
@@ -15,6 +15,7 @@
 #include "prob.hh"
 
 struct Line_details {
+  Grob *last_column_;
   Real force_;
   Interval extent_;   /* Y-extent of the system */
 
@@ -43,6 +44,7 @@ struct Line_details {
 
   Line_details ()
   {
+    last_column_ = 0;
     force_ = infinity_f;
     padding_ = 0;
     bottom_padding_ = 0;
@@ -61,6 +63,7 @@ struct Line_details {
 
   Line_details (Prob *pb)
   {
+    last_column_ = 0;
     force_ = 0;
     extent_ = unsmob_stencil (pb->get_property ("stencil")) ->extent (Y_AXIS);
     padding_ = robust_scm2double (pb->get_property ("next-padding"), 0);
index ffeaebc5a19c320d6c76a485b74ea8e0e287f58e..e0b2abac33f48a6df6bf21762a04a874d5356365 100644 (file)
@@ -54,12 +54,17 @@ struct Break_position
   Grob *col_;  
   bool score_ender_;
 
+  /* if non-zero, this is the (fixed, uncompressed) number of lines between
+     this Break_position and the previous. */
+  int forced_line_count_;
+
   Break_position (vsize s=VPOS, vsize brk=VPOS, Grob *g=NULL, bool end=false)
   {
     system_spec_index_ = s;
     score_break_ = brk;
     col_ = g;
     score_ender_ = end;
+    forced_line_count_ = 0;
   }
 
   /*
index e03a5c97c154f6a2576378fe1cb4e3b74fae4fd3..8dc19ef3576adc8dff840bcf962fb2f8b65b6680 100644 (file)
@@ -488,14 +488,7 @@ Page_breaking::create_system_list ()
     {
       if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (scm_car (s))))
        {
-         SCM system_count = ps->layout ()->c_variable ("system-count");
-
-         if (scm_is_number (system_count))
-           s = scm_append (scm_list_3 (scm_list_1 (scm_car (s)),
-                                       scm_vector_to_list (ps->get_paper_systems ()),
-                                       scm_cdr (s)));
-         else
-           system_specs_.push_back (System_spec (ps));
+         system_specs_.push_back (System_spec (ps));
        }
       else
         {
@@ -520,8 +513,24 @@ Page_breaking::find_chunks_and_breaks (Break_predicate is_break)
     {
       if (system_specs_[i].pscore_)
        {
-         vector<Grob*> cols
-           = system_specs_[i].pscore_->root_system ()->used_columns ();
+         vector<Grob*> cols;
+
+         SCM system_count = system_specs_[i].pscore_->layout ()->c_variable ("system-count");
+         if (scm_is_number (system_count))
+           {
+             // With system-count given, the line configuration for
+             // this score is fixed.  We need to ensure that chunk
+             // boundaries only occur at line breaks.
+             Constrained_breaking breaking (system_specs_[i].pscore_);
+             vector<Line_details> details = breaking.line_details (0, VPOS, scm_to_int (system_count));
+
+             for (vsize j = 0; j < details.size (); j++)
+               cols.push_back (details[j].last_column_);
+           }
+         else
+           cols = system_specs_[i].pscore_->root_system ()->used_columns ();
+
+         int last_chunk_idx = -1;
          vector<vsize> line_breaker_columns;
          line_breaker_columns.push_back (0);
 
@@ -535,10 +544,22 @@ Page_breaking::find_chunks_and_breaks (Break_predicate is_break)
                                                       cols[j],
                                                       last);
 
+             // NOTE: even in the breaks_ list, forced_line_count_
+             // refers to the number of lines between a
+             // Break_position and the start of that /chunk/.  This
+             // is needed for system_count_bounds to work correctly,
+             // since it mixes Break_positions from breaks_ and
+             // chunks_.
+             if (scm_is_number (system_count))
+               cur_pos.forced_line_count_ = j - last_chunk_idx;
+
              if (break_point || (i == system_specs_.size () - 1 && last))
                breaks_.push_back (cur_pos);
              if (chunk_end || last)
-               chunks_.push_back (cur_pos);
+               {
+                 chunks_.push_back (cur_pos);
+                 last_chunk_idx = j;
+               }
 
              if ((break_point || chunk_end) && !last)
                line_breaker_columns.push_back (j);
@@ -614,7 +635,10 @@ Page_breaking::system_count_bounds (vector<Break_position> const &chunks,
   for (vsize i = 0; i + 1 < chunks.size (); i++)
     {
       vsize sys = next_system (chunks[i]);
-      if (system_specs_[sys].pscore_)
+
+      if (chunks[i+1].forced_line_count_)
+       ret[i] = chunks[i+1].forced_line_count_;
+      else if (system_specs_[sys].pscore_)
        {
          vsize start;
          vsize end;
@@ -697,7 +721,10 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end)
   for (vsize i = 0; i+1 < current_chunks_.size (); i++)
     {
       vsize sys = next_system (current_chunks_[i]);
-      if (system_specs_[sys].pscore_)
+
+      if (current_chunks_[i+1].forced_line_count_)
+       div.push_back (current_chunks_[i+1].forced_line_count_);
+      else if (system_specs_[sys].pscore_)
        {
          line_breaker_args (sys, current_chunks_[i], current_chunks_[i+1], &start, &end);
          div.push_back (line_breaking_[sys].best_solution (start, end).size ());