]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/page-breaking.hh
Merge branch 'master' of ssh+git://gpercival@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / lily / include / page-breaking.hh
1 /*
2   page-breaking.hh -- declare a superclass and utility
3   functions for several different page-breaking algorithms
4
5   source file of the GNU LilyPond music typesetter
6
7   (c) 2006--2007 Joe Neeman <joeneeman@gmail.com>
8 */
9
10 #ifndef PAGE_BREAKING_HH
11 #define PAGE_BREAKING_HH
12
13 #include "constrained-breaking.hh"
14
15 /* Either a paper-score, markup or header.
16  */
17 struct System_spec
18 {
19   System_spec (Paper_score *ps)
20   {
21     pscore_ = ps;
22     prob_ = NULL;
23   }
24
25   System_spec (Prob *pb)
26   {
27     prob_ = pb;
28     pscore_ = NULL;
29   }
30
31   System_spec ()
32   {
33     pscore_ = NULL;
34     prob_ = NULL;
35   }
36
37   Paper_score *pscore_;
38   Prob *prob_;
39 };
40
41 struct Break_position
42 {
43   vsize sys_; /* our index in the all_ list */
44   vsize score_break_; /* if sys_ is a score, then we start at the score_brk_'th
45                          possible page-break in the score */
46   Grob *col_;  /* if sys_ is a score, this points to the broken column */
47   bool score_ender_;
48
49   Break_position (vsize s=VPOS, vsize brk=VPOS, Grob *g=NULL, bool end=false)
50   {
51     sys_ = s;
52     score_break_ = brk;
53     col_ = g;
54     score_ender_ = end;
55   }
56
57   bool operator< (const Break_position &other)
58   {
59     return (sys_ == VPOS && other.sys_ != VPOS)
60       || (sys_ < other.sys_)
61       || (sys_ == other.sys_ && score_break_ < other.score_break_);
62   }
63
64   bool operator<= (const Break_position &other)
65   {
66     return (sys_ == VPOS)
67       || (sys_ < other.sys_ && other.sys_ != VPOS)
68       || (sys_ == other.sys_ && score_break_ <= other.score_break_);
69   }
70 };
71
72 class Page_breaking
73 {
74 public:
75   typedef bool (*Break_predicate) (Grob *);
76   typedef vector<vsize> Line_division;
77   virtual SCM solve () = 0;
78
79   Page_breaking (Paper_book *pb, Break_predicate);
80   virtual ~Page_breaking ();
81
82 protected:
83   Paper_book *book_;
84
85   Real page_height (int page_number, bool last);
86   vsize next_system (Break_position const &break_pos) const;
87
88   SCM make_pages (vector<vsize> lines_per_page, SCM lines);
89
90   vsize min_system_count (vsize start, vsize end);
91   vsize max_system_count (vsize start, vsize end);
92   vector<Line_details> line_details (vsize start, vsize end, Line_division const &div);
93
94   void break_into_pieces (vsize start, vsize end, Line_division const &div);
95   SCM systems ();
96
97
98   vector<Line_division> line_divisions (vsize start,
99                                         vsize end,
100                                         vsize system_count,
101                                         Line_division lower_bound = Line_division (),
102                                         Line_division upper_bound = Line_division ());
103
104   SCM breakpoint_property (vsize breakpoint, char const *str);
105   vector<Break_position> breaks_;
106
107 private:
108   vector<Break_position> chunks_;
109   vector<System_spec> all_;
110   vector<Constrained_breaking> line_breaking_;
111
112   vector<Break_position> chunk_list (vsize start, vsize end);
113   Line_division system_count_bounds (vector<Break_position> const &chunks, bool min);
114   void line_breaker_args (vsize i,
115                           Break_position const &start,
116                           Break_position const &end,
117                           vsize *line_breaker_start,
118                           vsize *line_breaker_end);
119
120   void line_divisions_rec (vsize system_count,
121                            Line_division const &min,
122                            Line_division const &max,
123                            vector<Line_division> *result,
124                            Line_division *cur);
125
126   void create_system_list ();
127   void find_chunks_and_breaks (Break_predicate);
128 };
129 #endif /* PAGE_BREAKING_HH */