]> git.donarmstrong.com Git - lilypond.git/blob - src/staff.cc
release: 0.0.21
[lilypond.git] / src / staff.cc
1 #include "staff.hh"
2 #include "score.hh"
3 #include "voice.hh"
4 #include "swalker.hh"
5 #include "stcol.hh"
6 #include "sccol.hh"
7 #include "staffcommands.hh"
8 #include "debug.hh"
9
10 void
11 Staff::add(PointerList<Voice*> &l)
12 {
13     for (iter_top(l,i); i.ok(); i++)
14         voices.bottom().add(i);
15 }
16
17 void
18 Staff::process_commands(Moment l)
19 {
20     if (staff_commands_)
21         staff_commands_->clean(l);
22 }
23
24 Paperdef*
25 Staff::paper() const
26 {
27     return score_->paper_;
28 }
29
30 void
31 Staff::clean_cols()
32 {
33     iter_top(cols,i);
34     for(; i.ok(); ){
35         if (!i->score_column->used())
36             i.del();
37         else
38             i++;
39     }
40 }
41
42 Staff_column *
43 Staff::get_col(Moment w, bool mus)
44 {
45     Score_column* sc = score_->find_col(w,mus);
46     assert(sc->when == w);
47     
48     iter_top(cols,i);
49     for (; i.ok(); i++) {
50         if (*i->score_column > *sc) // too far
51             break;
52         if (sc == i->score_column)
53             return i;
54     }
55
56     /* post: *sc > *->score_column || !i.ok() */
57     Staff_column* newst = create_col(sc);
58
59     if (!i.ok()) {
60         cols.bottom().add(newst);
61         return cols.bottom();
62     }
63     
64     if (mus) {
65         i.insert(newst);
66         return newst;
67     }
68
69 //  ;  assert((i-1).ok())
70     // todo!
71     
72     // making a fix at 2:30 am, with several beers drunk.
73     // but it works :-)
74     if ((i-1).ok()&& (i-1)->when() == newst->when()) {
75         i--;
76     }
77
78     i.insert(newst);
79     
80     return newst;
81 }
82
83
84
85 /*
86     put all stuff grouped vertically in the Staff_cols
87     */
88 void
89 Staff::setup_staffcols()
90 {    
91     for (iter_top(voices,i); i.ok(); i++) {
92         Moment now = i->start;
93         for (iter_top(i->elts,ve); ve.ok(); ve++) {
94
95             Staff_column *sc=get_col(now,true);
96             sc->add(ve);
97             now += ve->duration;            
98         }       
99     }
100
101     for (iter_top(*staff_commands_,cc); cc.ok(); cc++) {
102         Staff_column *sc=get_col(cc->tdescription_.when,false);
103         sc->s_commands = cc;
104         sc->tdescription_ = new Time_description(cc->tdescription_);
105     }
106
107     iter_top(*staff_commands_,cc);
108     for (iter_top(cols,i); i.ok(); i++) {
109         while  ((cc+1).ok() && (cc+1)->when() < i->when())
110             cc++;
111
112         if(!i->tdescription_) {
113             if (cc->tdescription_.when == i->when())
114                 i->tdescription_ = new Time_description(cc->tdescription_);
115             else
116                 i->tdescription_ = new Time_description(
117                     i->when() - cc->when() ,&cc->tdescription_);
118         }
119     }
120 }
121
122 void
123 Staff::process()
124 {
125     setup_staffcols();
126     OK();
127     walk();
128 }
129
130 void
131 Staff::OK() const
132 {
133 #ifndef NDEBUG
134     cols.OK();
135     voices.OK();
136     assert(score_);    
137 #endif    
138 }
139
140
141 Moment
142 Staff::last() const
143 {
144     Moment l = 0.0;
145     for (iter_top(voices,i); i.ok(); i++) {
146         l = l >? i->last();
147     }
148     return l;
149 }
150
151
152 void
153 Staff::print() const
154 {
155 #ifndef NPRINT
156     mtor << "Staff {\n";
157     for (iter_top(voices,i); i.ok(); i++) {
158         i->print();     
159     }
160     if (staff_commands_)
161         staff_commands_->print();
162     mtor <<"}\n";
163 #endif
164 }
165
166 Staff::Staff()
167 {    
168     staff_commands_ = 0;
169     score_ =0;
170     pscore_=0;    
171 }