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