]> git.donarmstrong.com Git - lilypond.git/blob - src/score.cc
release: 0.0.18
[lilypond.git] / src / score.cc
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"
8
9
10 void
11 Score::process()
12 {
13     *mlog << "\nProcessing ... ";
14     
15     assert (paper_);
16     
17     /// distribute commands to disciples
18     pscore_ = new PScore(paper_);
19     for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
20         i->process_commands(last());
21         i->set_output(pscore_);
22         i->process();
23     }
24
25     // do this after processing, staffs first have to generate PCols.
26     do_pcols();
27
28     clean_cols();    // can't move this farther up.
29
30     calc_idealspacing();
31
32     // debugging
33     print ();
34     OK();
35
36     pscore_->preprocess();
37     *mlog << "Calculating ... ";
38     pscore_->calc_breaking();
39     *mlog << "Postprocessing ... ";
40     pscore_->postprocess();
41
42     // TODO: calculate vertical structs?
43     // TODO: calculate mixed structs.?
44     *mlog << "\n";
45 }
46
47 // remove empty cols.
48 void
49 Score::clean_cols()
50 {    
51     for (PCursor<Staff * > i(staffs_); i.ok(); i++)
52         i->clean_cols();
53     
54     for (PCursor<Score_column*> c(cols_); c.ok(); ) {
55         if (!c->pcol_->used()) {
56             c.del();
57         } else {
58             c->preprocess();
59             c++;
60         }
61     }
62     
63     pscore_->clean_cols();
64 }
65 /*
66   this sux.  We should have Score_column create the appropriate PCol.
67   Unfortunately, PCols don't know about their position.    
68   */
69 // todo
70 PCursor<Score_column*>
71 Score::create_cols(Real w)
72 {
73     Score_column* c1 = new Score_column(w);
74     Score_column* c2 = new Score_column(w);
75     
76     c1->musical = false;
77     c2->musical = true;
78     
79     PCursor<Score_column*> i(cols_);
80
81     for (; i.ok(); i++) {
82         assert(i->when != w);
83         if (i->when > w)
84             break;
85     }
86
87     if (!i.ok()) {
88         cols_.bottom().add(c1);
89         cols_.bottom().add(c2);
90         i = cols_.bottom();
91         i --;
92     } else {
93         i.insert(c1);
94         i.insert(c2);
95         i -= 2;
96     }
97     return i;
98 }
99
100 PCursor<Score_column*>
101 Score::find_col(Real w,bool mus)
102 {
103     PCursor<Score_column*> i(cols_);
104     for (; i.ok(); i++) {
105         if (i->when == w && i->musical == mus)
106             return i;
107         if (i->when > w)
108             break;
109     }
110     i = create_cols(w);
111     if (mus)
112         i++;
113     return i;
114 }
115
116 void
117 Score::do_pcols()
118 {
119     PCursor<Score_column*> i(cols_);
120     for (; i.ok(); i++) {
121         pscore_->add(i->pcol_);
122     }
123 }
124 Real
125 Score::last() const
126 {    
127     Real l = 0;
128     for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
129         l = MAX(l, i->last());
130     }
131     return l;
132 }
133
134 void
135 Score::OK() const
136 {
137 #ifndef NDEBUG
138     for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
139         i->OK();
140         assert(i->score_ == this);
141     }
142     staffs_.OK();
143     cols_.OK();
144     for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
145         assert(cc->when <= (cc+1)->when);
146     }
147 #endif    
148 }
149
150
151 void
152 Score::print() const
153 {
154 #ifndef NPRINT
155     mtor << "score {\n"; 
156     for (PCursor<Staff*> i(staffs_); i.ok(); i++) {
157         i->print();
158     }
159     for (PCursor<Score_column*> i(cols_); i.ok(); i++) {
160         i->print();
161     }
162     if (pscore_)
163         pscore_->print();
164     
165     mtor << "}\n";
166 #endif
167 }
168
169 Score::Score(Paperdef*p)
170 {
171     pscore_=0;
172     paper_ = p;
173 }
174
175 Score::~Score()
176 {
177     delete pscore_;
178 }
179
180 void
181 Score::output(String s)
182 {
183     OK();
184     if (paper_->outfile=="")
185         paper_->outfile = s;
186     
187     *mlog << "output to " << paper_->outfile << "...\n";
188     Tex_stream the_output(paper_->outfile);    
189     pscore_->output(the_output);
190 }
191
192
193
194 void
195 Score::add(Staff*s)
196 {
197     s->score_ = this;
198     staffs_.bottom().add(s);
199 }
200