lilypond-1.3.130
[lilypond.git] / lily / pscore.cc
blob989a0f92d7e74b7ac4afd0c256e7b451ac563369
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 "pscore.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 for (iter_top(cols,c); c.ok(); )
30 if (!c->used_b()) {
31 delete c.remove_p();
32 } else
33 c++;
37 void
38 PScore::add(PStaff *s)
40 assert(s->pscore_l_ == this);
41 staffs.bottom().add(s);
45 void
46 PScore::do_connect(PCol *c1, PCol *c2, Real d, Real h)
48 if (!c1 || !c2 )
49 return;
50 Idealspacing*s_l=get_spacing(c1,c2);
53 s_l->hooke = h;
54 s_l->space =d;
57 void
58 PScore::connect(PCol* c1, PCol *c2, Real d, Real h)
60 do_connect(c1,c2,d,h);
61 do_connect(c1->postbreak_p_, c2,d,h);
62 do_connect(c1, c2->prebreak_p_,d,h);
63 do_connect(c1->postbreak_p_, c2->prebreak_p_,d,h);
66 void
67 PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
69 assert(c && i && s);
71 if (breakstat == 0) {
72 typeset_item(i, c->prebreak_p_, s);
73 return;
76 if (breakstat == 2) {
77 typeset_item(i, c->postbreak_p_, s);
78 return;
82 its.bottom().add(i);
83 s->add(i);
84 c->add(i);
86 /* first do this, because i->width() may follow the 0-pointer */
87 i->add_processing();
90 void
91 PScore::typeset_spanner(Spanner*span_p, PStaff*ps)
93 span_p->pstaff_l_ = ps;
94 spanners.bottom().add(span_p);
95 ps->spans.bottom().add(span_p);
97 // do not init start/stop fields. These are for broken spans only.
98 span_p->add_processing();
102 void
103 PScore::add(PCol *p)
105 p->pscore_l_ = this;
106 if (p->breakable_b()){
107 p->prebreak_p_->pscore_l_ = this;
108 p->postbreak_p_->pscore_l_ = this;
110 cols.bottom().add(p);
113 PScore::PScore( Paper_def*p)
115 paper_l_ = p;
118 void
119 PScore::output(Tex_stream &ts)
121 int l=1;
123 ts << "\n "<< paper_l_->lookup_l()->texsetting << "%(Tex id)\n";
124 for (iter_top(lines,lic); lic.ok(); lic++) {
125 ts << "% line of score no. " << l++ <<"\n";
126 ts << lic->TeXstring();
127 if ((lic+1).ok())
128 ts << "\\interscoreline\n";
133 Array<Item*>
134 PScore::select_items(PStaff*ps, PCol*pc)
136 Array<Item*> ret;
137 assert(ps && pc);
138 for (iter_top(pc->its,i); i.ok(); i++){
139 if (i->pstaff_l_ == ps)
140 ret.push((Item*)(const Item*)i);
142 return ret;
145 void
146 PScore::OK()const
148 #ifdef NDEBUG
149 for (iter_top(cols,cc); cc.ok(); cc++)
150 cc->OK();
151 for (iter_top(suz,i); i.ok(); i++)
152 i->OK();
153 #endif
156 void
157 PScore::print() const
159 #ifndef NPRINT
160 mtor << "PScore { ";
161 paper_l_->print();
162 mtor << "\ncolumns: ";
163 for (iter_top(cols,cc); cc.ok(); cc++)
164 cc->print();
166 mtor << "\nideals: ";
167 for (iter_top(suz,i); i.ok(); i++)
168 i->print();
169 mtor << "}\n";
170 #endif
173 void
174 PScore::preprocess()
176 for (iter_top(spanners,i); i.ok(); i++) {
177 i->pre_processing();
179 for (iter_top(its,i); i.ok(); i++){
180 i->pre_processing();
184 void
185 PScore::postprocess()
187 for (iter_top(broken_spans,i); i.ok(); i++) { // could chase spans as well.
188 i->post_processing();
190 for (iter_top(its,i); i.ok(); i++){
191 i->post_processing();
194 for (iter_top(broken_spans,i); i.ok(); i++) {
195 i->molecule_processing();
197 for (iter_top(its,i); i.ok(); i++){
198 i->molecule_processing();
201 for (iter_top(lines,i); i.ok(); i++)
202 i->process();
206 PCursor<PCol *>
207 PScore::find_col(const PCol *c)const
209 const PCol*what = c;
210 if (what->daddy_l_ )
211 what = what->daddy_l_;
213 return cols.find((PCol*)what);
216 void
217 PScore::add_broken(Spanner*s)
219 assert(s->left->line_l_ == s->right->line_l_);
220 broken_spans.bottom().add(s);
221 s->left->starters.bottom().add (s);
222 s->right->stoppers.bottom().add (s);
225 void
226 PScore::set_breaking(Array<Col_hpositions> breaking)
228 for (int j=0; j < breaking.size(); j++) {
229 Array<PCol*> &curline(breaking[j].cols);
230 Array<Real> &config(breaking[j].config);
232 Line_of_score *s_p = new Line_of_score(curline,this);
233 lines.bottom().add(s_p);
234 for (int i=0; i < curline.size(); i++){
235 curline[i]->hpos = config[i];
240 void
241 PScore::calc_breaking()
243 Word_wrap w(*this);
244 set_breaking(w.solve());
247 void
248 PScore::process()
250 clean_cols();
251 *mlog << "Preprocessing ... " <<flush;
252 preprocess();
253 *mlog << "\nCalculating column positions ... " <<flush;
254 calc_breaking();
255 *mlog << "\nPostprocessing ..." << endl;
256 postprocess();