]> git.donarmstrong.com Git - lilypond.git/blob - lily/break.cc
release: 0.1.24
[lilypond.git] / lily / break.cc
1 /*
2   break.cc -- implement Break_algorithm
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9
10 #include "break.hh"
11 #include "paper-def.hh"
12 #include "line-spacer.hh"
13 #include "debug.hh"
14 #include "scoreline.hh"
15 #include "p-score.hh"
16 #include "p-col.hh"
17 #include "cpu-timer.hh"
18
19 String
20 Col_stats::str() const {
21   String s (count_i_);
22   s += _(" lines");
23   if  (count_i_)
24     s += String (Real (cols_i_)/count_i_, _(", (with an average of %.1f columns)"));
25
26   return s;
27 }
28
29 void
30 Col_stats::add (Line_of_cols const& line)
31 {
32   count_i_++;
33   cols_i_ += line.size();
34 }
35
36
37 Col_stats::Col_stats()
38 {
39   count_i_ =0;
40   cols_i_ =0;
41 }
42
43 /* **************************************************************** */
44
45 Line_of_cols
46 Break_algorithm::all_cols() const
47 {
48   Line_of_cols retval;
49   for (PCursor<Paper_column*> c (pscore_l_->col_p_list_.top());
50        c.ok(); c++)
51     {
52
53       retval.push (c);
54     }
55   return retval;
56 }
57
58 Array<int>
59 Break_algorithm::find_break_indices() const
60 {
61   Line_of_cols all (all_cols());
62   Array<int> retval;
63
64   for (int i=0; i < all.size(); i++)
65     if (all[i]->breakable_b_)
66       retval.push (i);
67
68   if (linelength <=0)
69     while (retval.size() >2)
70       retval.del (1);
71
72   return retval;
73 }
74
75 ///  return all breakable columns
76 Line_of_cols
77 Break_algorithm::find_breaks() const
78 {
79   Line_of_cols all (all_cols());
80   Line_of_cols retval;
81
82   for (int i=0; i < all.size(); i++)
83     if (all[i]->breakable_b_)
84       retval.push (all[i]);
85
86
87   if (linelength <=0)
88     while (retval.size() >2)
89       retval.del (1);
90
91   return retval;
92 }
93
94
95
96
97
98 Line_spacer*
99 Break_algorithm::generate_spacing_problem (Line_of_cols curline) const
100 {
101   Line_spacer * sp= (*get_line_spacer)();
102
103   sp->paper_l_ = pscore_l_->paper_l_;
104   sp->add_column (curline[0], true, 0.0);
105   for (int i=1; i< curline.size()-1; i++)
106     sp->add_column (curline[i]);
107
108   if (linelength > 0)
109     sp->add_column (curline.top(), true, linelength);
110   else
111     sp->add_column (curline.top());
112
113   sp->prepare();
114   return sp;
115 }
116
117 Break_algorithm::Break_algorithm()
118 {
119   pscore_l_ = 0;
120   get_line_spacer =0;
121   linelength = 0;
122 }
123
124 void
125 Break_algorithm::set_pscore (Paper_score*s)
126 {
127   pscore_l_ = s;
128   linelength = s->paper_l_->linewidth_f();
129   do_set_pscore();
130 }
131
132 bool
133 Break_algorithm::feasible (Line_of_cols curline) const
134 {
135   if (linelength <=  0)
136     return true;
137
138   Real l =0;
139   for (int i=0; i < curline.size(); i++)
140     l +=curline[i]->width().length ();
141   return l < linelength;
142 }
143
144 void
145 Break_algorithm::problem_OK() const
146 {
147   if (!pscore_l_->col_p_list_.size())
148     error (_("Score does not have any columns"));
149   OK();
150 }
151
152 void
153 Break_algorithm::OK() const
154 {
155 #ifndef NDEBUG
156   iter_top (pscore_l_->col_p_list_,start);
157   PCursor<Paper_column *> end (pscore_l_->col_p_list_.bottom());
158
159   assert (start->breakable_b_);
160   assert (end->breakable_b_);
161 #endif
162 }
163
164 Array<Col_hpositions>
165 Break_algorithm::solve() const
166 {
167   Cpu_timer timer;
168
169   Array<Col_hpositions> h= do_solve();
170
171   if (approx_stats_.count_i_)
172     *mlog << _("\nApproximated: ") << approx_stats_.str() << "\n";
173   if (exact_stats_.count_i_)
174     *mlog << _("Calculated exactly: ") << exact_stats_.str() << "\n";
175   *mlog << _("Time: ") << String(timer.read (), "%.2f") << _(" seconds\n");
176
177   return h;
178 }
179
180 void
181 Break_algorithm::do_set_pscore()
182 {
183
184 }