lilypond-0.0.62
[lilypond.git] / lily / p-score.cc
blob24421334ab955f99922618156380bfd918ef9368
1 #include "idealspacing.hh"
2 #include "debug.hh"
3 #include "lookup.hh"
4 #include "spanner.hh"
5 #include "paper-def.hh"
6 #include "molecule.hh"
7 #include "dimen.hh"
8 #include "scoreline.hh"
9 #include "p-score.hh"
10 #include "tex-stream.hh"
11 #include "item.hh"
12 #include "break.hh"
14 Idealspacing*
15 PScore::get_spacing(PCol*l, PCol*r)
17 assert(l!=r);
19 Idealspacing*i_p =new Idealspacing(l,r);
20 suz.bottom().add(i_p);
22 return i_p;
26 void
27 PScore::clean_cols()
29 int rank_i = 0;
30 for (iter_top(cols,c); c.ok(); )
31 if (!c->used_b()) {
32 delete c.remove_p();
33 } else {
34 c->set_rank(rank_i++);
35 c++;
41 void
42 PScore::add(PStaff *s)
44 assert(s->pscore_l_ == this);
45 staffs.bottom().add(s);
49 void
50 PScore::do_connect(PCol *c1, PCol *c2, Real d, Real h)
52 if (!c1 || !c2 )
53 return;
54 Idealspacing*s_l=get_spacing(c1,c2);
57 s_l->hooke = h;
58 s_l->space =d;
61 void
62 PScore::connect(PCol* c1, PCol *c2, Real d, Real h)
64 do_connect(c1,c2,d,h);
65 do_connect(c1->postbreak_p_, c2,d,h);
66 do_connect(c1, c2->prebreak_p_,d,h);
67 do_connect(c1->postbreak_p_, c2->prebreak_p_,d,h);
70 void
71 PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
73 assert(c && i && s);
75 if (breakstat == 0) {
76 typeset_item(i, c->prebreak_p_, s);
77 return;
80 if (breakstat == 2) {
81 typeset_item(i, c->postbreak_p_, s);
82 return;
86 its.bottom().add(i);
87 s->add(i);
88 c->add(i);
90 /* first do this, because i->width() may follow the 0-pointer */
91 i->add_processing();
94 void
95 PScore::typeset_spanner(Spanner*span_p, PStaff*ps)
97 span_p->pstaff_l_ = ps;
98 spanners.bottom().add(span_p);
99 ps->spans.bottom().add(span_p);
101 // do not init start/stop fields. These are for broken spans only.
102 span_p->add_processing();
106 void
107 PScore::add(PCol *p)
109 p->pscore_l_ = this;
110 if (p->breakable_b()){
111 p->prebreak_p_->pscore_l_ = this;
112 p->postbreak_p_->pscore_l_ = this;
114 cols.bottom().add(p);
117 PScore::PScore( Paper_def*p)
119 paper_l_ = p;
122 void
123 PScore::output(Tex_stream &ts)
125 int l=1;
127 ts << "\n "<< paper_l_->lookup_l()->texsetting << "%(Tex id)\n";
128 for (iter_top(lines,lic); lic.ok(); lic++) {
129 ts << "% line of score no. " << l++ <<"\n";
130 ts << lic->TeXstring();
131 if ((lic+1).ok())
132 ts << "\\interscoreline\n";
134 ts << "\n\\EndLilyPondOutput";
138 Array<Item*>
139 PScore::select_items(PStaff*ps, PCol*pc)
141 Array<Item*> ret;
142 assert(ps && pc);
143 for (iter_top(pc->its,i); i.ok(); i++){
144 if (i->pstaff_l_ == ps)
145 ret.push((Item*)(Item const *)i);
147 return ret;
150 void
151 PScore::OK()const
153 #ifndef NDEBUG
154 for (iter_top(cols,cc); cc.ok(); cc++)
155 cc->OK();
156 for (iter_top(suz,i); i.ok(); i++)
157 i->OK();
158 #endif
161 void
162 PScore::print() const
164 #ifndef NPRINT
165 mtor << "PScore { ";
166 paper_l_->print();
167 mtor << "\ncolumns: ";
168 for (iter_top(cols,cc); cc.ok(); cc++)
169 cc->print();
171 mtor << "\nideals: ";
172 for (iter_top(suz,i); i.ok(); i++)
173 i->print();
174 mtor << "}\n";
175 #endif
178 void
179 PScore::preprocess()
181 for (iter_top(spanners,i); i.ok(); i++) {
182 i->pre_processing();
184 for (iter_top(its,i); i.ok(); i++){
185 i->pre_processing();
189 void
190 PScore::postprocess()
192 for (iter_top(broken_spans,i); i.ok(); i++) { // could chase spans as well.
193 i->post_processing();
195 for (iter_top(its,i); i.ok(); i++){
196 i->post_processing();
199 for (iter_top(broken_spans,i); i.ok(); i++) {
200 i->molecule_processing();
202 for (iter_top(its,i); i.ok(); i++){
203 i->molecule_processing();
206 for (iter_top(lines,i); i.ok(); i++)
207 i->process();
211 PCursor<PCol *>
212 PScore::find_col(PCol const *c)const
214 PCol const *what = c;
215 if (what->daddy_l_ )
216 what = what->daddy_l_;
218 return cols.find((PCol*)what);
221 void
222 PScore::add_broken(Spanner*s)
224 assert(s->left_col_l_->line_l_ == s->right_col_l_->line_l_);
225 broken_spans.bottom().add(s);
226 s->left_col_l_->starters.bottom().add (s);
227 s->right_col_l_->stoppers.bottom().add (s);
230 void
231 PScore::set_breaking(Array<Col_hpositions> const &breaking)
233 for (int j=0; j < breaking.size(); j++) {
234 const Array<PCol*> &curline(breaking[j].cols);
235 const Array<PCol*> &errors(breaking[j].error_col_l_arr_);
236 const Array<Real> &config(breaking[j].config);
238 Line_of_score *s_p = new Line_of_score(curline,this);
239 s_p->error_mark_b_ = breaking[j].ugh_b_;
240 lines.bottom().add(s_p);
241 for (int i=0; i < curline.size(); i++){
242 curline[i]->hpos = config[i];
244 for (int i=0; i < errors.size(); i++)
245 errors[i]->error_mark_b_ = true;
249 void
250 PScore::calc_breaking()
252 Word_wrap w(*this);
253 set_breaking(w.solve());
256 void
257 PScore::process()
259 clean_cols();
260 print();
261 *mlog << "Preprocessing elements... " <<flush;
262 preprocess();
263 *mlog << "\nCalculating column positions ... " <<flush;
264 calc_breaking();
265 *mlog << "\nPostprocessing elements..." << endl;
266 postprocess();