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