]> git.donarmstrong.com Git - lilypond.git/blob - src/simplewalker.cc
f275cd272e9b275f39964f10b02f95f25b18dc1e
[lilypond.git] / src / simplewalker.cc
1 #include "request.hh"
2 #include "voice.hh"
3 #include "clef.hh"
4 #include "beam.hh"
5 #include "pscore.hh"
6 #include "simplestaff.hh"
7 #include "simplewalker.hh"
8 #include "sccol.hh"
9 #include "stem.hh"
10 #include "notehead.hh"
11 #include "rest.hh"
12 #include "debug.hh"
13 #include "keyitem.hh"
14 #include "clefitem.hh"
15 #include "keyitem.hh"
16 #include "slur.hh"
17 #include "localkeyitem.hh"
18
19 void
20 Simple_walker::do_INTERPRET_command(Command*com)
21 {
22     if (com->args[0] == "BAR") {
23         local_key_.reset(key_);
24     } else if (com->args[0] == "KEY") {
25         svec<Scalar>s(com->args);
26         s.del(0);
27         if (com->when) {
28             assert(!oldkey_undo);
29             oldkey_undo = new svec<int>( key_.oldkey_undo(s));
30         }
31         
32         typesetkey = key_.read(s);
33         local_key_.reset(key_); 
34     } else if (com->args[0] == "CLEF") {
35         svec<Scalar>s(com->args);
36         s.del(0);
37         clef_.read(s);
38     } else {
39         WARN << " ignoring INTERPRET command: " << com->args[0]<< '\n';
40     }
41 }
42
43 void
44 Simple_walker::do_TYPESET_command(Command*com)
45 {
46     /* ignore these commands if non-default versions have been
47       processed.  */
48     if (com->args[0] == "CURRENTKEY") 
49         if (processed_key) 
50             return;
51         else
52             com->args[0] = "KEY"; 
53     
54     if (com->args[0] == "CURRENTCLEF") {
55         if (processed_clef) 
56             return;
57     }
58     
59
60     Item* i = staff()->get_TYPESET_item(com);
61     if (!i)
62         return;
63
64     if (com->args[0] == "KEY") {
65         if (oldkey_undo) {
66             ((Keyitem*) i)->read(*oldkey_undo);
67             delete oldkey_undo;
68             oldkey_undo = 0;
69         }
70         processed_key = true;
71         ((Keyitem*) i)->read(typesetkey); // ugh        
72     }
73
74     if (com->args[0] == "CLEF"||com->args[0] == "CURRENTCLEF") {
75         processed_clef =true;
76         Clef_item*c=(Clef_item*)i;
77         c->read(clef_);
78         c->change = (break_status != BREAK_POST - BREAK_PRE);
79     }
80     col()->typeset_item_directional(i, 1, break_status);
81 }
82
83 void
84 Simple_walker::do_local_key(Note_req*n)
85 {
86     if ( local_key_.oct(n->octave).acc(n->name) != n->accidental) {
87         if (!local_key_item_) {
88             local_key_item_ = staff()->get_local_key_item();
89             local_key_item_->c0_position = clef_.c0_pos;
90         }
91         
92         local_key_item_->add(n->octave, n->name, n->accidental);        
93         local_key_.oct(n->octave).set(n->name, n->accidental);
94     }
95 }
96
97 void
98 Simple_walker::do_note(Rhythmic_req*rq)
99 {
100     Simple_column*c = col();
101     Simple_staff *s = staff();
102     
103     if (rq->note()) {
104         Note_req * req = rq->note() ;
105         const Voice *v = req->elt->voice_;
106         
107         Notehead*n = s->get_notehead(req, clef_.c0_pos);
108         stem_->add(n);
109         noteheads.add(n);
110         int sidx =find_slur(v);
111         if (sidx >= 0) {
112             pending_slurs[sidx]->add(n);
113         }
114
115         if (wantkey)
116             do_local_key(req);
117     }
118         
119     if (rq->rest()) {
120         c->typeset_item( s->get_rest(rq->rest()) );
121     }      
122 }
123
124 void
125 Simple_walker::process_requests()
126 {
127     Simple_column*c = col();
128     Simple_staff *s = staff();
129     if (c->beam_&& c->beam_->spantype == Span_req::START) {
130         if (beam_)
131             error("Too many beams (t = "
132                           +String(c->when())+")");
133         beam_ = new Beam;
134     }
135     for (int i=0; i < c->slurs.sz(); i++) {
136         Slur_req*sl = c->slurs[i];
137         
138         if (sl->spantype == Span_req::START) {
139             if  (find_slur(sl->elt->voice_ )>=0)
140                 error("Too many slurs in voice");
141             pending_slur_reqs.add(sl);
142             pending_slurs.add(new Slur);
143         }
144     }
145     
146     if (c->stem_) {
147         stem_ = s->get_stem(c->stem_->stem(), c->stem_requester_len);
148     }
149     
150     for (int i = 0; i <  c->notes.sz(); i ++)  {
151         do_note(c->notes[i]);
152     }
153     
154     if (beam_) {
155         if (!stem_)
156             error("beamed note should have a stem (t = " 
157                   +String(c->when())+")");
158         beam_->add(stem_);
159     }
160     if (stem_) {
161         c->typeset_item(stem_);
162         /* needed, otherwise placement of
163            local_key fucks up */
164 //      stem_->set_default_extents();
165         // can somebody explain myself?
166     }
167     if (c->beam_&& c->beam_->spantype == Span_req::STOP) {
168         pscore_->typeset_spanner(beam_, s->theline);
169         beam_ = 0;
170     }
171     for (int i = 0; i < noteheads.sz(); i++) {
172         c->typeset_item(noteheads[i]);
173     }
174     noteheads.set_size(0);
175  
176     if (local_key_item_) {
177         c->typeset_item_directional(local_key_item_, -1);
178         local_key_item_ = 0;    
179     }
180     if (stem_) {
181         stem_ = 0;
182     }
183     for (int i=0; i < c->slurs.sz(); i++) {
184         Slur_req*sl = c->slurs[i];
185
186         if (sl->spantype == Span_req::STOP) {
187             int idx = find_slur(sl->elt->voice_);
188             if (idx < 0)
189                 error("can't find slur to end");
190             
191             pscore_->typeset_spanner(pending_slurs[idx],
192                                      s->theline);
193             pending_slurs.del(idx);
194             pending_slur_reqs.del(idx);
195         }       
196     }
197     
198 }
199
200 Simple_walker::Simple_walker(Simple_staff*s)
201     : Staff_walker(s, s->theline->pscore_)
202 {
203     stem_ = 0;
204     beam_ =0;
205     oldkey_undo = 0;
206
207     Local_key_item * i = s->get_local_key_item();
208     wantkey  =i;
209     delete i;
210     local_key_item_ = 0;
211     reset();
212 }
213
214
215
216 Simple_staff*
217 Simple_walker::staff()
218 {
219     return (Simple_staff*) staff_;
220 }
221
222 Simple_column*
223 Simple_walker::col()
224 {
225     return (Simple_column*) *(*this);
226 }
227
228 void
229 Simple_walker::reset()
230 {
231     processed_clef =false;    
232     processed_key = false;
233 }
234
235 int
236 Simple_walker::find_slur(const Voice *v)
237 {
238     for (int i=0; i < pending_slur_reqs.sz(); i++) {
239         if (pending_slur_reqs[i]->elt->voice_ == v)
240             return i;
241     }
242     return -1;
243 }
244
245