lilypond-0.0.9
[lilypond.git] / score.cc
blob0f8bbf70de0b6b763add44afceac9c8e1d20e1d7
1 #include "tstream.hh"
2 #include "score.hh"
3 #include "sccol.hh"
4 #include "pscore.hh"
5 #include "staff.hh"
6 #include "debug.hh"
7 #include "paper.hh"
9 void
10 Score::output(String s)
12 OK();
13 if (paper->outfile=="")
14 paper->outfile = s;
16 *mlog << "output to " << paper->outfile << "...\n";
17 Tex_stream the_output(paper->outfile);
18 pscore_->output(the_output);
22 void
23 Score::process()
25 if (!paper)
26 paper = new Paperdef;
28 commands_.clean(last());
30 /// distribute commands to disciples
31 distribute_commands();
33 pscore_ = new PScore;
34 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
35 sc->set_output(pscore_);
36 sc->process();
39 // do this after processing, staffs first have to generate PCols.
40 do_pcols();
41 calc_idealspacing();
42 clean_cols();
43 OK();
44 // print();
45 pscore_->calc_breaking();
46 // TODO: calculate vertical structs
47 // TODO: calculate mixed structs.
50 // remove empty cols with no spacing attached.
51 /* should rethink ownership of cols
53 void
54 Score::clean_cols()
56 for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
57 sc->clean_cols();
59 for (PCursor<Score_column*> c(cols_); c.ok(); ) {
60 if (!c->pcol->used) {
61 mtor << "removing : ";
62 c->print();
63 c.del();
64 } else
65 c++;
68 pscore_->clean_cols();
70 /* this sux. We should have Score_column create the appropriate PCol.
71 Unfortunately, PCols don't know about their position.
73 // todo
74 PCursor<Score_column*>
75 Score::create_cols(Mtime w)
77 Score_column* c1 = new Score_column(w);
78 Score_column* c2 = new Score_column(w);
80 c1->musical = false;
81 c2->musical = true;
83 PCursor<Score_column*> scc(cols_);
85 for (; scc.ok(); scc++) {
86 assert(scc->when != w);
87 if (scc->when > w)
88 break;
91 if (!scc.ok()) {
92 cols_.bottom().add(c1);
93 cols_.bottom().add(c2);
94 scc = cols_.bottom();
95 scc --;
96 } else {
97 scc.insert(c1);
98 scc.insert(c2);
99 scc -= 2;
101 return scc;
104 Score_column*
105 Score::find_col(Mtime w,bool mus)
107 PCursor<Score_column*> scc(cols_);
108 for (; scc.ok(); scc++) {
109 if (scc->when == w && scc->musical == mus)
110 return scc;
111 if (scc->when > w)
112 break;
114 scc = create_cols(w);
115 if (mus)
116 scc++;
117 return scc;
120 void
121 Score::distribute_commands(void)
123 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
124 sc->add_commands(commands_);
127 void
128 Score::add(Staff*s)
130 s->score_ = this;
131 staffs_.bottom().add(s);
135 void
136 Score::do_pcols()
138 PCursor<Score_column*> sc(cols_);
139 for (; sc.ok(); sc++) {
140 pscore_->add(sc->pcol);
143 Mtime
144 Score::last() const
146 Mtime l = 0;
147 for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
148 l = MAX(l, stc->last());
150 return l;
153 void
154 Score::OK() const
156 #ifndef NDEBUG
157 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
158 sc->OK();
159 assert(sc->score_ == this);
161 staffs_.OK();
162 cols_.OK();
163 for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
164 assert(cc->when <= (cc+1)->when);
166 commands_.OK();
167 #endif
171 void
172 Score::print() const
174 #ifndef NPRINT
175 mtor << "score {\n";
176 for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
177 sc->print();
179 for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
180 sc->print();
182 commands_.print();
183 mtor << "}\n";
184 #endif
187 Score::Score()
189 pscore_=0;
190 paper = 0;
192 void
193 Score::add(Command*c)
195 commands_.add(*c);