flower-1.0.27
[lilypond.git] / src / score.cc
blob1adcf7dd057837c04ff8cc92b397c3bec00ee25a
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 "paperdef.hh"
8 #include "main.hh"
9 #include "source.hh"
10 #include "sourcefile.hh"
12 void
13 Score::process()
15 *mlog << "\nProcessing music ..." << flush;
17 assert (paper_p_);
18 if (last() == Moment(0)) {
19 warning("Need to have music in a score.", defined_ch_c_l_);
22 // distribute commands to disciples
23 pscore_p_ = new PScore(paper_p_);
24 for (iter_top(staffs_,i); i.ok(); i++) {
25 i->set_output(pscore_p_);
26 i->truncate_cols(last());
27 i->process();
30 // do this after processing, staffs first have to generate PCols.
31 find_col(last(), false)->set_breakable();
32 do_cols();
33 print();
34 calc_idealspacing();
36 // debugging
37 OK();
38 *mlog << endl;
39 pscore_p_->process();
42 /**
43 Remove empty cols, preprocess other columns.
45 void
46 Score::clean_cols()
48 for (iter_top(staffs_,i); i.ok(); i++)
49 i->clean_cols();
51 for (iter_top(cols_,c); c.ok(); ) {
52 if (!c->pcol_l_->used()) {
53 delete c.get();
54 } else {
55 c->preprocess();
56 c++;
61 /**
62 this sux. We should have Score_column create the appropriate PCol.
63 Unfortunately, PCols don't know about their position.
65 PCursor<Score_column*>
66 Score::create_cols(Moment w)
68 Score_column* c1 = new Score_column(w);
69 Score_column* c2 = new Score_column(w);
71 c1->musical_ = false;
72 c2->musical_ = true;
74 iter_top(cols_,i);
76 for (; i.ok(); i++) {
77 assert(i->when() != w);
78 if (i->when() > w)
79 break;
82 if (!i.ok()) {
83 cols_.bottom().add(c1);
84 cols_.bottom().add(c2);
85 i = cols_.bottom();
86 i --;
87 } else {
88 i.insert(c1);
89 i.insert(c2);
90 i -= 2;
92 return i;
95 PCursor<Score_column*>
96 Score::find_col(Moment w, bool mus)
97 { iter_top( cols_,i);
100 for (; i.ok(); i++) {
101 if (i->when() == w && i->musical_ == mus)
102 return i;
103 if (i->when() > w)
104 break;
106 i = create_cols(w);
107 if (mus)
108 i++;
109 return i;
112 void
113 Score::do_cols()
115 iter_top(cols_,i);
116 for (; i.ok(); i++) {
117 pscore_p_->add(i->pcol_l_);
119 clean_cols(); // can't move clean_cols() farther up.
122 Moment
123 Score::last() const
125 Moment l = 0;
126 for (iter_top(staffs_,i); i.ok(); i++) {
127 l = l>? i->last();
129 return l;
132 void
133 Score::OK() const
135 #ifndef NDEBUG
136 for (iter_top(staffs_,i); i.ok(); i++) {
137 i->OK();
138 assert(i->score_l_ == this);
140 staffs_.OK();
141 cols_.OK();
142 for (iter_top(cols_,cc); cc.ok() && (cc+1).ok(); cc++) {
143 assert(cc->when() <= (cc+1)->when());
145 #endif
149 void
150 Score::print() const
152 #ifndef NPRINT
153 mtor << "score {\n";
154 for (iter_top(staffs_,i); i.ok(); i++) {
155 i->print();
157 for (iter_top(cols_,i); i.ok(); i++) {
158 i->print();
160 if (pscore_p_)
161 pscore_p_->print();
163 mtor << "}\n";
164 #endif
167 Score::Score(Paperdef*paper_p)
169 pscore_p_=0;
170 paper_p_ = paper_p;
171 errorlevel_i_ = 0;
172 defined_ch_c_l_ = 0;
175 Score::~Score()
177 delete pscore_p_;
178 delete paper_p_;
181 void
182 Score::output(String s)
184 OK();
185 if (paper_p_->outfile=="")
186 paper_p_->outfile = s;
188 if ( errorlevel_i_ ) {
189 *mlog << "lilypond: warning: no output to: " << paper_p_->outfile
190 << " (errorlevel=" << errorlevel_i_ << ")" << endl;
191 return;
194 *mlog << "output to " << paper_p_->outfile << "...\n";
196 Tex_stream the_output(paper_p_->outfile);
198 the_output << "% outputting Score, defined at: " <<
199 source_global_l->
200 sourcefile_l (defined_ch_c_l_)->file_line_no_str(defined_ch_c_l_) << "\n";
201 pscore_p_->output(the_output);
206 void
207 Score::add(Staff*s)
209 s->score_l_ = this;
210 staffs_.bottom().add(s);
213 void
214 Score::add_marks(Array<String> s_arr, Array<Moment> m_arr)
216 for (int i=0; i < s_arr.size(); i++) {
217 String mark_str (s_arr[i]);
218 if (markers_assoc_.elt_query(mark_str) &&
219 m_arr[i] != markers_assoc_[mark_str])
221 error("Conflicting marker: `" + s_arr[i]+ "\'");
222 else
223 markers_assoc_[s_arr[i]] = m_arr[i];