]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/optimal-page-breaking.cc
Merge branch 'master' of git+ssh://jneem@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / lily / optimal-page-breaking.cc
index 6f3fcc5683124a6e6915673fa4b00f79b48fe030..d18ad2837e92ffe2104f0a4ae326bea06b0cc38e 100644 (file)
@@ -5,7 +5,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2006 Joe Neeman <joeneeman@gmail.com>
+  (c) 2006--2007 Joe Neeman <joeneeman@gmail.com>
 */
 
 #include "optimal-page-breaking.hh"
@@ -39,8 +39,8 @@ Optimal_page_breaking::try_page_spacing (Line_division const &line_count)
   Real page_h = page_height (1, false); // FIXME
   SCM force_sym = ly_symbol2scm ("blank-last-page-force");
   Real blank_force = robust_scm2double (book_->paper_->lookup_variable (force_sym), 0);
-  bool ragged_all = book_->paper_->c_variable ("ragged-bottom");
-  bool ragged_last = book_->paper_->c_variable ("ragged-last-bottom");
+  bool ragged_all = to_boolean (book_->paper_->c_variable ("ragged-bottom"));
+  bool ragged_last = to_boolean (book_->paper_->c_variable ("ragged-last-bottom"));
   Spacing_result ret = space_systems_on_best_pages (lines,
                                                    page_h,
                                                    blank_force,
@@ -50,21 +50,23 @@ Optimal_page_breaking::try_page_spacing (Line_division const &line_count)
   /* add in the line penalties */
   Real line_force = 0;
   Real line_penalty = 0;
-  Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 1);
+  Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 10);
 
   for (vsize i = 0; i < lines.size (); i++)
     {
-      line_force += fabs (lines[i].force_);
+      line_force += lines[i].force_ * lines[i].force_;
       line_penalty += lines[i].break_penalty_;
     }
 
   ret.demerits_ = ret.force_[0] * ret.force_[0] * page_weighting;
   for (vsize i = 1; i < ret.force_.size (); i++)
-    {
-      Real uniformity = fabs (ret.force_[i] - ret.force_[i-1]);
-      ret.demerits_ += (ret.force_[i] * ret.force_[i]
-                      + uniformity * uniformity) * page_weighting;
-    }
+    ret.demerits_ += ret.force_[i] * ret.force_[i] * page_weighting;
+
+  /* for a while we tried averaging page and line forces instead of summing
+     them, but it caused the following problem. If there is a single page
+     with a very bad page force (for example because of a forced page break),
+     the page breaker will put in a _lot_ of pages so that the bad force
+     becomes averaged out over many pages. */
   ret.demerits_ += line_force + line_penalty;
   return ret;
 }
@@ -91,13 +93,13 @@ Optimal_page_breaking::solve ()
        {
          Spacing_result cur = try_page_spacing (div[d]);
          cur_page_count = cur.systems_per_page_.size ();
-         if (cur.demerits_ < best.demerits_)
+         if (cur.demerits_ < best.demerits_ || isinf (best.demerits_))
            {
              best = cur;
              best_division = div[d];
            }
 
-         if (cur.demerits_ < this_best_demerits)
+         if (cur.demerits_ < this_best_demerits || isinf (best.demerits_))
            {
              this_best_demerits = cur.demerits_;
              lower_bound = div[d];
@@ -110,7 +112,7 @@ Optimal_page_breaking::solve ()
              all_lines_stretched = false;
 
          if (all_lines_stretched)
-           max_page_count = cur_page_count + 1;
+           max_page_count = min (max_page_count, cur_page_count + 1);
        }
     }