]> git.donarmstrong.com Git - lilypond.git/blob - lily/optimal-page-breaking.cc
Merge branch 'master' into topic/master-translation
[lilypond.git] / lily / optimal-page-breaking.cc
1 /*
2   optimal-page-breaking.cc -- implement a page-breaker that
3   will break pages in such a way that both horizontal and
4   vertical spacing will be acceptable
5
6   source file of the GNU LilyPond music typesetter
7
8   (c) 2006--2007 Joe Neeman <joeneeman@gmail.com>
9 */
10
11 #include "optimal-page-breaking.hh"
12 #include "output-def.hh"
13 #include "page-spacing.hh"
14 #include "paper-book.hh"
15 #include "paper-score.hh"
16 #include "prob.hh"
17 #include "system.hh"
18
19 static bool
20 is_break (Grob *g)
21 {
22   (void) g; /* shutup warning */
23   return false;
24 }
25
26 Optimal_page_breaking::Optimal_page_breaking (Paper_book *pb)
27   : Page_breaking (pb, is_break)
28 {
29 }
30
31 Optimal_page_breaking::~Optimal_page_breaking ()
32 {
33 }
34
35 SCM
36 Optimal_page_breaking::solve ()
37 {
38   vsize end = breaks_.size () - 1;
39   vsize min_sys_count = min_system_count (0, end);
40   vsize max_sys_count = max_system_count (0, end);
41   vsize max_page_count = INT_MAX;
42   vsize cur_page_count = 0;
43   Spacing_result best;
44   Line_division best_division;
45   Line_division lower_bound;
46   vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
47
48   for (vsize sys_count = min_sys_count;
49        cur_page_count <= max_page_count && sys_count <= max_sys_count;
50        sys_count++)
51     {
52       Real best_demerits_for_this_sys_count = infinity_f;
53       set_current_breakpoints (0, end, sys_count, lower_bound);
54
55       for (vsize i = 0; i < current_configuration_count (); i++)
56         {
57           Spacing_result cur = space_systems_on_best_pages (i, first_page_num);
58           cur_page_count = cur.systems_per_page_.size ();
59           if (cur.demerits_ < best.demerits_ || isinf (best.demerits_))
60             {
61               best = cur;
62               best_division = current_configuration (i);
63             }
64
65           if (cur.demerits_ < best_demerits_for_this_sys_count || isinf (best.demerits_))
66             {
67               best_demerits_for_this_sys_count = cur.demerits_;
68               lower_bound = current_configuration (i);
69             }
70
71           if (all_lines_stretched (i))
72             max_page_count = min (max_page_count, cur_page_count + 1);
73         }
74     }
75
76   break_into_pieces (0, end, best_division);
77   SCM lines = systems ();
78   return make_pages (best.systems_per_page_, lines);
79 }
80