]> git.donarmstrong.com Git - lilypond.git/blob - src/staff.cc
release: 0.0.26
[lilypond.git] / src / staff.cc
1 #include "staff.hh"
2 #include "score.hh"
3 #include "voice.hh"
4 #include "staffwalker.hh"
5 #include "stcol.hh"
6 #include "sccol.hh"
7 #include "staffcommands.hh"
8 #include "debug.hh"
9 #include "inputcommands.hh"
10 #include "inputcommand.hh"
11 #include "request.hh"
12
13 void
14 Staff::do_commands(PointerList<Input_command*> score_wide,
15                    PointerList<Input_command*> staff_wide)
16 {
17     Input_commands commands;
18
19     // bring in commands from voices.
20     for (iter_top(voices, i); i.ok(); i++) {
21         Moment here = i->start;
22         for (iter_top(i->elts, j); j.ok(); j++) {
23             for (iter_top(j->reqs, k); k.ok(); k++) {
24                 if (k->command()){
25                     commands.find_moment(here);
26                     commands.add(*k->command()->com_p_,
27                                  score_l_->markers_assoc_);
28                 }
29             }
30             here += j->duration;
31         }
32     }
33     for (iter_top(score_wide,i); i.ok(); i++) 
34         commands.add(**i, score_l_->markers_assoc_);
35     for (iter_top(staff_wide,i); i.ok(); i++) 
36         commands.add(**i, score_l_->markers_assoc_);
37
38     commands.parse(this);
39 }
40
41 void
42 Staff::add(PointerList<Voice*> &l)
43 {
44     for (iter_top(l,i); i.ok(); i++)
45         voices.bottom().add(i);
46 }
47
48 void
49 Staff::truncate_cols(Moment l)
50 {
51     iter_bot(cols, i);
52     for (; i->when() > l; i=cols.bottom()) {
53         Staff_column * col_p = i.get();
54         assert(col_p->when() > l);
55         delete col_p;
56     }
57 }
58
59 Paperdef*
60 Staff::paper() const
61 {
62     return score_l_->paper_p_;
63 }
64
65 void
66 Staff::clean_cols()
67 {
68     iter_top(cols,i);
69     for(; i.ok(); ){
70         if (!i->score_column_l_->used())
71             delete i.get();
72         else
73             i++;
74     }
75 }
76
77 Staff_column *
78 Staff::get_col(Moment w, bool mus)
79 {
80     Score_column* sccol_l = score_l_->find_col(w,mus);
81     
82     iter_top(cols,i);
83     for (; i.ok(); i++) {
84
85         if (*i->score_column_l_ > *sccol_l) // too far
86             break;
87         if (sccol_l == i->score_column_l_)
88             return i;
89     }
90
91     /* post: *sc > *->score_column_l_ || !i.ok() */
92     Staff_column* newst = create_col(sccol_l);
93
94     if (!i.ok()) {
95         cols.bottom().add(newst);
96         return cols.bottom();
97     }
98     
99     if (mus) {
100         i.insert(newst);
101         return newst;
102     }
103
104     
105     // making a fix at 2:30 am, with several beers drunk.
106     // but it works :-)
107     if ((i-1).ok()&& (i-1)->when() == newst->when()) {
108         i--;
109     }
110
111     i.insert(newst);
112     
113     return newst;
114 }
115
116 void
117 Staff::get_marks(Array<String>&s_arr, Array<Moment>&m_arr)
118 {
119      for (iter_top(voices,i); i.ok(); i++) {
120         Moment now = i->start;
121         for (iter_top(i->elts,j); j.ok(); j++) {
122             for (iter_top(j->reqs, k); k.ok(); k++) {
123                 if (k->mark()) { // ugh. 4 levels
124                     s_arr.push(k->mark()->mark_str_);
125                     m_arr.push(now);
126                 }
127             }
128             now += j->duration;     
129         }
130      }
131 }
132 /*
133     put all stuff grouped vertically in the Staff_cols
134     */
135 void
136 Staff::setup_staffcols()
137 {    
138     for (iter_top(voices,i); i.ok(); i++) {
139         Moment now = i->start;
140         for (iter_top(i->elts,j); j.ok(); j++) {
141
142             Staff_column *s_l=get_col(now,true);
143             s_l->add(j);
144             now += j->duration;     
145         }       
146     }
147     set_time_descriptions();
148 }
149
150 void
151 Staff::set_time_descriptions()
152 {
153     Time_description t(0,0);
154     for (iter_top(cols,i); i.ok(); i++) {
155         if (i->staff_commands_p_)
156             t = i->staff_commands_p_->tdescription_;
157         else if (i->tdescription_)
158             t = *i->tdescription_;
159         if(!i->tdescription_) {
160             i->tdescription_ = new Time_description(i->when() - t.when ,&t);
161         }
162     }
163
164 }
165 void
166 Staff::process()
167 {
168     setup_staffcols();
169     OK();
170     walk();
171 }
172
173 void
174 Staff::OK() const
175 {
176 #ifndef NDEBUG
177     cols.OK();
178     voices.OK();
179     iter_top(cols, i);
180     iter_top(cols, j);
181     i++;
182     for (; i.ok(); j++,i++) {
183         if ( j->when() == i->when())
184             assert(!j->mus() && i->mus());
185         else
186             assert(j->when () < i->when() );
187     }
188     assert(score_l_);
189 #endif    
190 }
191
192
193 Moment
194 Staff::last() const
195 {
196     Moment l = 0.0;
197     for (iter_top(voices,i); i.ok(); i++) {
198         l = l >? i->last();
199     }
200     return l;
201 }
202
203
204 void
205 Staff::print() const
206 {
207 #ifndef NPRINT
208     mtor << "Staff {\n";
209     for (iter_top(voices,i); i.ok(); i++) {
210         i->print();     
211     }
212     mtor <<"}\n";
213 #endif
214 }
215
216 Staff::Staff()
217 {    
218     score_l_ =0;
219     pscore_l_ =0;    
220 }