2 constrained-breaking.hh -- declare a line breaker that
3 supports limits on the number of systems
5 source file of the GNU LilyPond music typesetter
7 (c) 2006--2009 Joe Neeman <joeneeman@gmail.com>
10 #ifndef CONSTRAINED_BREAKING_HH
11 #define CONSTRAINED_BREAKING_HH
13 #include "lily-guile.hh"
20 Interval extent_; /* Y-extent of the system */
22 Real padding_; /* compulsory space after this system (if we're not
25 Real space_; /* spring length */
28 SCM break_permission_;
37 /* The page-breaker deals with forbidden page breaks by "compressing"
38 two Line_detailses into one. The following fields are used by the
39 page-breaker to keep track of this. If the number of fields needed
40 by the page-breaker grows, it might be a good idea to create a separate
42 int compressed_lines_count_;
43 int compressed_nontitle_lines_count_;
53 break_permission_ = ly_symbol2scm ("allow");
54 page_permission_ = ly_symbol2scm ("allow");
55 turn_permission_ = ly_symbol2scm ("allow");
60 compressed_lines_count_ = 1;
61 compressed_nontitle_lines_count_ = 1;
64 Line_details (Prob *pb)
68 extent_ = unsmob_stencil (pb->get_property ("stencil")) ->extent (Y_AXIS);
69 padding_ = robust_scm2double (pb->get_property ("next-padding"), 0);
71 space_ = robust_scm2double (pb->get_property ("next-space"), 1.0);
73 break_permission_ = ly_symbol2scm ("allow");
74 page_permission_ = pb->get_property ("page-break-permission");
75 turn_permission_ = pb->get_property ("page-turn-permission");
77 page_penalty_ = robust_scm2double (pb->get_property ("page-break-penalty"), 0);
78 turn_penalty_ = robust_scm2double (pb->get_property ("page-turn-penalty"), 0);
79 title_ = to_boolean (pb->get_property ("is-title"));
80 compressed_lines_count_ = 1;
81 compressed_nontitle_lines_count_ = title_ ? 0 : 1;
86 Helper to trace back an optimal path
88 struct Constrained_break_node
90 /* the number of bars in all the systems before this one
94 /* unlike the Gourlay breaker, this is the sum of all demerits up to,
95 * and including, this line */
97 struct Line_details details_;
99 Constrained_break_node ()
102 demerits_ = infinity_f;
107 printf ("prev break %d, demerits %f\n", prev_, demerits_);
112 A dynamic programming solution to breaking scores into lines
114 class Constrained_breaking
117 vector<Column_x_positions> solve (vsize start, vsize end, vsize sys_count);
118 vector<Column_x_positions> best_solution (vsize start, vsize end);
119 vector<Line_details> line_details (vsize start, vsize end, vsize sys_count);
121 Constrained_breaking (Paper_score *ps);
122 Constrained_breaking (Paper_score *ps, vector<vsize> const &start_col_posns);
124 int max_system_count (vsize start, vsize end);
125 int min_system_count (vsize start, vsize end);
128 Paper_score *pscore_;
129 vsize valid_systems_;
133 Real between_system_space_;
134 Real between_system_padding_;
136 /* the (i,j)th entry is the configuration for breaking between
138 Matrix<Line_details> lines_;
140 /* the [i](j,k)th entry is the score for fitting the first k bars onto the
141 first j systems, starting at the i'th allowed starting column */
142 vector<Matrix<Constrained_break_node> > state_;
144 vector<vsize> start_; /* the columns at which we might be asked to start breaking */
145 vector<vsize> starting_breakpoints_; /* the corresponding index in breaks_ */
148 vector<vsize> breaks_;
151 void resize (vsize systems);
153 Column_x_positions space_line (vsize start_col, vsize end_col);
154 vsize prepare_solution (vsize start, vsize end, vsize sys_count);
156 Real combine_demerits (Real force, Real prev_force);
158 bool calc_subproblem (vsize start, vsize systems, vsize max_break_index);
159 void fill_line_details (Line_details *const, vsize, vsize);
161 #endif /* CONSTRAINED_BREAKING_HH */