lilypond-0.0.32
[lilypond.git] / src / score.cc
blob3084f90c90e96f64cf1c0cd597a29ce8c798b832
1 /*
2 score.cc -- implement Score
4 source file of the LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
9 #include "tstream.hh"
10 #include "score.hh"
11 #include "sccol.hh"
12 #include "pscore.hh"
13 #include "staff.hh"
14 #include "debug.hh"
15 #include "paperdef.hh"
16 #include "main.hh"
17 #include "source.hh"
18 #include "sourcefile.hh"
19 #include "scorewalker.hh"
21 void
22 Score::setup_music()
24 *mlog << "\nSetting up music ..." << flush;
25 if (last() == Moment(0)) {
26 warning("Need to have music in a score.", defined_ch_c_l_);
29 pscore_p_ = new PScore(paper_p_);
30 find_col(0, false)->set_breakable(); // ugh
31 find_col(last(), false)->set_breakable();
35 for (iter_top(staffs_,i); i.ok(); i++) {
36 i->set_output(pscore_p_);
37 i->setup_staffcols();
38 i->OK();
42 void
43 Score::process_music()
45 *mlog << "Processing music ..." << flush;
46 for (Score_walker w(this); w.ok(); w++) {
47 w.process();
51 void
52 Score::process()
54 setup_music();
55 process_music();
57 // do this after processing, staffs first have to generate PCols.
58 do_cols();
59 print();
60 calc_idealspacing();
62 // debugging
63 OK();
64 *mlog << endl;
65 pscore_p_->process();
68 /**
69 Remove empty cols, preprocess other columns.
71 void
72 Score::clean_cols()
74 for (iter_top(staffs_,i); i.ok(); i++)
75 i->clean_cols();
77 for (iter_top(cols_,c); c.ok(); ) {
78 if (!c->pcol_l_->used()) {
79 delete c.get();
80 } else {
81 c->preprocess();
82 c++;
87 /**
88 Create columns at time #w#.
89 this sux. We should have Score_column create the appropriate PCol.
90 Unfortunately, PCols don't know about their position.
92 @return cursor pointing to the nonmusical (first) column
94 PCursor<Score_column*>
95 Score::create_cols(Moment w)
97 Score_column* c1 = new Score_column(w);
98 Score_column* c2 = new Score_column(w);
100 c1->musical_b_ = false;
101 c2->musical_b_ = true;
103 iter_top(cols_,i);
105 for (; i.ok(); i++) {
106 assert(i->when() != w);
107 if (i->when() > w)
108 break;
111 if (!i.ok()) {
112 cols_.bottom().add(c1);
113 cols_.bottom().add(c2);
114 i = cols_.bottom();
115 i --;
116 } else {
117 i.insert(c1);
118 i.insert(c2);
119 i -= 2;
121 return i;
124 PCursor<Score_column*>
125 Score::find_col(Moment w, bool mus)
127 iter_top( cols_,i);
129 for (; i.ok(); i++) {
130 if (i->when() == w && i->musical_b_ == mus)
131 return i;
132 if (i->when() > w)
133 break;
135 i = create_cols(w);
136 if (mus)
137 i++;
138 return i;
141 void
142 Score::do_cols()
144 iter_top(cols_,i);
145 for (; i.ok(); i++) {
146 pscore_p_->add(i->pcol_l_);
148 clean_cols(); // can't move clean_cols() farther up.
151 Moment
152 Score::last() const
154 Moment l = 0;
155 for (iter_top(staffs_,i); i.ok(); i++) {
156 l = l>? i->last();
158 return l;
161 void
162 Score::OK() const
164 #ifndef NDEBUG
165 for (iter_top(staffs_,i); i.ok(); i++) {
166 i->OK();
167 assert(i->score_l_ == this);
169 staffs_.OK();
170 cols_.OK();
171 for (iter_top(cols_,cc); cc.ok() && (cc+1).ok(); cc++) {
172 assert(cc->when() <= (cc+1)->when());
174 #endif
178 void
179 Score::print() const
181 #ifndef NPRINT
182 mtor << "score {\n";
183 for (iter_top(staffs_,i); i.ok(); i++) {
184 i->print();
186 for (iter_top(cols_,i); i.ok(); i++) {
187 i->print();
189 if (pscore_p_)
190 pscore_p_->print();
192 mtor << "}\n";
193 #endif
196 Score::Score(Paperdef*paper_p)
198 pscore_p_=0;
199 paper_p_ = paper_p;
200 errorlevel_i_ = 0;
201 defined_ch_c_l_ = 0;
204 Score::~Score()
206 delete pscore_p_;
207 delete paper_p_;
210 void
211 Score::output(String s)
213 OK();
214 if (paper_p_->outfile=="")
215 paper_p_->outfile = s;
217 if ( errorlevel_i_ ) {
218 *mlog << "lilypond: warning: no output to: " << paper_p_->outfile
219 << " (errorlevel=" << errorlevel_i_ << ")" << endl;
220 return;
223 *mlog << "output to " << paper_p_->outfile << "...\n";
225 Tex_stream the_output(paper_p_->outfile);
227 the_output << "% outputting Score, defined at: " <<
228 source_global_l->
229 sourcefile_l (defined_ch_c_l_)->file_line_no_str(defined_ch_c_l_) << "\n";
230 pscore_p_->output(the_output);
235 void
236 Score::add(Staff*s)
238 s->score_l_ = this;
239 staffs_.bottom().add(s);