]> git.donarmstrong.com Git - lilypond.git/blob - score.cc
release: 0.0.5
[lilypond.git] / score.cc
1 #include "scommands.hh"
2 #include "tstream.hh"
3 #include "score.hh"
4 #include "sccol.hh"
5 #include "pscore.hh"
6 #include "staff.hh"
7 #include "debug.hh"
8 #include "paper.hh"
9
10 void
11 Score::set(Paperdef*p)
12 {
13     delete paper_;
14     paper_ = p;
15 }
16 void
17 Score::output(String s)
18 {
19     OK();
20     if (paper_->outfile=="")
21         paper_->outfile = s;
22     
23     *mlog << "output to " << paper_->outfile << "...\n";
24     Tex_stream the_output(paper_->outfile);    
25     pscore_->output(the_output);
26 }
27
28
29 void
30 Score::process()
31 {
32     set(commands_->parse(last()));
33     commands_->print();
34     
35     if (!paper_)
36         paper_ = new Paperdef;
37     
38     commands_->clean(last());
39     
40     /// distribute commands to disciples
41     distribute_commands();
42     
43     pscore_ = new PScore;
44     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
45         sc->set_output(pscore_);
46         sc->process();
47     }
48
49     // do this after processing, staffs first have to generate PCols.
50     do_pcols();
51     calc_idealspacing();
52     clean_cols();
53     OK();
54     //    print();
55     pscore_->calc_breaking();
56     // TODO: calculate vertical structs
57     // TODO: calculate mixed structs.
58 }
59
60 // remove empty cols with no spacing attached.
61 /* should rethink ownership of cols
62     */
63 void
64 Score::clean_cols()
65 {    
66     for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
67         sc->clean_cols();
68     
69     for (PCursor<Score_column*> c(cols_); c.ok(); ) {
70         if (!c->pcol->used) {
71             mtor << "removing : ";
72             c->print();
73             c.del();
74         } else
75             c++;
76     }
77     
78     pscore_->clean_cols();
79 }
80 /* this sux.  We should have Score_column create the appropriate PCol.
81     Unfortunately, PCols don't know about their position.    
82     */
83 // todo
84 PCursor<Score_column*>
85 Score::create_cols(Real w)
86 {
87     Score_column* c1 = new Score_column(w);
88     Score_column* c2 = new Score_column(w);
89     
90     c1->musical = false;
91     c2->musical = true;
92     
93     PCursor<Score_column*> scc(cols_);
94
95     for (; scc.ok(); scc++) {
96         assert(scc->when != w);
97         if (scc->when > w)
98             break;
99     }
100
101     if (!scc.ok()) {
102         cols_.bottom().add(c1);
103         cols_.bottom().add(c2);
104         scc = cols_.bottom();
105         scc --;
106     } else {
107         scc.insert(c1);
108         scc.insert(c2);
109         scc -= 2;
110     }
111     return scc;
112 }
113
114 Score_column*
115 Score::find_col(Real w,bool mus)
116 {
117     PCursor<Score_column*> scc(cols_);
118     for (; scc.ok(); scc++) {
119         if (scc->when == w && scc->musical == mus)
120             return scc;
121         if (scc->when > w)
122             break;
123     }
124     scc = create_cols(w);
125     if (mus)
126         scc++;
127     return scc;
128 }
129
130 void
131 Score::distribute_commands(void)
132 {
133     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
134         sc->add_commands(*commands_);
135     }
136 }
137 void
138 Score::add(Staff*s)
139 {
140     s->score_ = this;
141     staffs_.bottom().add(s);    
142 }
143
144
145 void
146 Score::do_pcols()
147 {
148     PCursor<Score_column*> sc(cols_);
149     for (; sc.ok(); sc++) {
150         pscore_->add(sc->pcol);
151     }
152 }
153 Real
154 Score::last() const
155 {    
156     Real l = 0;
157     for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
158         l = MAX(l, stc->last());
159     }
160     return l;
161 }
162
163 void
164 Score::OK() const
165 {
166 #ifndef NDEBUG
167     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
168         sc->OK();
169         assert(sc->score_ == this);
170     }
171     staffs_.OK();
172     cols_.OK();
173     for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
174         assert(cc->when <= (cc+1)->when);
175     }
176     commands_->OK();
177 #endif    
178 }
179
180
181 void
182 Score::print() const
183 {
184 #ifndef NPRINT
185     mtor << "score {\n"; 
186     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
187         sc->print();
188     }
189     for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
190         sc->print();
191     }
192     commands_->print();
193     mtor << "}\n";
194 #endif
195 }
196
197 Score::Score()
198 {
199     pscore_=0;
200     paper_ = 0;
201     commands_ = new Score_commands;
202 }
203
204 Score::~Score()
205 {
206     delete pscore_;
207     delete commands_;
208     delete paper_;
209 }
210
211 void
212 Score::set(Score_commands*c)
213 {
214     delete commands_;
215     commands_ = c;
216 }