2 p-score.cc -- implement PScore
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9 #include "super-elem.hh"
13 #include "paper-def.hh"
14 #include "scoreline.hh"
16 #include "tex-stream.hh"
19 #include "word-wrap.hh"
20 #include "gourlay-breaking.hh"
22 PScore::PScore(Paper_def*p)
25 super_elem_l_ = new Super_elem;
26 typeset_element(super_elem_l_);
31 super_elem_l_->unlink_all();
35 PScore::typeset_element(Score_elem * elem_p)
37 elem_p_list_.bottom().add(elem_p);
38 elem_p->pscore_l_ = this;
40 elem_p->add_processing();
44 PScore::typeset_item(Item *i, PCol *c, int breakstat)
48 if (breakstat == -1) {
49 typeset_item(i, c->prebreak_p_);
54 typeset_item(i, c->postbreak_p_);
63 PScore::typeset_broken_spanner(Spanner*span_p)
65 span_p->left_col_l_->starters.bottom().add (span_p);
66 span_p->right_col_l_->stoppers.bottom().add(span_p);
67 assert(span_p->left_col_l_->line_l_ == span_p->right_col_l_->line_l_);
69 typeset_element(span_p);
74 PScore::typeset_unbroken_spanner(Spanner*span_p)
76 span_p_list_.bottom().add(span_p);
77 span_p->pscore_l_=this;
79 if (span_p->left_col_l_)
80 span_p->left_col_l_->used_b_ = true;
81 if ( span_p->right_col_l_)
82 span_p->right_col_l_->used_b_ = true;
84 // do not init start/stop fields. These are for broken spans only.
85 span_p->add_processing();
93 for (iter_top(col_p_list_,c); c.ok(); )
97 c->set_rank(rank_i++);
106 if (p->breakable_b()){
107 p->prebreak_p_->pscore_l_ = this;
108 p->postbreak_p_->pscore_l_ = this;
110 col_p_list_.bottom().add(p);
114 PScore::output(Tex_stream &ts)
116 ts << "\n "<< paper_l_->lookup_l()->texsetting << "%(Tex id)\n";
117 ts<< super_elem_l_->TeX_string();
118 ts << "\n\\EndLilyPondOutput";
126 for (iter_top(col_p_list_,cc); cc.ok(); cc++)
132 PScore::print() const
139 mtor << "\n elements: ";
140 for (iter_top(elem_p_list_,cc); cc.ok(); cc++)
142 mtor << "\n unbroken spanners: ";
143 for (iter(span_p_list_.top(), i); i.ok(); i++)
145 mtor << "\ncolumns: ";
146 for (iter_top(col_p_list_,cc); cc.ok(); cc++)
156 super_elem_l_->breakable_col_processing();
157 super_elem_l_->pre_processing();
161 PScore::postprocess()
163 super_elem_l_->post_processing();
164 super_elem_l_->molecule_processing();
168 PScore::find_col(PCol const *c)const
170 PCol const *what = c;
172 what = what->daddy_l_;
174 return col_p_list_.find((PCol*)what);
179 PScore::set_breaking(Array<Col_hpositions> const &breaking)
181 super_elem_l_->line_of_score_l_->set_breaking( breaking);
182 super_elem_l_->break_processing();
185 for (iter(span_p_list_.top(),i); i.ok(); ) {
186 Spanner *span_p = i.remove_p();
187 if (span_p->broken_b()) {
191 typeset_broken_spanner(span_p);
194 for (iter(elem_p_list_.top(),i ); i.ok() ;) {
195 Item *i_l =i->item();
196 if ( i_l && !i_l->pcol_l_->line_l_) {
203 for (iter_top(col_p_list_, i); i.ok(); i++)
204 i->clean_breakable_items();
208 PScore::calc_breaking()
210 Break_algorithm *algorithm_p;
211 Array<Col_hpositions> sol;
212 bool try_wrap = ! paper_l_->get_var( "castingalgorithm");
215 algorithm_p = new Gourlay_breaking ;
216 algorithm_p->set_pscore(this);
217 sol = algorithm_p->solve();
220 error ( "Can not solve this casting problem exactly; revert to Word_wrap");
225 algorithm_p = new Word_wrap;
226 algorithm_p->set_pscore(this);
227 sol = algorithm_p->solve();
238 *mlog << "Preprocessing elements... " <<flush;
240 *mlog << "\nCalculating column positions ... " <<flush;
242 *mlog << "\nPostprocessing elements..." << endl;
246 /** Get all breakable columns between l and r, (not counting l and r). */
248 PScore::breakable_col_range(PCol*l,PCol*r)const
250 Link_array<PCol> ret;
252 PCursor<PCol*> start(l ? find_col(l)+1 : col_p_list_.top() );
253 PCursor<PCol*> stop(r ? find_col(r) : col_p_list_.bottom());
256 ugh! windows-suck-suck-suck.
258 while ( PCursor<PCol*>::compare(start,stop) < 0 ) {
259 if (start->breakable_b())
267 PScore::col_range(PCol*l,PCol*r)const
269 Link_array<PCol> ret;
271 PCursor<PCol*> start(l ? find_col(l)+1 : col_p_list_.top() );
272 PCursor<PCol*> stop(r ? find_col(r) : col_p_list_.bottom());
276 ugh! windows-suck-suck-suck.
278 while ( PCursor<PCol*>::compare(start,stop) < 0 )
285 PScore::broken_col_range(PCol*l,PCol*r)const
287 Link_array<PCol> ret;
289 PCursor<PCol*> start(l ? find_col(l)+1 : col_p_list_.top() );
290 PCursor<PCol*> stop(r ? find_col(r) : col_p_list_.bottom());
293 ugh! windows-suck-suck-suck.
295 while ( PCursor<PCol*>::compare(start,stop) < 0 ) {
296 if (start->breakable_b() && !start->line_l_ )