]> git.donarmstrong.com Git - lilypond.git/blob - lily/page-breaking.cc
bad
[lilypond.git] / lily / page-breaking.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2006--2011 Joe Neeman <joeneeman@gmail.com>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21   This is a utility class for page-breaking algorithms. There are some complex
22   parts of this class, some of which are useful to understand if you intend
23   to write a page breaking algorithm (ie. a subclass of Page_breaking). Most
24   of these complexities were introduced in order to break the problem of
25   page-breaking into simpler subproblems and to hide some of the bookkeeping
26   complexities of page breaking from the page breaking algorithms.
27
28   COMPRESSED LINES
29   There are several functions that actually distribute systems across pages
30   (for example, the space_systems_XXX and pack_systems_XXX functions). If
31   each of these functions had to handle \noPageBreak, it would be a mess.
32   Therefore, we handle \noPageBreak by "compressing" the list of systems
33   before doing any layout: we concatenate any two systems separated by a
34   \noPageBreak into a single system. The page-breaking functions can do their
35   magic without encountering a \noPageBreak; we then "uncompress" the systems
36   at the end. We almost always work with cached_line_details_, which are
37   "compressed."
38
39   CHUNKS
40   The basic operation of a page breaking algorithm is to repeatedly request
41   some systems from the line-breaker and place those systems on some pages.
42   With each repetition, the page breaking algorithm asks the line-breaker for
43   some systems that it thinks will help it achieve a better layout. The
44   Page_breaking class provides functionality to facilitate this in the case
45   that the page breaking algorithm only cares about the number of systems.
46
47   Even if a page breaking algorithm only cares number of systems, there may
48   be many ways to satisfy its request. For example, in a piece with 2 scores
49   and a request for 10 systems, we could return 5 systems from each score or
50   4 from the first and 6 from the second. Even within a score, we might
51   want to try several different line breaking configurations with a fixed
52   system count; if there is a forced \pageBreak, for example, we might wish
53   to tweak the number of systems on both sides of the \pageBreak independently.
54
55   The Page_breaking class takes care of finding these configurations. It
56   divides the piece into "chunks" and sets up the line-breaker in such a way
57   that the number of systems in each chunk can be modified independently.
58   Chunks never cross score boundaries; each title and markup is its own chunk.
59   When a page breaking algorithm requests a number of systems, the Page_breaker
60   stores an array of potential configurations, which the page breaking
61   algorithm can iterate over using current_configuration(vsize).
62
63   LINE_DIVISION
64   A Line_division is simply a way of storing the exact way in which the
65   total number of systems is distributed among chunks. Note that a
66   Line_division may not (in fact, usually will not) describe all of the chunks
67   in the entire book. Rather, it will describe the subset of chunks that lie
68   between some fixed starting and ending point. This subset of chunks changes
69   whenever a page breaking algorithm asks to consider a different pair of
70   starting and ending breakpoints. In particular, a Line_division should be
71   discarded after a call to set_current_breakpoints, since that Line_division
72   refers to a subset of chunks which might be different from the current
73   subset of chunks under consideration.
74
75   HOW TO WRITE A PAGE BREAKING ALGORITHM
76   All page breakers supported by this class work more-or-less in the same way.
77   First, they request a particular number of systems by saying
78     set_current_breakpoints (0, last_break_position (), system_count)
79   (never mind what the first two arguments do, I'll get to them later).
80   Alternatively, you can do
81     set_to_ideal_line_configuration (0, last_break_position ()),
82   and the number of systems will be automatically chosen according to what
83   the line breaker wants.
84
85   If there are multiple scores, there will be many different ways to achieve
86   a certain number of lines.  You can see how many alternatives are available
87   with current_configuration_count ().  For every i from 0 to
88   current_configuration_count ()-1, you can see the line division of the
89   corresponding configuration with current_configuration (i), or you can try
90   out various page configurations with one of the space_systems_xxx or
91   pack_systems_xxx functions.  The first argument to each of these functions
92   is the configuration index.
93
94   When you're done trying out configurations and you've picked the one
95   you want, do
96     break_into_pieces (0, last_break_position (), line_division_that_you_want);
97     return make_pages (systems_per_page, systems ());
98   where systems_per_page is a vector of numbers telling how many systems are
99   on each page.  You can get your systems_per_page vector by looking inside
100   the Page_spacing_results that are returned by space_systems_xxx or
101   pack_systems_xxx.
102
103   A note on performance: set_current_breakpoints is EXPONENTIALLY SLOW unless
104   you constrain it by giving it a lower or an upper bound on the configurations
105   it looks for.  Optimal_page_breaking, for example, works by trying
106   out a bunch of configurations, increasing the system count by one, trying
107   again and so on.  Each time we increase the system count, we assume that the
108   best new configurations are going to be elementwise larger than the
109   best configuration for the previous system count (in other words, we're going
110   to get a new configuration just by adding an extra line to sone score
111   and leaving the rest the same).  Therefore, we pass the best previous line
112   division as an lower bound to set_current_breakpoints.
113
114   Now you should be in a position to understand Optimal_page_breaking::solve.
115   Go ahead and read that before finding out, in the next paragraph,
116   what the first two arguments to set_current_breakpoints do.
117
118   "BREAKS"
119   Sometimes, it's useful to run this whole page-breaking machinery on a subset
120   of the book.  To do this, you can mark certain "breaks" in the book (a poor
121   choice of name, perhaps, since a "break" here is different from a page break)
122   and you can run page breaking between any two breaks.  You mark your breaks
123   by providing a Break_predicate (and, if you want, a Prob_break_predicate)
124   to Page_breaking's constructor.  You then choose a subset of your book
125   by passing the starting and ending breaks to set_current_breakpoints.  You
126   can see an example of this in Page_turn_page_breaking, where there is a break
127   everywhere that a page turn is allowed.
128 */
129
130 #include "page-breaking.hh"
131
132 #include "international.hh"
133 #include "item.hh"
134 #include "line-interface.hh"
135 #include "output-def.hh"
136 #include "page-layout-problem.hh"
137 #include "page-spacing.hh"
138 #include "paper-book.hh"
139 #include "paper-score.hh"
140 #include "paper-system.hh"
141 #include "text-interface.hh"
142 #include "system.hh"
143 #include "warn.hh"
144
145 /* for each forbidden page break, merge the systems around it into one
146    system. */
147 static vector<Line_details>
148 compress_lines (const vector<Line_details> &orig)
149 {
150   vector<Line_details> ret;
151
152   for (vsize i = 0; i < orig.size (); i++)
153     {
154       if (ret.size () && !scm_is_symbol (ret.back ().page_permission_))
155         {
156           Line_details const &old = ret.back ();
157           Line_details compressed = orig[i];
158           /*
159             We must account for the padding between the lines that we are compressing.
160             The padding values come from "old," which is the upper system here. Note
161             the meaning of tight-spacing: if a system has tight-spacing, then the padding
162             _before_ it is ignored.
163           */
164           Real padding = 0;
165           if (!orig[i].tight_spacing_)
166             padding = orig[i].title_ ? old.title_padding_ : old.padding_;
167
168           // FIXME: double check these. Doesn't foo.piggyback (bar) mean
169           // that foo goes on top?
170           // TODO: break out a Line_details::piggyback from here?
171           compressed.shape_ = old.shape_.piggyback (orig[i].shape_, padding);
172           compressed.refpoint_extent_[UP] = old.refpoint_extent_[UP];
173           compressed.refpoint_extent_[DOWN] += compressed.shape_.rest_[UP] - old.shape_.rest_[UP];
174           compressed.space_ += old.space_;
175           compressed.inverse_hooke_ += old.inverse_hooke_;
176
177           compressed.compressed_lines_count_ = old.compressed_lines_count_ + 1;
178           compressed.compressed_nontitle_lines_count_ =
179             old.compressed_nontitle_lines_count_ + (compressed.title_ ? 0 : 1);
180
181           // compressed.title_ is true if and only if the first of its
182           // compressed lines was a title.
183           compressed.title_ = old.title_;
184           
185           // take care of footnotes
186           compressed.footnotes_.insert (compressed.footnotes_.begin (),
187             old.footnotes_.begin (), old.footnotes_.end ());
188           
189           ret.back () = compressed;
190         }
191       else
192         {
193           ret.push_back (orig[i]);
194           ret.back ().force_ = 0;
195         }
196     }
197   return ret;
198 }
199
200 /* translate the number of systems-per-page into something meaningful for
201    the uncompressed lines.
202 */
203 static vector<vsize>
204 uncompress_solution (vector<vsize> const &systems_per_page,
205                      vector<Line_details> const &compressed)
206 {
207   vector<vsize> ret;
208   vsize start_sys = 0;
209
210   for (vsize i = 0; i < systems_per_page.size (); i++)
211     {
212       int compressed_count = 0;
213       for (vsize j = start_sys; j < start_sys + systems_per_page[i]; j++)
214         compressed_count += compressed[j].compressed_lines_count_ - 1;
215
216       ret.push_back (systems_per_page[i] + compressed_count);
217       start_sys += systems_per_page[i];
218     }
219   return ret;
220 }
221
222 /* for Page_breaking, the start index (when we are dealing with the stuff
223    between a pair of breakpoints) refers to the break_ index of the end of
224    the previous page. So the system index of the start of the current page
225    could either be the same as the end of the previous page or one more than
226    it. */
227
228 /* Turn a break index into the sys index that starts the next page */
229 vsize
230 Page_breaking::next_system (Break_position const &break_pos) const
231 {
232   vsize sys = break_pos.system_spec_index_;
233
234   if (sys == VPOS) /* beginning of the book */
235     return 0;
236   if (system_specs_[sys].pscore_ && !break_pos.score_ender_)
237     return sys; /* the score overflows the previous page */
238   return sys + 1; /* this page starts with a new System_spec */
239 }
240
241 Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break, Prob_break_predicate prob_break)
242 {
243   book_ = pb;
244   system_count_ = 0;
245   paper_height_ = robust_scm2double (pb->paper_->c_variable ("paper-height"), 1.0);
246   ragged_ = to_boolean (pb->paper_->c_variable ("ragged-bottom"));
247   ragged_last_ = to_boolean (pb->paper_->c_variable ("ragged-last-bottom"));
248   systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("systems-per-page"), 0));
249   max_systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("max-systems-per-page"), 0));
250   min_systems_per_page_ = max (0, robust_scm2int (pb->paper_->c_variable ("min-systems-per-page"), 0));
251   orphan_penalty_ = robust_scm2int (pb->paper_->c_variable ("orphan-penalty"), 100000);
252
253   Stencil *footnote_separator = Page_layout_problem::get_footnote_separator_stencil (pb->paper_);
254
255   if (footnote_separator)
256     {
257       Interval separator_extent = footnote_separator->extent (Y_AXIS);
258       Real separator_span = max (separator_extent[UP] - separator_extent[DOWN], 0.0);
259
260       footnote_separator_stencil_height_ = separator_span;
261     }
262   else
263     footnote_separator_stencil_height_ = 0.0;
264
265   footnote_padding_ = robust_scm2double (pb->paper_->c_variable ("footnote-padding"), 0.0);
266
267   if (systems_per_page_ && (max_systems_per_page_ || min_systems_per_page_))
268     {
269       warning (_f ("ignoring min-systems-per-page and max-systems-per-page because systems-per-page was set"));
270       min_systems_per_page_ = max_systems_per_page_ = 0;
271     }
272   if (max_systems_per_page_ && min_systems_per_page_ > max_systems_per_page_)
273     {
274       warning (_f ("min-systems-per-page is larger than max-systems-per-page, ignoring both values"));
275       min_systems_per_page_ = max_systems_per_page_ = 0;
276     }
277
278   create_system_list ();
279   find_chunks_and_breaks (is_break, prob_break);
280 }
281
282 Page_breaking::~Page_breaking ()
283 {
284 }
285
286 bool
287 Page_breaking::ragged () const
288 {
289   return ragged_;
290 }
291
292 bool
293 Page_breaking::ragged_last () const
294 {
295   return ragged_last_;
296 }
297
298 int
299 Page_breaking::systems_per_page () const
300 {
301   return systems_per_page_;
302 }
303
304 int
305 Page_breaking::max_systems_per_page () const
306 {
307   if (systems_per_page_)
308     return systems_per_page_;
309   return max_systems_per_page_;
310 }
311
312 int
313 Page_breaking::min_systems_per_page () const
314 {
315   if (systems_per_page_)
316     return systems_per_page_;
317   return min_systems_per_page_;
318 }
319
320 vsize
321 Page_breaking::system_count () const
322 {
323   return system_count_;
324 }
325
326 Real
327 Page_breaking::footnote_separator_stencil_height () const
328 {
329   return footnote_separator_stencil_height_;
330 }
331
332 Real
333 Page_breaking::footnote_padding () const
334 {
335   return footnote_padding_;
336 }
337
338 bool
339 Page_breaking::too_many_lines (int line_count) const
340 {
341   return max_systems_per_page () > 0 && line_count > max_systems_per_page ();
342 }
343
344 bool
345 Page_breaking::too_few_lines (int line_count) const
346 {
347   return line_count < min_systems_per_page ();
348 }
349
350 Real
351 Page_breaking::line_count_penalty (int line_count) const
352 {
353   if (too_many_lines (line_count))
354     return (line_count - max_systems_per_page ()) * TERRIBLE_SPACING_PENALTY;
355   if (too_few_lines (line_count))
356     return (min_systems_per_page () - line_count) * TERRIBLE_SPACING_PENALTY;
357
358   return 0;
359 }
360
361 int
362 Page_breaking::line_count_status (int line_count) const
363 {
364   if (too_many_lines (line_count))
365     return SYSTEM_COUNT_TOO_MANY;
366   if (too_few_lines (line_count))
367     return SYSTEM_COUNT_TOO_FEW;
368
369   return SYSTEM_COUNT_OK;
370 }
371
372 /* translate indices into breaks_ into start-end parameters for the line breaker */
373 void
374 Page_breaking::line_breaker_args (vsize sys,
375                                   Break_position const &start,
376                                   Break_position const &end,
377                                   vsize *line_breaker_start,
378                                   vsize *line_breaker_end)
379 {
380   assert (system_specs_[sys].pscore_);
381   assert (next_system (start) <= sys && sys <= end.system_spec_index_);
382
383   if (start.system_spec_index_ == sys)
384     *line_breaker_start = start.score_break_;
385   else
386     *line_breaker_start = 0;
387
388   if (end.system_spec_index_ == sys)
389     *line_breaker_end = end.score_break_;
390   else
391     *line_breaker_end = VPOS;
392 }
393
394 void
395 Page_breaking::break_into_pieces (vsize start_break, vsize end_break,
396                                   Line_division const &div)
397 {
398   vector<Break_position> chunks = chunk_list (start_break, end_break);
399   bool ignore_div = false;
400   if (chunks.size () != div.size () + 1)
401     {
402       programming_error ("did not find a valid page breaking configuration");
403       ignore_div = true;
404     }
405
406   for (vsize i = 0; i + 1 < chunks.size (); i++)
407     {
408       vsize sys = next_system (chunks[i]);
409       if (system_specs_[sys].pscore_)
410         {
411           vsize start;
412           vsize end;
413           line_breaker_args (sys, chunks[i], chunks[i+1], &start, &end);
414
415           vector<Column_x_positions> pos = ignore_div
416             ? line_breaking_[sys].best_solution (start, end)
417             : line_breaking_[sys].solve (start, end, div[i]);
418           system_specs_[sys].pscore_->root_system ()->break_into_pieces (pos);
419         }
420     }
421 }
422
423 SCM
424 Page_breaking::systems ()
425 {
426   SCM ret = SCM_EOL;
427   for (vsize sys = 0; sys < system_specs_.size (); sys++)
428     {
429       if (system_specs_[sys].pscore_)
430         {
431           system_specs_[sys].pscore_->root_system ()
432             ->do_break_substitution_and_fixup_refpoints ();
433           SCM lines = system_specs_[sys].pscore_->root_system ()
434             ->get_broken_system_grobs ();
435           ret = scm_cons (lines, ret);
436         }
437       else if (Prob *pb = system_specs_[sys].prob_)
438         {
439           ret = scm_cons (scm_list_1 (pb->self_scm ()), ret);
440           pb->unprotect ();
441         }
442     }
443   return scm_append (scm_reverse (ret));
444 }
445
446 SCM
447 Page_breaking::make_page (int page_num, bool last) const
448 {
449   bool last_part = ly_scm2bool (book_->paper_->c_variable ("is-last-bookpart"));
450   SCM mod = scm_c_resolve_module ("scm page");
451   SCM make_page_scm = scm_c_module_lookup (mod, "make-page");
452
453   make_page_scm = scm_variable_ref (make_page_scm);
454
455   return scm_apply_0 (make_page_scm,
456                       scm_list_n (book_->self_scm (),
457                                   ly_symbol2scm ("page-number"), scm_from_int (page_num),
458                                   ly_symbol2scm ("is-last-bookpart"), scm_from_bool (last_part),
459                                   ly_symbol2scm ("is-bookpart-last-page"), scm_from_bool (last),
460                                   SCM_UNDEFINED));
461 }
462
463 // Returns the total height of the paper, including margins and
464 // space for the header/footer.  This is an upper bound on
465 // page_height, and it doesn't depend on the current page.
466 Real
467 Page_breaking::paper_height () const
468 {
469   return paper_height_;
470 }
471
472 Real
473 Page_breaking::page_height (int page_num, bool last) const
474 {
475   // The caches allow us to store the page heights for any
476   // non-negative page numbers.  We use a negative value in the
477   // cache to signal that that position has not yet been initialized.
478   // This means that we won't cache properly if page_num is negative or
479   // if calc_height returns a negative number.  But that's likely to
480   // be rare, so it shouldn't affect performance.
481   vector<Real>& cache = last ? last_page_height_cache_ : page_height_cache_;
482   if (page_num >= 0 && (int) cache.size () > page_num && cache[page_num] >= 0)
483     return cache[page_num];
484   else
485     {
486       SCM mod = scm_c_resolve_module ("scm page");
487       SCM page = make_page (page_num, last);
488       SCM calc_height = scm_c_module_lookup (mod, "calc-printable-height");
489       calc_height = scm_variable_ref (calc_height);
490
491       SCM height_scm = scm_apply_1 (calc_height, page, SCM_EOL);
492       Real height = scm_to_double (height_scm);
493
494       if (page_num >= 0)
495         {
496           if ((int) cache.size () <= page_num)
497             cache.resize (page_num + 1, -1);
498           cache[page_num] = height;
499         }
500       return height;
501     }
502 }
503
504 SCM
505 Page_breaking::breakpoint_property (vsize breakpoint, char const *str)
506 {
507   Break_position const &pos = breaks_[breakpoint];
508
509   if (pos.system_spec_index_ == VPOS)
510     return SCM_EOL;
511   if (system_specs_[pos.system_spec_index_].pscore_)
512     return pos.col_->get_property (str);
513   return system_specs_[pos.system_spec_index_].prob_->get_property (str);
514 }
515
516 SCM
517 Page_breaking::get_page_configuration (SCM systems, int page_num, bool ragged, bool last)
518 {
519   SCM dummy_page = make_page (page_num, last);
520   Page_layout_problem layout (book_, dummy_page, systems);
521   return scm_is_pair (systems) ? layout.solution (ragged) : SCM_EOL;
522 }
523
524 SCM
525 Page_breaking::draw_page (SCM systems, SCM configuration, int page_num, bool last)
526 {
527   // Create a stencil for each system.
528   SCM paper_systems = SCM_EOL;
529   for (SCM s = scm_reverse (systems); scm_is_pair (s); s = scm_cdr (s))
530     {
531       SCM paper_system = scm_car (s);
532       if (Grob *g = unsmob_grob (scm_car (s)))
533         {
534           System *sys = dynamic_cast<System*> (g);
535           paper_system = sys->get_paper_system ();
536         }
537
538       paper_systems = scm_cons (paper_system, paper_systems);
539     }
540
541   // Create the page and draw it.
542   SCM page = make_page (page_num, last);
543   SCM page_module = scm_c_resolve_module ("scm page");
544   SCM page_stencil = scm_c_module_lookup (page_module, "page-stencil");
545   page_stencil = scm_variable_ref (page_stencil);
546
547   Prob *p = unsmob_prob (page);
548   p->set_property ("lines", paper_systems);
549   p->set_property ("configuration", configuration);
550
551   Stencil *foot = unsmob_stencil (p->get_property ("foot-stencil"));
552   SCM footnotes = Page_layout_problem::get_footnotes_from_lines (systems, footnote_padding ());
553   Page_layout_problem::add_footnotes_to_footer (footnotes, foot, unsmob_paper_book (p->get_property ("paper-book")));
554
555   p->set_property ("foot-stencil", foot->smobbed_copy ());
556   scm_apply_1 (page_stencil, page, SCM_EOL);
557
558   return page;
559 }
560
561 SCM
562 Page_breaking::make_pages (vector<vsize> lines_per_page, SCM systems)
563 {
564   if (scm_is_null (systems))
565     return SCM_EOL;
566
567   int first_page_number
568     = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
569   SCM ret = SCM_EOL;
570   SCM label_page_table = book_->top_paper ()->c_variable ("label-page-table");
571   if (label_page_table == SCM_UNDEFINED)
572     label_page_table = SCM_EOL;
573
574   // Build a list of (systems . configuration) pairs. Note that we lay out
575   // the staves and find the configurations before drawing anything. Some
576   // grobs (like tuplet brackets) look at their neighbours while drawing
577   // themselves. If this happens before the neighbouring staves have
578   // been laid out, bad side-effects could happen (in particular,
579   // Align_interface::align_to_ideal_distances might be called).
580   SCM systems_and_configs = SCM_EOL;
581
582   for (vsize i = 0; i < lines_per_page.size (); i++)
583     {
584       int page_num = i + first_page_number;
585       bool bookpart_last_page = (i == lines_per_page.size () - 1);
586       bool rag = ragged () || (bookpart_last_page && ragged_last ());
587       SCM line_count = scm_from_int (lines_per_page[i]);
588       SCM lines = scm_list_head (systems, line_count);
589       SCM config = get_page_configuration (lines, page_num, rag, bookpart_last_page);
590
591       systems_and_configs = scm_cons (scm_cons (lines, config), systems_and_configs);
592       systems = scm_list_tail (systems, line_count);
593     }
594
595   // Now it's safe to make the pages.
596   int page_num = first_page_number + lines_per_page.size () - 1;
597   for (SCM s = systems_and_configs; scm_is_pair (s); s = scm_cdr (s))
598     {
599       SCM lines = scm_caar (s);
600       SCM config = scm_cdar (s);
601       
602       bool bookpart_last_page = (s == systems_and_configs);
603       SCM page = draw_page (lines, config, page_num, bookpart_last_page);
604
605       /* collect labels */
606       SCM page_num_scm = scm_from_int (page_num);
607       for (SCM l = lines ; scm_is_pair (l)  ; l = scm_cdr (l))
608         {
609           SCM labels = SCM_EOL;
610           if (Grob * line = unsmob_grob (scm_car (l)))
611             {
612               System *system = dynamic_cast<System*> (line);
613               labels = system->get_property ("labels");
614             }
615           else if (Prob *prob = unsmob_prob (scm_car (l)))
616             labels = prob->get_property ("labels");
617
618           for (SCM lbls = labels ; scm_is_pair (lbls) ; lbls = scm_cdr (lbls))
619             label_page_table = scm_cons (scm_cons (scm_car (lbls), page_num_scm),
620                                          label_page_table);
621         }
622
623       ret = scm_cons (page, ret);
624       --page_num;
625     }
626
627   // By reversing the table, we ensure that duplicated labels (eg. those
628   // straddling a page turn) will appear in the table with their last
629   // occurence first.
630   label_page_table = scm_reverse_x (label_page_table, SCM_EOL);
631   book_->top_paper ()->set_variable (ly_symbol2scm ("label-page-table"), label_page_table);
632   return ret;
633 }
634
635 /* The page-turn-page-breaker needs to have a line-breaker between any two
636    columns with non-NULL page-turn-permission.
637
638    The optimal-breaker needs to have a line-breaker between any two columns
639    with page-break-permission = 'force.
640
641    By using a grob predicate, we can accommodate both of these uses.
642 */
643 void
644 Page_breaking::create_system_list ()
645 {
646   SCM specs = book_->get_system_specs ();
647   for (SCM s = specs; scm_is_pair (s); s = scm_cdr (s))
648     {
649       if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (scm_car (s))))
650         {
651           system_specs_.push_back (System_spec (ps));
652         }
653       else
654         {
655           Prob *pb = unsmob_prob (scm_car (s));
656           assert (pb);
657
658           pb->protect ();
659           system_specs_.push_back (System_spec (pb));
660         }
661     }
662   if (!system_specs_.size ())
663     system_specs_.push_back (System_spec ());
664 }
665
666 void
667 Page_breaking::find_chunks_and_breaks (Break_predicate is_break, Prob_break_predicate prob_is_break)
668 {
669   SCM force_sym = ly_symbol2scm ("force");
670
671   chunks_.push_back (Break_position ());
672   breaks_.push_back (Break_position ());
673
674   for (vsize i = 0; i < system_specs_.size (); i++)
675     {
676       if (system_specs_[i].pscore_)
677         {
678           vector<Grob*> cols = system_specs_[i].pscore_->root_system ()->used_columns ();
679           vector<Grob*> forced_line_break_cols;
680
681           SCM system_count = system_specs_[i].pscore_->layout ()->c_variable ("system-count");
682           if (scm_is_number (system_count))
683             {
684               // With system-count given, the line configuration for
685               // this score is fixed.  We need to ensure that chunk
686               // boundaries only occur at line breaks.
687               Constrained_breaking breaking (system_specs_[i].pscore_);
688               vector<Line_details> details = breaking.line_details (0, VPOS, scm_to_int (system_count));
689
690               for (vsize j = 0; j < details.size (); j++)
691                 forced_line_break_cols.push_back (details[j].last_column_);
692             }
693
694           int last_forced_line_break_idx = 0;
695           vsize forced_line_break_idx = 0;
696           vector<vsize> line_breaker_columns;
697           line_breaker_columns.push_back (0);
698
699           for (vsize j = 1; j < cols.size (); j++)
700             {
701               if (forced_line_break_cols.size ())
702                 {
703                   if (forced_line_break_idx >= forced_line_break_cols.size ()
704                       || forced_line_break_cols[forced_line_break_idx] != cols[j])
705                     continue;
706                   else
707                     forced_line_break_idx++;
708                 }
709
710               bool last = (j == cols.size () - 1);
711               bool break_point = is_break && is_break (cols[j]);
712               bool chunk_end = cols[j]->get_property ("page-break-permission") == force_sym;
713               Break_position cur_pos = Break_position (i,
714                                                        line_breaker_columns.size (),
715                                                        cols[j],
716                                                        last);
717
718               // NOTE: even in the breaks_ list, forced_line_count_
719               // refers to the number of lines between a
720               // Break_position and the start of that /chunk/.  This
721               // is needed for system_count_bounds to work correctly,
722               // since it mixes Break_positions from breaks_ and
723               // chunks_.
724               if (scm_is_number (system_count))
725                 cur_pos.forced_line_count_ = forced_line_break_idx - last_forced_line_break_idx;
726
727               if (break_point || (i == system_specs_.size () - 1 && last))
728                 breaks_.push_back (cur_pos);
729               if (chunk_end || last)
730                 {
731                   chunks_.push_back (cur_pos);
732                   last_forced_line_break_idx = forced_line_break_idx;
733                 }
734
735               if ((break_point || chunk_end) && !last)
736                 line_breaker_columns.push_back (j);
737             }
738           line_breaking_.push_back (Constrained_breaking (system_specs_[i].pscore_, line_breaker_columns));
739         }
740       else if (system_specs_[i].prob_)
741         {
742           bool break_point = prob_is_break && prob_is_break (system_specs_[i].prob_);
743           if (break_point || i == system_specs_.size () - 1)
744             breaks_.push_back (Break_position (i));
745
746           chunks_.push_back (Break_position (i));
747
748           /* FIXME: shouldn't we push a Null_breaker or similar dummy
749              class? --hwn */
750           line_breaking_.push_back (Constrained_breaking (NULL));
751         }
752     }
753 }
754
755 vector<Break_position>
756 Page_breaking::chunk_list (vsize start_index, vsize end_index)
757 {
758   Break_position start = breaks_[start_index];
759   Break_position end = breaks_[end_index];
760
761   vsize i = 0;
762   for (; i < chunks_.size () && chunks_[i] <= start; i++)
763     ;
764
765   vector<Break_position> ret;
766   ret.push_back (start);
767   for (; i < chunks_.size () && chunks_[i] < end; i++)
768     ret.push_back (chunks_[i]);
769   ret.push_back (end);
770   return ret;
771 }
772
773 // Returns the minimum number of _non-title_ lines.
774 vsize
775 Page_breaking::min_system_count (vsize start, vsize end)
776 {
777   vector<Break_position> chunks = chunk_list (start, end);
778   Line_division div = system_count_bounds (chunks, true);
779   vsize ret = 0;
780
781   for (vsize i = 0; i < div.size (); i++)
782     ret += div[i];
783   return ret;
784 }
785
786 // Returns the maximum number of _non-title_ lines.
787 vsize
788 Page_breaking::max_system_count (vsize start, vsize end)
789 {
790   vector<Break_position> chunks = chunk_list (start, end);
791   Line_division div = system_count_bounds (chunks, false);
792   vsize ret = 0;
793
794   for (vsize i = 0; i < div.size (); i++)
795     ret += div[i];
796   return ret;
797 }
798
799 // The numbers returned by this function represent either
800 // the maximum or minimum number of _non-title_ lines
801 // per chunk.
802 Page_breaking::Line_division
803 Page_breaking::system_count_bounds (vector<Break_position> const &chunks,
804                                     bool min)
805 {
806   assert (chunks.size () >= 2);
807
808   Line_division ret;
809   ret.resize (chunks.size () - 1, 0);
810
811   for (vsize i = 0; i + 1 < chunks.size (); i++)
812     {
813       vsize sys = next_system (chunks[i]);
814
815       if (chunks[i+1].forced_line_count_)
816         ret[i] = chunks[i+1].forced_line_count_;
817       else if (system_specs_[sys].pscore_)
818         {
819           vsize start;
820           vsize end;
821           line_breaker_args (sys, chunks[i], chunks[i+1], &start, &end);
822           ret[i] = min
823             ? line_breaking_[sys].min_system_count (start, end)
824             : line_breaking_[sys].max_system_count (start, end);
825         }
826     }
827
828   return ret;
829 }
830
831 void
832 Page_breaking::set_current_breakpoints (vsize start,
833                                         vsize end,
834                                         vsize system_count,
835                                         Line_division lower_bound,
836                                         Line_division upper_bound)
837 {
838   system_count_ = system_count;
839   current_chunks_ = chunk_list (start, end);
840   current_start_breakpoint_ = start;
841   current_end_breakpoint_ = end;
842   clear_line_details_cache ();
843
844   if (!lower_bound.size ())
845     lower_bound = system_count_bounds (current_chunks_, true);
846   if (!upper_bound.size ())
847     upper_bound = system_count_bounds (current_chunks_, false);
848
849   assert (lower_bound.size () == current_chunks_.size () - 1);
850   assert (upper_bound.size () == current_chunks_.size () - 1);
851
852   Line_division work_in_progress;
853   current_configurations_.clear ();
854   line_divisions_rec (system_count,
855                       lower_bound,
856                       upper_bound,
857                       &work_in_progress);
858
859   /* we only consider a constant number of configurations. Otherwise,
860      this becomes slow when there are many small scores. The constant
861      5 is somewhat arbitrary. */
862   if (current_configurations_.size () > 5)
863     {
864       vector<pair<Real,vsize> > dems_and_indices;
865
866       for (vsize i = 0; i < current_configurations_.size (); i++)
867         {
868           cache_line_details (i);
869           Real dem = 0;
870           for (vsize j = 0; j < cached_line_details_.size (); j++)
871             dem += cached_line_details_[j].force_ * cached_line_details_[j].force_
872               + cached_line_details_[j].break_penalty_;
873
874           dems_and_indices.push_back (pair<Real,vsize> (dem, i));
875         }
876       vector_sort (dems_and_indices, less<pair<Real,vsize> > ());
877
878       vector<Line_division> best_5_configurations;
879       for (vsize i = 0; i < 5; i++)
880         best_5_configurations.push_back (current_configurations_[dems_and_indices[i].second]);
881
882       clear_line_details_cache ();
883       current_configurations_ = best_5_configurations;
884     }
885 }
886
887 void
888 Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end)
889 {
890   current_chunks_ = chunk_list (start, end);
891   current_start_breakpoint_ = start;
892   current_end_breakpoint_ = end;
893   clear_line_details_cache ();
894   system_count_ = 0;
895
896   Line_division div;
897   for (vsize i = 0; i+1 < current_chunks_.size (); i++)
898     {
899       vsize sys = next_system (current_chunks_[i]);
900
901       if (current_chunks_[i+1].forced_line_count_)
902         div.push_back (current_chunks_[i+1].forced_line_count_);
903       else if (system_specs_[sys].pscore_)
904         {
905           line_breaker_args (sys, current_chunks_[i], current_chunks_[i+1], &start, &end);
906           div.push_back (line_breaking_[sys].best_solution (start, end).size ());
907         }
908       else
909         div.push_back (0);
910
911       system_count_ += div.back ();
912     }
913   current_configurations_.clear ();
914   current_configurations_.push_back (div);
915 }
916
917 vsize
918 Page_breaking::current_configuration_count () const
919 {
920   return current_configurations_.size ();
921 }
922
923 void
924 Page_breaking::cache_line_details (vsize configuration_index)
925 {
926   if (cached_configuration_index_ != configuration_index)
927     {
928       cached_configuration_index_ = configuration_index;
929
930       Line_division &div = current_configurations_[configuration_index];
931       uncompressed_line_details_.clear ();
932       for (vsize i = 0; i + 1 < current_chunks_.size (); i++)
933         {
934           vsize sys = next_system (current_chunks_[i]);
935           if (system_specs_[sys].pscore_)
936             {
937               vsize start;
938               vsize end;
939               line_breaker_args (sys, current_chunks_[i], current_chunks_[i+1], &start, &end);
940
941               vector<Line_details> details = line_breaking_[sys].line_details (start, end, div[i]);
942               uncompressed_line_details_.insert (uncompressed_line_details_.end (), details.begin (), details.end ());
943             }
944           else
945             {
946               assert (div[i] == 0);
947               uncompressed_line_details_.push_back (system_specs_[sys].prob_
948                                                     ? Line_details (system_specs_[sys].prob_, book_->paper_)
949                                                     : Line_details ());
950             }
951         }
952       cached_line_details_ = compress_lines (uncompressed_line_details_);
953       compute_line_heights ();
954     }
955 }
956
957 void
958 Page_breaking::clear_line_details_cache ()
959 {
960   cached_configuration_index_ = VPOS;
961   cached_line_details_.clear ();
962   uncompressed_line_details_.clear ();
963 }
964
965 void
966 Page_breaking::line_divisions_rec (vsize system_count,
967                                    Line_division const &min_sys,
968                                    Line_division const &max_sys,
969                                    Line_division *cur_division)
970 {
971   vsize my_index = cur_division->size ();
972   int others_min = 0;
973   int others_max = 0;
974
975   for (vsize i = my_index + 1; i < min_sys.size (); i++)
976     {
977       others_min += min_sys[i];
978       others_max += max_sys[i];
979     }
980   others_max = min (others_max, (int) system_count);
981   int real_min = max ((int) min_sys[my_index], (int) system_count - others_max);
982   int real_max = min ((int) max_sys[my_index], (int) system_count - others_min);
983
984   if (real_min > real_max || real_min < 0)
985     {
986       /* this should never happen within a recursive call. If it happens
987          at all, it means that we were called with an unsolvable problem
988          and we should return an empty result */
989       assert (my_index == 0);
990       return;
991     }
992
993   for (int i = real_min; i <= real_max; i++)
994     {
995       cur_division->push_back (i);
996       if (my_index == min_sys.size () - 1)
997         current_configurations_.push_back (*cur_division);
998       else
999         line_divisions_rec (system_count - i, min_sys, max_sys, cur_division);
1000       cur_division->pop_back ();
1001     }
1002 }
1003
1004 void
1005 Page_breaking::compute_line_heights ()
1006 {
1007   Real prev_hanging = 0;
1008   Real prev_hanging_begin = 0;
1009   Real prev_hanging_rest = 0;
1010
1011   // refpoint_hanging is the y coordinate of the origin of this system.
1012   // It may not be the same as refpoint_extent[UP], which is the
1013   // refpoint of the first spaceable staff in this system.
1014   Real prev_refpoint_hanging = 0;
1015   for (vsize i = 0; i < cached_line_details_.size (); i++)
1016     {
1017       Line_details& cur = cached_line_details_[i];
1018       Line_shape shape = cur.shape_;
1019       Real a = shape.begin_[UP];
1020       Real b = shape.rest_[UP];
1021       bool title = cur.title_;
1022       Real refpoint_hanging = max (prev_hanging_begin + a, prev_hanging_rest + b);
1023
1024       if (i > 0)
1025         {
1026           Real padding = 0;
1027           Line_details const& prev = cached_line_details_[i-1];
1028           if (!cur.tight_spacing_)
1029             padding = title
1030               ? prev.title_padding_
1031               : prev.padding_;
1032           Real min_dist = title
1033             ? prev.title_min_distance_
1034             : prev.min_distance_;
1035           refpoint_hanging = max (refpoint_hanging + padding,
1036                                   prev_refpoint_hanging - prev.refpoint_extent_[DOWN]
1037                                   + cur.refpoint_extent_[UP] + min_dist);
1038         }
1039
1040       Real hanging_begin = refpoint_hanging - shape.begin_[DOWN];
1041       Real hanging_rest = refpoint_hanging - shape.rest_[DOWN];
1042       Real hanging = max (hanging_begin, hanging_rest);
1043       cur.tallness_ = hanging - prev_hanging;
1044       prev_hanging = hanging;
1045       prev_hanging_begin = hanging_begin;
1046       prev_hanging_rest = hanging_rest;
1047       prev_refpoint_hanging = refpoint_hanging;
1048     }
1049 }
1050
1051 vsize
1052 Page_breaking::min_page_count (vsize configuration, vsize first_page_num)
1053 {
1054   vsize ret = 1;
1055   vsize page_starter = 0;
1056   Real cur_rod_height = 0;
1057   Real cur_spring_height = 0;
1058   Real cur_page_height = page_height (first_page_num, false);
1059   int line_count = 0;
1060
1061   cache_line_details (configuration);
1062
1063   if (cached_line_details_.size ())
1064     cur_page_height -= min_whitespace_at_top_of_page (cached_line_details_[0]);
1065
1066   for (vsize i = 0; i < cached_line_details_.size (); i++)
1067     {
1068       Line_details const &cur = cached_line_details_[i];
1069       Line_details const *const prev = (i > 0) ? &cached_line_details_[i-1] : 0;
1070       Real ext_len;
1071       if (cur_rod_height > 0)
1072         ext_len = cur.tallness_;
1073       else
1074         ext_len = cur.full_height();
1075
1076       Real spring_len = (i > 0) ? prev->spring_length (cur) : 0;
1077       Real next_rod_height = cur_rod_height + ext_len;
1078       Real next_spring_height = cur_spring_height + spring_len;
1079       Real next_height = next_rod_height + (ragged () ? next_spring_height : 0)
1080         + min_whitespace_at_bottom_of_page (cur);
1081       int next_line_count = line_count + cur.compressed_nontitle_lines_count_;
1082
1083       if ((!too_few_lines (line_count) && (next_height > cur_page_height && cur_rod_height > 0))
1084           || too_many_lines (next_line_count)
1085           || (prev && prev->page_permission_ == ly_symbol2scm ("force")))
1086         {
1087           line_count = cur.compressed_nontitle_lines_count_;
1088           cur_rod_height = cur.full_height();
1089           cur_spring_height = 0;
1090           page_starter = i;
1091
1092           cur_page_height = page_height (first_page_num + ret, false);
1093           cur_page_height -= min_whitespace_at_top_of_page (cur);
1094
1095           ret++;
1096         }
1097       else
1098         {
1099           cur_rod_height = next_rod_height;
1100           cur_spring_height = next_spring_height;
1101           line_count = next_line_count;
1102         }
1103     }
1104
1105   /* there are two potential problems with the last page (because we didn't know
1106      it was the last page until after we managed to fit all the systems to it):
1107      - we are ragged-last but the last page has a compressed spring
1108      - the value returned by page_height (num, true) is smaller than the
1109        value returned by page_height (num, false) and it causes the page not to
1110        fit.
1111
1112      In either case, we just need to add one more page. This is because the last
1113      line will always fit on the extra page and by adding one more page to the
1114      end, the previous page is no longer the last page, so our previous
1115      calculations that treated it as a non-last page were ok.
1116   */
1117
1118   if (is_last ())
1119     {
1120       cur_page_height = page_height (first_page_num + ret - 1, true);
1121       cur_page_height -= min_whitespace_at_top_of_page (cached_line_details_[page_starter]);
1122       cur_page_height -= min_whitespace_at_bottom_of_page (cached_line_details_.back ());
1123
1124       Real cur_height = cur_rod_height + ((ragged_last () || ragged ()) ? cur_spring_height : 0);
1125       if (!too_few_lines (line_count - cached_line_details_.back ().compressed_nontitle_lines_count_)
1126           && cur_height > cur_page_height
1127           /* don't increase the page count if the last page had only one system */
1128           && cur_rod_height > cached_line_details_.back ().full_height ())
1129         ret++;
1130       assert (ret <= cached_line_details_.size ());
1131     }
1132
1133   return ret;
1134 }
1135
1136 // If systems_per_page_ is positive, we don't really try to space on N pages;
1137 // we just put the requested number of systems on each page and penalize
1138 // if the result doesn't have N pages.
1139 Page_spacing_result
1140 Page_breaking::space_systems_on_n_pages (vsize configuration, vsize n, vsize first_page_num)
1141 {
1142   Page_spacing_result ret;
1143
1144   if (systems_per_page_ > 0)
1145     {
1146       Page_spacing_result ret = space_systems_with_fixed_number_per_page (configuration, first_page_num);
1147       ret.demerits_ += (ret.force_.size () == n) ? 0 : BAD_SPACING_PENALTY;
1148       return ret;
1149     }
1150
1151   cache_line_details (configuration);
1152   bool valid_n = (n >= min_page_count (configuration, first_page_num)
1153                   && n <= cached_line_details_.size ());
1154
1155   if (!valid_n)
1156     programming_error ("number of pages is out of bounds");
1157
1158   if (n == 1 && valid_n)
1159     ret = space_systems_on_1_page (cached_line_details_,
1160                                    page_height (first_page_num, is_last ()),
1161                                    ragged () || (is_last () && ragged_last ()));
1162   else if (n == 2 && valid_n)
1163     ret = space_systems_on_2_pages (configuration, first_page_num);
1164   else
1165     {
1166       Page_spacer ps (cached_line_details_, first_page_num, this);
1167       ret = ps.solve (n);
1168     }
1169
1170   return finalize_spacing_result (configuration, ret);
1171 }
1172
1173 Real
1174 Page_breaking::blank_page_penalty () const
1175 {
1176   SCM penalty_sym;
1177
1178   if (is_last ())
1179     penalty_sym = ly_symbol2scm ("blank-last-page-force");
1180   else if (ends_score ())
1181     penalty_sym = ly_symbol2scm ("blank-after-score-page-force");
1182   else
1183     penalty_sym = ly_symbol2scm ("blank-page-force");
1184
1185   Break_position const &pos = breaks_[current_end_breakpoint_];
1186   if (Paper_score *ps = system_specs_[pos.system_spec_index_].pscore_)
1187     return robust_scm2double (ps->layout ()->lookup_variable (penalty_sym), 0.0);
1188
1189   return robust_scm2double (book_->paper_->lookup_variable (penalty_sym), 0.0);
1190 }
1191
1192 // If systems_per_page_ is positive, we don't really try to space on N
1193 // or N+1 pages; see the comment to space_systems_on_n_pages.
1194 Page_spacing_result
1195 Page_breaking::space_systems_on_n_or_one_more_pages (vsize configuration, vsize n, vsize first_page_num,
1196                                                      Real penalty_for_fewer_pages)
1197 {
1198   Page_spacing_result n_res;
1199   Page_spacing_result m_res;
1200
1201   if (systems_per_page_ > 0)
1202     {
1203       Page_spacing_result ret = space_systems_with_fixed_number_per_page (configuration, first_page_num);
1204       ret.demerits_ += (ret.force_.size () == n || ret.force_.size () == (n-1)) ? 0 : BAD_SPACING_PENALTY;
1205       return ret;
1206     }
1207
1208   cache_line_details (configuration);
1209   vsize min_p_count = min_page_count (configuration, first_page_num);
1210   bool valid_n = n >= min_p_count || n <= cached_line_details_.size ();
1211
1212   if (!valid_n)
1213     programming_error ("both page counts are out of bounds");
1214
1215   if (n == 1 && valid_n)
1216     {
1217       bool rag = ragged () || (is_last () && ragged_last ());
1218       Real height = page_height (first_page_num, is_last ());
1219
1220       if (1 >= min_p_count)
1221         n_res = space_systems_on_1_page (cached_line_details_, height, rag);
1222       if (1 < cached_line_details_.size ())
1223         m_res = space_systems_on_2_pages (configuration, first_page_num);
1224     }
1225   else
1226     {
1227       Page_spacer ps (cached_line_details_, first_page_num, this);
1228       
1229       if (n >= min_p_count || !valid_n)
1230         n_res = ps.solve (n);
1231       if (n < cached_line_details_.size () || !valid_n)
1232         m_res = ps.solve (n+1);
1233     }
1234
1235   m_res = finalize_spacing_result (configuration, m_res);
1236   n_res = finalize_spacing_result (configuration, n_res);
1237
1238   Real page_spacing_weight = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 10);
1239   n_res.demerits_ += penalty_for_fewer_pages * page_spacing_weight;
1240
1241   if (n_res.force_.size ())
1242     n_res.force_.back () += penalty_for_fewer_pages;
1243
1244   return (m_res.demerits_ < n_res.demerits_) ? m_res : n_res;
1245 }
1246
1247 Page_spacing_result
1248 Page_breaking::space_systems_on_best_pages (vsize configuration, vsize first_page_num)
1249 {
1250   if (systems_per_page_ > 0)
1251     return space_systems_with_fixed_number_per_page (configuration, first_page_num);
1252
1253   cache_line_details (configuration);
1254   Page_spacer ps (cached_line_details_, first_page_num, this);
1255
1256   return finalize_spacing_result (configuration, ps.solve ());
1257 }
1258
1259 Page_spacing_result
1260 Page_breaking::space_systems_with_fixed_number_per_page (vsize configuration,
1261                                                          vsize first_page_num)
1262 {
1263   Page_spacing_result res;
1264   Page_spacing space (page_height (first_page_num, false), this);
1265   vsize line = 0;
1266   vsize page = 0;
1267   vsize page_first_line = 0;
1268
1269   cache_line_details (configuration);
1270   while (line < cached_line_details_.size ())
1271     {
1272       page++;
1273       space.clear ();
1274       space.resize (page_height (first_page_num + page, false));
1275
1276       int system_count_on_this_page = 0;
1277       while (system_count_on_this_page < systems_per_page_
1278              && line < cached_line_details_.size ())
1279         {
1280           Line_details const &cur_line = cached_line_details_[line];
1281           space.append_system (cur_line);
1282           system_count_on_this_page += cur_line.compressed_nontitle_lines_count_;
1283           line++;
1284
1285           if (cur_line.page_permission_ == ly_symbol2scm ("force"))
1286             break;
1287         }
1288
1289       res.systems_per_page_.push_back (line - page_first_line);
1290
1291       res.force_.push_back (space.force_);
1292       res.penalty_ += cached_line_details_[line-1].page_penalty_;
1293       if (system_count_on_this_page != systems_per_page_)
1294         {
1295           res.penalty_ += abs (system_count_on_this_page - systems_per_page_) * TERRIBLE_SPACING_PENALTY;
1296           res.system_count_status_ |= ((system_count_on_this_page < systems_per_page_))
1297             ? SYSTEM_COUNT_TOO_FEW : SYSTEM_COUNT_TOO_MANY;
1298         }
1299
1300       page_first_line = line;
1301     }
1302
1303   /* Recalculate forces for the last page because we know now that is
1304      really the last page. */
1305   space.resize (page_height (first_page_num + page, true));
1306   res.force_.back () = space.force_;
1307   return finalize_spacing_result (configuration, res);
1308 }
1309
1310 Page_spacing_result
1311 Page_breaking::pack_systems_on_least_pages (vsize configuration, vsize first_page_num)
1312 {
1313   // TODO: add support for min/max-systems-per-page.
1314   Page_spacing_result res;
1315   vsize page = 0;
1316   vsize page_first_line = 0;
1317   Page_spacing space (page_height (first_page_num, false), this);
1318
1319   cache_line_details (configuration);
1320   for (vsize line = 0; line < cached_line_details_.size (); line++)
1321     {
1322       Real prev_force = space.force_;
1323       space.append_system (cached_line_details_[line]);
1324       if ((line > page_first_line)
1325           && (isinf (space.force_)
1326               || ((line > 0)
1327                   && (cached_line_details_[line-1].page_permission_ == ly_symbol2scm ("force")))))
1328         {
1329           res.systems_per_page_.push_back (line - page_first_line);
1330           res.force_.push_back (prev_force);
1331           res.penalty_ += cached_line_details_[line-1].page_penalty_;
1332           page++;
1333           space.resize (page_height (first_page_num + page, false));
1334           space.clear ();
1335           space.append_system (cached_line_details_[line]);
1336           page_first_line = line;
1337         }
1338
1339       if (line == cached_line_details_.size () - 1)
1340         {
1341           /* This is the last line */
1342           /* When the last page height was computed, we did not know yet that it
1343            * was the last one. If the systems put on it don't fit anymore, the last
1344            * system is moved to a new page */
1345           space.resize (page_height (first_page_num + page, true));
1346           if ((line > page_first_line) && (isinf (space.force_)))
1347             {
1348               res.systems_per_page_.push_back (line - page_first_line);
1349               res.force_.push_back (prev_force);
1350               /* the last page containing the last line */
1351               space.resize (page_height (first_page_num + page + 1, true));
1352               space.clear ();
1353               space.append_system (cached_line_details_[line]);
1354               res.systems_per_page_.push_back (1);
1355               res.force_.push_back (space.force_);
1356               res.penalty_ += cached_line_details_[line-1].page_penalty_;
1357               res.penalty_ += cached_line_details_[line].page_penalty_;
1358             }
1359           else
1360             {
1361               res.systems_per_page_.push_back (line + 1 - page_first_line);
1362               res.force_.push_back (space.force_);
1363               res.penalty_ += cached_line_details_[line].page_penalty_;
1364             }
1365         }
1366     }
1367   return finalize_spacing_result (configuration, res);
1368 }
1369
1370 /* Calculate demerits and fix res.systems_per_page_ so that
1371    it refers to the original line numbers, not the ones given by compress_lines (). */
1372 Page_spacing_result
1373 Page_breaking::finalize_spacing_result (vsize configuration, Page_spacing_result res)
1374 {
1375   if (res.force_.empty ())
1376     return res;
1377
1378   cache_line_details (configuration);
1379   res.systems_per_page_ = uncompress_solution (res.systems_per_page_, cached_line_details_);
1380
1381   Real line_force = 0;
1382   Real line_penalty = 0;
1383   Real page_demerits = res.penalty_;
1384   Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 10);
1385
1386   for (vsize i = 0; i < uncompressed_line_details_.size (); i++)
1387     {
1388       line_force += uncompressed_line_details_[i].force_ * uncompressed_line_details_[i].force_;
1389       line_penalty += uncompressed_line_details_[i].break_penalty_;
1390     }
1391
1392   for (vsize i = 0; i < res.force_.size (); i++)
1393     {
1394       Real f = res.force_[i];
1395
1396       page_demerits += min(f*f, BAD_SPACING_PENALTY);
1397     }
1398
1399   /* for a while we tried averaging page and line forces across pages instead
1400      of summing them, but it caused a problem: if there is a single page
1401      with a very bad page force (for example because of a forced page break),
1402      the page breaker will put in a _lot_ of pages so that the bad force
1403      becomes averaged out over many pages. */
1404   res.demerits_ = line_force + line_penalty + page_demerits * page_weighting;
1405   return res;
1406
1407 }
1408
1409 /* the cases for page_count = 1 or 2 can be done in O (n) time. Since they
1410    are by far the most common cases, we have special functions for them.
1411
1412    space_systems_on_1_page has a different calling convention than most of the
1413    space_systems functions. This is because space_systems_on_1_page is (unlike
1414    the other space_systems functions) sometimes called on subsets of a full
1415    configuration. */
1416 Page_spacing_result
1417 Page_breaking::space_systems_on_1_page (vector<Line_details> const &lines, Real page_height, bool ragged)
1418 {
1419   Page_spacing space (page_height, this);
1420   Page_spacing_result ret;
1421   int line_count = 0;
1422
1423   for (vsize i = 0; i < lines.size (); i++)
1424     {
1425       space.append_system (lines[i]);
1426       line_count += lines[i].compressed_nontitle_lines_count_;
1427     }
1428
1429   ret.systems_per_page_.push_back (lines.size ());
1430   ret.force_.push_back (ragged ? min (space.force_, 0.0) : space.force_);
1431   ret.penalty_ = line_count_penalty (line_count) + lines.back ().page_penalty_ + lines.back ().turn_penalty_;
1432   ret.system_count_status_ |= line_count_status (line_count);
1433
1434   /* don't do finalize_spacing_result () because we are only an internal function */
1435   return ret;
1436 }
1437
1438 Page_spacing_result
1439 Page_breaking::space_systems_on_2_pages (vsize configuration, vsize first_page_num)
1440 {
1441   Real page1_height = page_height (first_page_num, false);
1442   Real page2_height = page_height (first_page_num + 1, is_last ());
1443   bool ragged1 = ragged ();
1444   bool ragged2 = ragged () || (is_last () && ragged_last ());
1445
1446   /* if there is a forced break, this reduces to 2 1-page problems */
1447   cache_line_details (configuration);
1448   for (vsize i = 0; i + 1 < cached_line_details_.size (); i++)
1449     if (cached_line_details_[i].page_permission_ == ly_symbol2scm ("force"))
1450       {
1451         vector<Line_details> lines1 (cached_line_details_.begin (), cached_line_details_.begin () + i + 1);
1452         vector<Line_details> lines2 (cached_line_details_.begin () + i + 1, cached_line_details_.end ());
1453         Page_spacing_result p1 = space_systems_on_1_page (lines1, page1_height, ragged1);
1454         Page_spacing_result p2 = space_systems_on_1_page (lines2, page2_height, ragged2);
1455
1456         p1.systems_per_page_.push_back (p2.systems_per_page_[0]);
1457         p1.force_.push_back (p2.force_[0]);
1458         p1.penalty_ += p2.penalty_ - cached_line_details_[i].turn_penalty_;
1459         p1.system_count_status_ |= p2.system_count_status_;
1460         return p1;
1461       }
1462
1463   vector<Real> page1_force;
1464   vector<Real> page2_force;
1465
1466   // page1_penalty and page2_penalty store the penalties based
1467   // on min-systems-per-page and max-systems-per-page.
1468   vector<Real> page1_penalty;
1469   vector<Real> page2_penalty;
1470
1471   // page1_status and page2_status keep track of whether the min-systems-per-page
1472   // and max-systems-per-page constraints are satisfied.
1473   vector<int> page1_status;
1474   vector<int> page2_status;
1475
1476   Page_spacing page1 (page1_height, this);
1477   Page_spacing page2 (page2_height, this);
1478   int page1_line_count = 0;
1479   int page2_line_count = 0;
1480
1481   page1_force.resize (cached_line_details_.size () - 1, infinity_f);
1482   page2_force.resize (cached_line_details_.size () - 1, infinity_f);
1483   page1_penalty.resize (cached_line_details_.size () - 1, infinity_f);
1484   page2_penalty.resize (cached_line_details_.size () - 1, infinity_f);
1485   page1_status.resize (cached_line_details_.size () - 1, 0);
1486   page2_status.resize (cached_line_details_.size () - 1, 0);
1487
1488   /* find the page 1 and page 2 forces for each page-breaking position */
1489   for (vsize i = 0; i < page1_force.size (); i++)
1490     {
1491       page1.append_system (cached_line_details_[i]);
1492       page2.prepend_system (cached_line_details_[cached_line_details_.size () - 1 - i]);
1493       page1_line_count += cached_line_details_[i].compressed_nontitle_lines_count_;
1494       page2_line_count += cached_line_details_[cached_line_details_.size () - 1 - i].compressed_nontitle_lines_count_;
1495
1496       page1_force[i] = (ragged1 && page1.force_ < 0 && i > 0) ? infinity_f : page1.force_;
1497       page1_penalty[i] = line_count_penalty (page1_line_count);
1498       page1_status[i] = line_count_status (page1_line_count);
1499
1500       if (ragged2)
1501         page2_force[page2_force.size () - 1 - i] =
1502           (page2.force_ < 0 && i + 1 < page1_force.size ()) ? infinity_f : 0;
1503       else
1504         page2_force[page2_force.size () - 1 - i] = page2.force_;
1505       page2_penalty[page2_penalty.size () - 1 - i] = line_count_penalty (page2_line_count);
1506       page2_status[page2_penalty.size () - 1 - i] = line_count_status (page2_line_count);
1507     }
1508
1509   /* find the position that minimises the sum of the page forces */
1510   vsize best_sys_count = 1;
1511   Real best_demerits = infinity_f;
1512   for (vsize i = 0; i < page1_force.size (); i++)
1513     {
1514       Real f = page1_force[i] * page1_force[i] + page2_force[i] * page2_force[i];
1515
1516       // NOTE: we treat max-systems-per-page and min-systems-per-page as soft
1517       // constraints. That is, we penalize harshly when they don't happen
1518       // but we don't completely reject.
1519       Real dem = f
1520         + page1_penalty[i] + page2_penalty[i]
1521         + cached_line_details_[i+1].page_penalty_
1522         + cached_line_details_.back ().page_penalty_ + cached_line_details_.back ().turn_penalty_;
1523       if (dem < best_demerits)
1524         {
1525           best_demerits = dem;
1526           best_sys_count = i+1;
1527         }
1528     }
1529
1530   Page_spacing_result ret;
1531   ret.systems_per_page_.push_back (best_sys_count);
1532   ret.systems_per_page_.push_back (cached_line_details_.size () - best_sys_count);
1533   ret.force_.push_back (page1_force[best_sys_count-1]);
1534   ret.force_.push_back (page2_force[best_sys_count-1]);
1535   ret.system_count_status_ = page1_status[best_sys_count-1] | page2_status[best_sys_count-1];
1536   ret.penalty_ = cached_line_details_[best_sys_count-1].page_penalty_
1537     + cached_line_details_.back ().page_penalty_
1538     + cached_line_details_.back ().turn_penalty_
1539     + page1_penalty[best_sys_count-1] + page2_penalty[best_sys_count-1];
1540
1541   /* don't do finalize_spacing_result () because we are only an internal function */
1542   return ret;
1543 }
1544
1545 bool
1546 Page_breaking::all_lines_stretched (vsize configuration)
1547 {
1548   cache_line_details (configuration);
1549   for (vsize i = 0; i < cached_line_details_.size (); i++)
1550     if (cached_line_details_[i].force_ < 0)
1551       return false;
1552
1553   return true;
1554 }
1555
1556 Page_breaking::Line_division
1557 Page_breaking::current_configuration (vsize configuration_index) const
1558 {
1559   return current_configurations_[configuration_index];
1560 }
1561
1562 bool
1563 Page_breaking::is_last () const
1564 {
1565   return current_end_breakpoint_ == last_break_position ();
1566 }
1567
1568 bool
1569 Page_breaking::ends_score () const
1570 {
1571   return breaks_[current_end_breakpoint_].score_ender_;
1572 }
1573
1574 vsize
1575 Page_breaking::last_break_position () const
1576 {
1577   return breaks_.size () - 1;  
1578 }
1579
1580 // This gives the minimum distance between the top of the
1581 // printable area (ie. the bottom of the top-margin) and
1582 // the extent box of the topmost system.
1583 Real
1584 Page_breaking::min_whitespace_at_top_of_page (Line_details const &line) const
1585 {
1586   SCM first_system_spacing = book_->paper_->c_variable ("top-system-spacing");
1587   if (line.title_)
1588     first_system_spacing = book_->paper_->c_variable ("top-markup-spacing");
1589
1590   Real min_distance = -infinity_f;
1591   Real padding = 0;
1592
1593   Page_layout_problem::read_spacing_spec (first_system_spacing,
1594                                           &min_distance,
1595                                           ly_symbol2scm ("minimum-distance"));
1596   Page_layout_problem::read_spacing_spec (first_system_spacing,
1597                                           &padding,
1598                                           ly_symbol2scm ("padding"));
1599
1600   // FIXME: take into account the height of the header
1601   Real translate = max (line.shape_.begin_[UP], line.shape_.rest_[UP]);
1602   return max (0.0, max (padding, min_distance - translate));
1603 }
1604
1605 Real
1606 Page_breaking::min_whitespace_at_bottom_of_page (Line_details const &line) const
1607 {
1608   SCM last_system_spacing = book_->paper_->c_variable ("last-bottom-spacing");
1609   Real min_distance = -infinity_f;
1610   Real padding = 0;
1611
1612   Page_layout_problem::read_spacing_spec (last_system_spacing,
1613                                           &min_distance,
1614                                           ly_symbol2scm ("minimum-distance"));
1615   Page_layout_problem::read_spacing_spec (last_system_spacing,
1616                                           &padding,
1617                                           ly_symbol2scm ("padding"));
1618
1619   // FIXME: take into account the height of the footer
1620   Real translate = min (line.shape_.begin_[DOWN], line.shape_.rest_[DOWN]);
1621   return max (0.0, max (padding, min_distance + translate));
1622 }
1623
1624 int
1625 Page_breaking::orphan_penalty () const
1626 {
1627   return orphan_penalty_;
1628 }