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