]> git.donarmstrong.com Git - lilypond.git/blob - src/pscore.cc
release: 0.0.18
[lilypond.git] / src / pscore.cc
1 // utility functions for PScore
2 #include "debug.hh"
3 #include "lookup.hh"
4 #include "spanner.hh"
5 #include "paper.hh"
6 #include "molecule.hh"
7 #include "dimen.hh"
8 #include "scoreline.hh"
9 #include "pscore.hh"
10 #include "tstream.hh"
11
12
13 void
14 PScore::clean_cols()
15 {
16     for (PCursor<PCol *> c(cols); c.ok(); )
17         if (!c->used()) {
18             c.del();
19         } else
20             c++;
21 }
22
23
24 void
25 PScore::add(PStaff *s)
26 {
27     assert(s->pscore_ == this);
28     staffs.bottom().add(s);
29 }
30
31 void
32 PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
33 {
34     assert(c && i && s);
35 //    assert(!breakstat != 4 || c->breakable() );
36     if (breakstat == 0) {
37         typeset_item(i, c->prebreak, s);
38         return;
39     }
40
41     if (breakstat == 2) {
42         typeset_item(i, c->postbreak, s);
43         return;
44     }
45
46
47     its.bottom().add(i);
48     s->add(i);
49     c->add(i);
50
51     /* first do this, because i->width() may follow the 0-pointer */
52     i->preprocess();
53
54
55     if (0 && c->daddy && c == c->daddy->prebreak) { // makeshift.
56         
57         Interval iv (i->width());
58         if (!iv.empty()) {
59             svec<Item*> col_its (select_items(s, c));
60             for (int j =0; j < col_its.sz(); j++)
61                 col_its[j]->translate(Offset(-iv.length(),0));
62             i->translate (Offset(-iv.max, 0));
63         }
64     }
65     
66 }
67
68 void
69 PScore::typeset_spanner(Spanner*sp, PStaff*ps)
70 {
71     sp->preprocess();
72     sp->pstaff_ = ps;
73     spanners.bottom().add(sp);
74     ps->spans.bottom().add(sp);
75     // do not init start/stop fields. These are for broken spans only.
76 }
77
78
79 void
80 PScore::add_line(svec< PCol *> curline, svec<Real> config)
81 {    
82     Line_of_score *p = new Line_of_score(curline,this);
83     lines.bottom().add(p);      
84     for (int i=0; i < curline.sz(); i++){
85         PCol *c=(PCol *)curline[i]; // so, this isn't really const.
86         c->hpos = config[i];
87     }
88 }
89
90 Idealspacing*
91 PScore::get_spacing(PCol*l, PCol*r)
92 {
93     assert(l!=r);
94     for (PCursor<Idealspacing*> ic (suz); ic.ok(); ic++) {
95         if (ic->left == l && ic->right == r){
96             return ic;
97         }
98     }
99     
100     Idealspacing*ip =new Idealspacing(l,r);
101     suz.bottom().add(ip);
102
103     return ip;
104 }
105
106
107 int
108 PScore::compare_pcols(PCol*a,  PCol*b)const
109 {
110     PCursor<PCol*> ac(find_col(a));
111     PCursor<PCol*> bc(find_col(b));
112     assert(ac.ok() && bc.ok());
113     return ac - bc;
114 }
115
116 /*
117   return all breakable columns
118  */
119 svec< PCol *>
120 PScore::find_breaks() const
121 {
122     svec< PCol *> retval;
123     for (PCursor<PCol *> c(cols); c.ok(); c++)
124         if (c->breakable())
125             retval.add(c);
126
127     return retval;
128 }
129
130 void
131 PScore::add(PCol *p)
132 {
133     p->pscore_ = this;
134     if (p->breakable()){
135         p->prebreak->pscore_ = this;
136         p->postbreak->pscore_ = this;
137     }
138     cols.bottom().add(p);
139 }
140
141 PScore::PScore( Paperdef*p)
142 {
143     paper_ = p;
144 }
145
146 void
147 PScore::output(Tex_stream &ts)
148 {
149     int l=1;
150
151     ts << "\n "<<  paper_->lookup_->texsetting << "%(Tex id)\n";
152     for (PCursor<Line_of_score*> lic(lines); lic.ok(); lic++) {
153         ts << "% line of score no. " << l++ <<"\n";
154         ts << lic->TeXstring();
155         if ((lic+1).ok())
156             ts << "\\interscoreline\n";
157     }   
158 }
159
160
161 svec<Item*>
162 PScore::select_items(PStaff*ps , PCol*pc)
163 {
164     svec<Item*> ret;
165     assert(ps && pc);
166     for (PCursor<const Item*> ic(pc->its); ic.ok(); ic++){
167         if (ic->pstaff_ == ps)
168             ret.add((Item*)(const Item*)ic);
169     }
170     return ret;
171 }
172
173 void
174 PScore::OK()const
175 {
176 #ifdef NDEBUG
177     for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
178         cc->OK();
179     for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
180         ic->OK();
181 #endif
182 }
183
184 void
185 PScore::print() const
186 {    
187 #ifndef NPRINT
188     mtor << "PScore { ";
189     paper_->print();
190     mtor << "\ncolumns: ";
191     for (PCursor<PCol*> cc(cols); cc.ok(); cc++)
192         cc->print();
193     
194     mtor << "\nideals: ";
195     for (PCursor<Idealspacing*> ic(suz); ic.ok(); ic++)
196         ic->print();
197     mtor << "}\n";
198 #endif 
199 }
200
201 void
202 PScore::preprocess()
203 {
204 }
205
206 void
207 PScore::postprocess()
208 {
209     for (PCursor<Spanner*> ic(broken_spans); ic.ok(); ic++) {
210         ic->process();
211     }
212     for (PCursor<Item*> ic(its); ic.ok(); ic++){
213         ic->postprocess();
214     }
215     for (PCursor<Line_of_score*> i(lines); i.ok(); i++)
216         i->process();
217 }
218
219 PCursor<PCol *>
220 PScore::find_col(PCol *c)const
221 {
222     PCol*what = (PCol*)c;
223     if (what->daddy )
224         what = what -> daddy;
225     
226     return cols.find(what);
227 }
228
229 void
230 PScore::add_broken(Spanner*s)
231 {
232     broken_spans.bottom().add(s);
233     s->left->starters.bottom().add (s);
234     s->right->stoppers.bottom().add (s);
235 }