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