]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff.cc
b23f163d29fd8f8eb4886e93178d31de2be56628
[lilypond.git] / lily / staff.cc
1 /*
2   staff.cc -- implement Staff
3
4   source file of the LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "proto.hh"
10 #include "plist.hh"
11 #include "staff.hh"
12 #include "score.hh"
13 #include "voice.hh"
14 #include "staff-walker.hh"
15 #include "staff-column.hh"
16 #include "score-column.hh"
17 #include "voice-element.hh"
18 #include "debug.hh"
19 #include "musical-request.hh"
20 #include "command-request.hh" // todo
21 #include "midi-stream.hh"
22 #include "pqueue.hh"
23
24
25 void
26 Staff::add(PointerList<Voice*> const &l)
27 {
28     for (iter_top(l,i); i.ok(); i++)
29         voice_list_.bottom().add(i);
30 }
31
32 Paper_def *
33 Staff::paper() const
34 {
35     return score_l_->paper_p_;
36 }
37
38 void
39 Staff::clean_cols()
40 {
41     iter_top(cols_,i);
42     for(; i.ok(); ){
43         if (!i->musical_column_l_->used_b())
44             i->musical_column_l_ = 0;
45         if (!i->command_column_l_->used_b())
46             i->command_column_l_ =0;
47         
48         if (!i->command_column_l_&& !i->musical_column_l_)
49             delete i.remove_p();
50         else
51             i++;
52     }
53 }
54
55 Staff_column *
56 Staff::get_col(Moment w, PCursor<Staff_column*> *last)
57 {    
58     iter_top(cols_,i);
59     if (last && last->ok() && (*last)->when() <= w)
60         i = *last;
61     
62     for (; i.ok(); i++) {
63         if (i->when() == w) {
64             if (last)
65                 *last = i;
66             return i;
67         } else if (i->when() > w)
68             break;
69     }
70
71
72     PCursor<Score_column*> scorecolumns(score_l_->find_col(w, false));
73     Staff_column* staffcolumn_p = new Staff_column;
74     staffcolumn_p->staff_l_ = this;
75     Score_column* comcol_l  = scorecolumns++;
76     staffcolumn_p->set_cols(comcol_l, scorecolumns);
77     
78     if (!i.ok()) {
79         cols_.bottom().add(    staffcolumn_p);
80         i = cols_.bottom();
81     } else {
82         i.insert(staffcolumn_p);
83         i--;
84     }
85     if (last)
86         *last = i;
87     return i;
88 }
89
90 /** put all stuff grouped vertically in the Staff_cols.  Do the
91   preprarations for walking the cols. not virtual */
92 void
93 Staff::setup_staffcols()
94 {
95     PQueue<Subtle_req *, Moment> subtle_req_pq;
96         PCursor<Staff_column*> last(cols_);
97     
98     for (iter_top(voice_list_,i); i.ok(); i++) {
99         Moment now = i->start;
100         iter_top(i->elts,j);
101         while( j.ok()) {
102             
103             Moment next = now;
104             if (subtle_req_pq.size())
105                 next = next <? subtle_req_pq.front_idx();
106
107             Staff_column *s_l= get_col(next, &last);
108
109             while (subtle_req_pq.size()
110                    && subtle_req_pq.front_idx() == s_l->when()) {
111                 s_l->setup_one_request(subtle_req_pq.get()); // ugh!
112             }
113             if(next == now) {
114                 s_l->add(j, subtle_req_pq); 
115                 now += j->duration_;
116                 j++;
117             }
118         }
119         
120     }
121    last = cols_.top(); 
122     while (subtle_req_pq.size()) {
123         Moment front =subtle_req_pq.front_idx();
124         Staff_column *s_l = get_col(front, &last);
125         while(subtle_req_pq.size() && subtle_req_pq.front_idx() == front)
126             s_l->setup_one_request(subtle_req_pq.get()); // ugh!
127     }
128         
129 }
130
131 void
132 Staff::OK() const
133 {
134 #ifndef NDEBUG
135     cols_.OK();
136     voice_list_.OK();
137     iter_top(cols_, i);
138     iter_top(cols_, j);
139     i++;
140     for (; i.ok(); j++,i++) {
141         assert(j->when () < i->when() );
142     }
143     assert(score_l_);
144 #endif    
145 }
146
147
148 Moment
149 Staff::last() const
150 {
151     Moment l = 0;
152     for (iter_top(voice_list_,i); i.ok(); i++) {
153         l = l >? i->last();
154     }
155     return l;
156 }
157
158 void
159 Staff::print() const
160 {
161 #ifndef NPRINT
162     mtor << "Staff {\n";
163     for (iter_top(voice_list_,i); i.ok(); i++) {
164         i->print();     
165     }
166     mtor <<"}\n";
167 #endif
168 }
169
170 Staff::Staff()
171 {    
172     score_l_ =0;
173     pscore_l_ =0;
174     pstaff_l_ =0;
175 }