]> git.donarmstrong.com Git - lilypond.git/blob - score.cc
release: 0.0.4
[lilypond.git] / 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 void
10 Score::output(String s)
11 {
12     OK();
13     if (paper->outfile=="")
14         paper->outfile = s;
15     
16     *mlog << "output to " << paper->outfile << "...\n";
17     Tex_stream the_output(paper->outfile);    
18     pscore_->output(the_output);
19 }
20
21
22 void
23 Score::process()
24 {
25     if (!paper)
26         paper = new Paperdef;
27
28     commands_.clean(last());
29     
30     /// distribute commands to disciples
31     distribute_commands();
32     
33     pscore_ = new PScore;
34     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
35         sc->set_output(pscore_);
36         sc->process();
37     }
38
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.
48 }
49
50 // remove empty cols with no spacing attached.
51 /* should rethink ownership of cols
52     */
53 void
54 Score::clean_cols()
55 {    
56     for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
57         sc->clean_cols();
58     
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++;
66     }
67     
68     pscore_->clean_cols();
69 }
70 /* this sux.  We should have Score_column create the appropriate PCol.
71     Unfortunately, PCols don't know about their position.    
72     */
73 // todo
74 PCursor<Score_column*>
75 Score::create_cols(Mtime w)
76 {
77     Score_column* c1 = new Score_column(w);
78     Score_column* c2 = new Score_column(w);
79     
80     c1->musical = false;
81     c2->musical = true;
82     
83     PCursor<Score_column*> scc(cols_);
84
85     for (; scc.ok(); scc++) {
86         assert(scc->when != w);
87         if (scc->when > w)
88             break;
89     }
90
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;
100     }
101     return scc;
102 }
103
104 Score_column*
105 Score::find_col(Mtime w,bool mus)
106 {
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;
113     }
114     scc = create_cols(w);
115     if (mus)
116         scc++;
117     return scc;
118 }
119
120 void
121 Score::distribute_commands(void)
122 {
123     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
124         sc->add_commands(commands_);
125     }
126 }
127 void
128 Score::add(Staff*s)
129 {
130     s->score_ = this;
131     staffs_.bottom().add(s);    
132 }
133
134
135 void
136 Score::do_pcols()
137 {
138     PCursor<Score_column*> sc(cols_);
139     for (; sc.ok(); sc++) {
140         pscore_->add(sc->pcol);
141     }
142 }
143 Mtime
144 Score::last() const
145 {    
146     Mtime l = 0;
147     for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
148         l = MAX(l, stc->last());
149     }
150     return l;
151 }
152
153 void
154 Score::OK() const
155 {
156 #ifndef NDEBUG
157     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
158         sc->OK();
159         assert(sc->score_ == this);
160     }
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);
165     }
166     commands_.OK();
167 #endif    
168 }
169
170
171 void
172 Score::print() const
173 {
174 #ifndef NPRINT
175     mtor << "score {\n"; 
176     for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
177         sc->print();
178     }
179     for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
180         sc->print();
181     }
182     commands_.print();
183     mtor << "}\n";
184 #endif
185 }
186
187 Score::Score()
188 {
189     pscore_=0;
190     paper = 0;
191 }
192 void
193 Score::add(Command*c)
194 {
195     commands_.add(*c);
196 }