]> git.donarmstrong.com Git - lilypond.git/blob - score.cc
543aca0d5ad2cbd085d3a4d91f8f380fb5dfb0c9
[lilypond.git] / score.cc
1 #include <time.h>
2 #include "tstream.hh"
3 #include "score.hh"
4 #include "pscore.hh"
5 #include "staff.hh"
6 #include "misc.hh"
7 #include "debug.hh"
8
9 void
10 Score::add(Command *c)
11 {
12     commands_.bottom().add(new Command(*c));
13 }
14
15 void
16 Score::add(Staff*s)
17 {
18     s->score_ = this;
19     staffs_.bottom().add(s);    
20 }
21
22
23 void
24 Score::do_pcols()
25 {
26     PCursor<Score_column*> sc(cols_);
27     for (;sc.ok(); sc++) {
28         pscore_->add(sc->pcol);
29     }
30 }
31 /*
32     this sux. Really makeshift.
33     */
34 void
35 Score::do_miscs()
36 {
37     Command c;
38
39     c.when = 0.0;
40     
41     c.code = BREAK_END;
42     commands_.top().insert(new Command(c));    
43     c.code = BREAK_POST;
44     commands_.top().insert(new Command(c));
45     c.code = BREAK_MIDDLE;
46     commands_.top().insert(new Command(c));
47     c.code = BREAK_PRE;
48     commands_.top().insert(new Command(c));
49
50     PCursor<Command*> bot(commands_.bottom());
51     c.when = last();    
52     while (bot.ok() && bot->when > c.when) {
53 //       mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
54        bot.remove();
55        bot = commands_.bottom();
56     }
57    
58     c.code = BREAK_PRE;
59     bot.add(new Command(c));
60     bot++;
61     c.code = BREAK_MIDDLE;
62     bot.add(new Command(c));
63    bot++;
64     c.code = BREAK_POST;
65     bot.add(new Command(c));
66    bot++;
67    c.code = BREAK_END;
68     bot.add(new Command(c));
69     
70    commands_.OK();
71 }
72
73 Mtime
74 Score::last() const
75 {    
76     Mtime l = 0;
77     for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
78         l = MAX(l, stc->last());
79     }
80     return l;
81 }
82 void
83 Score::clean_commands() 
84 {
85     Mtime l= last();
86     for (PCursor<Command*> cc(commands_); cc.ok(); cc++) {
87         if (cc->when > l){
88            mtor << "remming \n";
89             cc.remove();
90         }
91     }
92 }
93 void
94 Score::process()
95 {
96      do_miscs();
97     
98     /// distribute commands to disciples
99     distribute_commands();
100     
101     pscore_ = new PScore;
102     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
103         sc->set_output(pscore_);
104         sc->process();
105     }
106     do_pcols();
107     calc_idealspacing();
108     clean_cols();
109     OK();
110     //    print();
111     pscore_->calc_breaking();
112 }
113
114 // remove empty cols with no spacing attached.
115 /* should rethink ownership of cols
116     */
117 void
118 Score::clean_cols()
119 {
120     for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
121         sc->clean_cols();
122     for (PCursor<Score_column*> c(cols_); c.ok(); c++) {
123         if (!c->pcol->used) {
124 //          mtor << "removing : "; c->print();
125             c.remove();
126         }
127     }
128     
129     pscore_->clean_cols();
130 }
131 /* this sux.  We should have Score_column create the appropriate PCol.
132     Unfortunately, PCols don't know about their position.    
133     */
134 // todo
135 PCursor<Score_column*>
136 Score::create_cols(Mtime w)
137 {
138     Score_column* c1 = new Score_column(w);
139     Score_column* c2 = new Score_column(w);
140     
141     c1->musical = false;
142     c2->musical = true;
143     
144     PCursor<Score_column*> scc(cols_);
145
146     for (; scc.ok(); scc++) {
147         assert(scc->when != w);
148         if (scc->when > w)
149             break;
150     }
151
152     if (!scc.ok()) {
153         cols_.bottom().add(c1);
154         cols_.bottom().add(c2);
155         scc = cols_.bottom();
156         scc --;
157     } else {
158         scc.insert(c1);
159         scc.insert(c2);
160         scc -= 2;
161     }
162     return scc;
163 }
164
165 Score_column*
166 Score::find_col(Mtime w,bool mus)
167 {
168     PCursor<Score_column*> scc(cols_);
169     for (; scc.ok(); scc++) {
170         if (scc->when == w && scc->musical == mus)
171             return scc;
172         if (scc->when > w)
173             break;
174     }
175     scc = create_cols(w);
176     if (mus)
177         scc++;
178     return scc;
179 }
180
181 void
182 Score::distribute_commands(void)
183 {
184     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
185         sc->add_commands(commands_);
186     }
187 }
188
189
190 void
191 Score::output(String s)
192 {
193     OK();
194     mtor << "output to " << s << "...\n";
195
196     Tex_stream the_output(s);
197     the_output << "% Automatically generated by LilyPond 0.0 at";
198     time_t t(time(0));
199     the_output << ctime(&t)<<"\n";
200     the_output << "% from input file ..\n";
201     pscore_->output(the_output);
202 }
203
204 void
205 Score::OK() const
206 {
207     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
208         sc->OK();
209         assert(sc->score_ == this);
210     }
211     staffs_.OK();
212     cols_.OK();
213     for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
214         assert(cc->when <= (cc+1)->when);
215     }
216     for (PCursor<Command*> cc(commands_); cc.ok() && (cc+1).ok(); cc++) {
217         assert(cc->when <= (cc+1)->when);
218     }
219     
220 }
221
222 void
223 Score::print() const
224 {
225     mtor << "score {\n"; 
226     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
227         sc->print();
228     }
229     for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
230         sc->print();
231     }
232     mtor << "}\n";
233 }
234
235 /****************************************************************/
236
237 Score_column::Score_column(Mtime w)
238 {
239     when = w;
240     pcol = new PCol(0);
241     musical = false;
242 }
243
244 bool
245 Score_column::used() {
246     return pcol->used;
247 }
248
249 void
250 Score_column::print() const
251 {
252     mtor << "Score_column { mus "<< musical <<" at " <<  when<<'\n';
253     mtor << " # symbols: " << pcol->its.size() << "\n";
254     mtor << "durations: [" ;
255     for (int i=0; i < durations.sz(); i++)
256         mtor << durations[i] << " ";
257     mtor << "]\n}\n";
258 }