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