]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/page-breaking.cc
Merge branch 'master' into nested-bookparts
[lilypond.git] / lily / page-breaking.cc
index be11ffa3eaf45790b4182c8ace501426c43e64ad..10a428de5bd2521c8c5d3da3e9e023db6ba626f3 100644 (file)
@@ -98,6 +98,7 @@ Page_breaking::next_system (Break_position const &break_pos) const
 Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break)
 {
   book_ = pb;
+  system_count_ = 0;
   ragged_ = to_boolean (pb->paper_->c_variable ("ragged-bottom"));
   ragged_last_ = to_boolean (pb->paper_->c_variable ("ragged-last-bottom"));
   page_top_space_ = robust_scm2double (pb->paper_->c_variable ("page-top-space"), 0);
@@ -127,6 +128,12 @@ Page_breaking::page_top_space () const
   return page_top_space_;
 }
 
+vsize
+Page_breaking::system_count () const
+{
+  return system_count_;
+}
+
 /* translate indices into breaks_ into start-end parameters for the line breaker */
 void
 Page_breaking::line_breaker_args (vsize sys,
@@ -247,20 +254,23 @@ Page_breaking::make_pages (vector<vsize> lines_per_page, SCM systems)
   SCM book = book_->self_scm ();
   int first_page_number
     = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
+  bool last_part = ly_scm2bool (book_->paper_->c_variable ("part-is-last"));
   SCM ret = SCM_EOL;
-  SCM label_page_table = SCM_EOL;
+  SCM label_page_table = book_->top_paper ()->c_variable ("label-page-table");
+  if (label_page_table == SCM_UNDEFINED)
+    label_page_table = SCM_EOL;
 
   for (vsize i = 0; i < lines_per_page.size (); i++)
     {
       SCM page_num = scm_from_int (i + first_page_number);
-      SCM last = scm_from_bool (i == lines_per_page.size () - 1);
-      SCM rag = scm_from_bool (ragged () || (to_boolean (last)
-                                            && ragged_last ()));
+      bool last_from_part = (i == lines_per_page.size () - 1);
+      SCM last_from_book = scm_from_bool (last_part && last_from_part);
+      SCM rag = scm_from_bool (ragged () || (last_from_part && ragged_last ()));
       SCM line_count = scm_from_int (lines_per_page[i]);
       SCM lines = scm_list_head (systems, line_count);
       SCM page = scm_apply_0 (make_page,
                              scm_list_n (book, lines, page_num,
-                                         rag, last, SCM_UNDEFINED));
+                                         rag, last_from_book, SCM_UNDEFINED));
 
       /* collect labels */
       for (SCM l = lines ; scm_is_pair (l)  ; l = scm_cdr (l))
@@ -283,7 +293,7 @@ Page_breaking::make_pages (vector<vsize> lines_per_page, SCM systems)
       ret = scm_cons (page, ret);
       systems = scm_list_tail (systems, line_count);
     }
-  book_->paper_->set_variable (ly_symbol2scm ("label-page-table"), label_page_table);
+  book_->top_paper ()->set_variable (ly_symbol2scm ("label-page-table"), label_page_table);
   ret = scm_reverse (ret);
   return ret;
 }
@@ -451,6 +461,7 @@ Page_breaking::set_current_breakpoints (vsize start,
                                        Line_division lower_bound,
                                        Line_division upper_bound)
 {
+  system_count_ = system_count;
   current_chunks_ = chunk_list (start, end);
   current_start_breakpoint_ = start;
   current_end_breakpoint_ = end;
@@ -506,6 +517,7 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end)
   current_start_breakpoint_ = start;
   current_end_breakpoint_ = end;
   clear_line_details_cache ();
+  system_count_ = 0;
 
   Line_division div;
   for (vsize i = 0; i+1 < current_chunks_.size (); i++)
@@ -518,6 +530,8 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end)
        }
       else
        div.push_back (1);
+
+      system_count_ += div.back ();
     }
   current_configurations_.clear ();
   current_configurations_.push_back (div);
@@ -676,16 +690,19 @@ Page_spacing_result
 Page_breaking::space_systems_on_n_pages (vsize configuration, vsize n, vsize first_page_num)
 {
   Page_spacing_result ret;
-  assert (n >= min_page_count (configuration, first_page_num));
 
   cache_line_details (configuration);
-  if (n > cached_line_details_.size ())
-    return Page_spacing_result ();
-  if (n == 1)
+  bool valid_n = (n >= min_page_count (configuration, first_page_num)
+                 && n <= cached_line_details_.size ());
+
+  if (!valid_n)
+    programming_error ("number of pages is out of bounds");
+
+  if (n == 1 && valid_n)
     ret = space_systems_on_1_page (cached_line_details_,
                                   page_height (first_page_num, is_last ()),
                                   ragged () || (is_last () && ragged_last ()));
-  else if (n == 2)
+  else if (n == 2 && valid_n)
     ret = space_systems_on_2_pages (configuration, first_page_num);
   else
     {
@@ -699,7 +716,19 @@ Page_breaking::space_systems_on_n_pages (vsize configuration, vsize n, vsize fir
 Real
 Page_breaking::blank_page_penalty () const
 {
-  SCM penalty_sym = is_last () ? ly_symbol2scm ("blank-last-page-force") : ly_symbol2scm ("blank-page-force");
+  SCM penalty_sym;
+
+  if (is_last ())
+    penalty_sym = ly_symbol2scm ("blank-last-page-force");
+  else if (ends_score ())
+    penalty_sym = ly_symbol2scm ("blank-after-score-page-force");
+  else
+    penalty_sym = ly_symbol2scm ("blank-page-force");
+
+  Break_position const &pos = breaks_[current_end_breakpoint_];
+  if (Paper_score *ps = system_specs_[pos.system_spec_index_].pscore_)
+    return robust_scm2double (ps->layout ()->lookup_variable (penalty_sym), 0.0);
+
   return robust_scm2double (book_->paper_->lookup_variable (penalty_sym), 0.0);
 }
 
@@ -711,8 +740,12 @@ Page_breaking::space_systems_on_n_or_one_more_pages (vsize configuration, vsize
 
   cache_line_details (configuration);
   vsize min_p_count = min_page_count (configuration, first_page_num);
+  bool valid_n = n >= min_p_count || n <= cached_line_details_.size ();
+
+  if (!valid_n)
+    programming_error ("both page counts are out of bounds");
 
-  if (n == 1)
+  if (n == 1 && valid_n)
     {
       bool rag = ragged () || (is_last () && ragged_last ());
       Real height = page_height (first_page_num, is_last ());
@@ -726,9 +759,9 @@ Page_breaking::space_systems_on_n_or_one_more_pages (vsize configuration, vsize
     {
       Page_spacer ps (cached_line_details_, first_page_num, this);
       
-      if (n >= min_p_count)
+      if (n >= min_p_count || !valid_n)
        n_res = ps.solve (n);
-      if (n < cached_line_details_.size ())
+      if (n < cached_line_details_.size () || !valid_n)
        m_res = ps.solve (n+1);
     }
 
@@ -990,6 +1023,12 @@ Page_breaking::is_last () const
   return current_end_breakpoint_ == last_break_position ();
 }
 
+bool
+Page_breaking::ends_score () const
+{
+  return breaks_[current_end_breakpoint_].score_ender_;
+}
+
 vsize
 Page_breaking::last_break_position () const
 {