lilypond-0.0.2
[lilypond.git] / score.cc
blob543aca0d5ad2cbd085d3a4d91f8f380fb5dfb0c9
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"
9 void
10 Score::add(Command *c)
12 commands_.bottom().add(new Command(*c));
15 void
16 Score::add(Staff*s)
18 s->score_ = this;
19 staffs_.bottom().add(s);
23 void
24 Score::do_pcols()
26 PCursor<Score_column*> sc(cols_);
27 for (;sc.ok(); sc++) {
28 pscore_->add(sc->pcol);
32 this sux. Really makeshift.
34 void
35 Score::do_miscs()
37 Command c;
39 c.when = 0.0;
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));
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();
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));
70 commands_.OK();
73 Mtime
74 Score::last() const
76 Mtime l = 0;
77 for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
78 l = MAX(l, stc->last());
80 return l;
82 void
83 Score::clean_commands()
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();
93 void
94 Score::process()
96 do_miscs();
98 /// distribute commands to disciples
99 distribute_commands();
101 pscore_ = new PScore;
102 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
103 sc->set_output(pscore_);
104 sc->process();
106 do_pcols();
107 calc_idealspacing();
108 clean_cols();
109 OK();
110 // print();
111 pscore_->calc_breaking();
114 // remove empty cols with no spacing attached.
115 /* should rethink ownership of cols
117 void
118 Score::clean_cols()
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();
129 pscore_->clean_cols();
131 /* this sux. We should have Score_column create the appropriate PCol.
132 Unfortunately, PCols don't know about their position.
134 // todo
135 PCursor<Score_column*>
136 Score::create_cols(Mtime w)
138 Score_column* c1 = new Score_column(w);
139 Score_column* c2 = new Score_column(w);
141 c1->musical = false;
142 c2->musical = true;
144 PCursor<Score_column*> scc(cols_);
146 for (; scc.ok(); scc++) {
147 assert(scc->when != w);
148 if (scc->when > w)
149 break;
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;
162 return scc;
165 Score_column*
166 Score::find_col(Mtime w,bool mus)
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;
175 scc = create_cols(w);
176 if (mus)
177 scc++;
178 return scc;
181 void
182 Score::distribute_commands(void)
184 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
185 sc->add_commands(commands_);
190 void
191 Score::output(String s)
193 OK();
194 mtor << "output to " << s << "...\n";
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);
204 void
205 Score::OK() const
207 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
208 sc->OK();
209 assert(sc->score_ == this);
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);
216 for (PCursor<Command*> cc(commands_); cc.ok() && (cc+1).ok(); cc++) {
217 assert(cc->when <= (cc+1)->when);
222 void
223 Score::print() const
225 mtor << "score {\n";
226 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
227 sc->print();
229 for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
230 sc->print();
232 mtor << "}\n";
235 /****************************************************************/
237 Score_column::Score_column(Mtime w)
239 when = w;
240 pcol = new PCol(0);
241 musical = false;
244 bool
245 Score_column::used() {
246 return pcol->used;
249 void
250 Score_column::print() const
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";