]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/page-spacing.hh
Add basic support for min-systems-per-page.
[lilypond.git] / lily / include / page-spacing.hh
1 /*
2   page-spacing.hh -- routines for spacing systems
3   vertically across pages
4
5   source file of the GNU LilyPond music typesetter
6
7   (c) 2006--2009 Joe Neeman <joeneeman@gmail.com>
8 */
9
10 #ifndef PAGE_SPACING_HH
11 #define PAGE_SPACING_HH
12
13 #include "constrained-breaking.hh"
14 #include "page-spacing-result.hh"
15
16 /* This is a penalty that we add whenever a page breaking solution
17    is not bad enough to completely discard, but bad enough that
18    it is worse than any "proper" solution. For example, if we didn't
19    manage to fit systems on the desired number of pages or if there was
20    too big for a page.
21
22    This constant is large enough that it dominates any reasonable penalty,
23    but small enough that nothing will overflow to infinity (so that we
24    can still distinguish bad spacings by the number of BAD_SPACING_PENALTYs
25    that they incur.
26
27    BAD_SPACING_PENALTY is for occasions where the spacing is bad.
28    TERRIBLE_SPACING_PENALTY is for when we are disregarding a user override
29    (for example, we are failing to satisfy min-systems-per-page. These user
30    overrides are more important than getting good spacing, so they get a
31    larger penalty.
32 */
33 const Real BAD_SPACING_PENALTY = 1e6;
34 const Real TERRIBLE_SPACING_PENALTY = 1e8;
35
36
37 /* for page_count > 2, we use a dynamic algorithm similar to
38    constrained-breaking -- we have a class that stores the intermediate
39    calculations so they can be reused for querying different page counts.
40 */
41 class Page_spacer
42 {
43 public:
44   Page_spacer (vector<Line_details> const &lines, vsize first_page_num, Page_breaking const*);
45   Page_spacing_result solve (vsize page_count);
46
47 private:
48   struct Page_spacing_node
49   {
50     Page_spacing_node ()
51     {
52       demerits_ = infinity_f;
53       force_ = infinity_f;
54       penalty_ = infinity_f;
55       prev_ = VPOS;
56     }
57
58     Real demerits_;
59     Real force_;
60     Real penalty_;
61     vsize prev_;
62   };
63
64   Page_breaking const *breaker_;
65   vsize first_page_num_;
66   vector<Line_details> lines_;
67   Matrix<Page_spacing_node> state_;
68   vsize max_page_count_;
69
70   bool ragged_;
71   bool ragged_last_;
72
73   void resize (vsize page_count);
74   bool calc_subproblem (vsize page, vsize lines);
75 };
76
77 struct Page_spacing
78 {
79   Real force_;
80   Real page_height_;
81   Real rod_height_;
82   Real spring_len_;
83   Real inverse_spring_k_;
84   Real page_top_space_;
85
86   Line_details last_line_;
87   Line_details first_line_;
88
89   Page_spacing (Real page_height, Real page_top_space)
90   {
91     page_height_ = page_height;
92     page_top_space_ = page_top_space;
93     clear ();
94   }
95
96   void calc_force ();
97   void resize (Real new_height);
98   void append_system (const Line_details &line);
99   void prepend_system (const Line_details &line);
100   void clear ();
101 };
102
103 #endif /* PAGE_SPACING_HH */