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