]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/constrained-breaking.hh
Fix some bugs in the dynamic engraver and PostScript backend
[lilypond.git] / lily / include / constrained-breaking.hh
1 /*
2   constrained-breaking.hh -- declare a line breaker that
3   supports limits on the number of systems
4
5   source file of the GNU LilyPond music typesetter
6
7   (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
9
10 #ifndef CONSTRAINED_BREAKING_HH
11 #define CONSTRAINED_BREAKING_HH
12
13 #include "break-algorithm.hh"
14 #include "lily-guile.hh"
15
16 struct Line_details {
17   Real force_;
18   Real extent_;   /* Y-extent of the system */
19   Real padding_;  /* compulsory space after this system (if we're not last on a page) */
20   Real space_;    /* spring length (stretches over extent_ but not over padding_) */
21   Real inverse_hooke_;
22
23   SCM break_permission_;
24   SCM page_permission_;
25   SCM turn_permission_;
26   Real break_penalty_;
27   Real page_penalty_;
28   Real turn_penalty_;
29
30   Line_details ()
31   {
32     force_ = infinity_f;
33     extent_ = 0;
34     padding_ = 0;
35     space_ = 0;
36     inverse_hooke_ = 1;
37     break_permission_ = ly_symbol2scm ("allow");
38     page_permission_ = ly_symbol2scm ("allow");
39     turn_permission_ = ly_symbol2scm ("allow");
40     break_penalty_ = 0;
41     page_penalty_ = 0;
42     turn_penalty_ = 0;
43   }
44 };
45
46 /*
47    Helper to trace back an optimal path
48 */
49 struct Constrained_break_node
50 {
51   /* the number of bars in all the systems before this one
52   */
53   int prev_;
54
55   /* unlike the Gourlay breaker, this is the sum of all demerits up to,
56    * and including, this line */
57   Real demerits_;
58   struct Line_details details_;
59
60   Constrained_break_node ()
61   {
62     prev_ = -1;
63     demerits_ = infinity_f;
64   }
65
66   void print () const
67   {
68     printf ("prev break %d, demerits %f\n", prev_, demerits_);
69   }
70 };
71
72 /*
73    A dynamic programming solution to breaking scores into lines
74 */
75 class Constrained_breaking : public Break_algorithm
76 {
77 public:
78   vector<Column_x_positions> solve ();
79   Constrained_breaking ();
80   Constrained_breaking (vector<vsize> const &start_col_posns);
81
82   vector<Column_x_positions> get_solution(vsize start, vsize end, vsize sys_count);
83   vector<Line_details> get_details (vsize start, vsize end, vsize sys_count);
84   int get_max_systems (vsize start, vsize end);
85   int get_min_systems (vsize start, vsize end);
86
87   void resize (vsize systems);
88
89 private:
90   vsize valid_systems_;
91   vsize systems_;
92
93   /* the (i,j)th entry is the configuration for breaking between
94     columns i and j */
95   vector<Line_details> lines_;
96   vsize lines_rank_;
97
98   /* the [i](j,k)th entry is the score for fitting the first k bars onto the
99     first j systems, starting at the i'th allowed starting column */
100   vector<vector<Constrained_break_node> > state_;
101
102   vector<vsize> start_;         /* the columns at which we might be asked to start breaking */
103   vector<vsize> starting_breakpoints_; /* the corresponding index in breaks_ */
104
105   vector<Grob*> all_;
106   vector<vsize> breaks_;
107
108   Column_x_positions space_line (vsize start_col, vsize end_col);
109   void prepare_solution (vsize start, vsize end, vsize sys_count, vsize *rank, vsize *brk);
110
111   Real combine_demerits (Real force, Real prev_force);
112
113   bool calc_subproblem(vsize start, vsize systems, vsize max_break_index);
114 };
115 #endif /* CONSTRAINED_BREAKING_HH */