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