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