]> git.donarmstrong.com Git - lilypond.git/blob - src/staffcommands.cc
release: 0.0.18
[lilypond.git] / src / staffcommands.cc
1 #include "staffcommands.hh"
2 #include "debug.hh"
3 #include "parseconstruct.hh"
4
5 void
6 Staff_commands_at::print() const
7 {
8 #ifndef NPRINT
9     PCursor<Command*> i (*this);
10     mtor << "Commands at: " << when<<"\n";
11     
12     for (; i.ok(); i++)
13         i->print();
14 #endif
15 }
16 void
17 Staff_commands_at::OK()const
18 {
19     PCursor<Command*> i (*this);
20     for (; i.ok() && (i+1).ok(); i++)
21         if (!i->isbreak() && !(i+1)->isbreak())
22             assert(i->priority >= (i+1)->priority);
23 }
24
25 Staff_commands_at::Staff_commands_at(Real r)
26 {
27     when = r;
28 }
29
30 bool
31 Staff_commands_at::is_breakable()
32 {
33     PCursor<Command*> i(*this);
34     for (; i.ok(); i++) {
35         if (i->isbreak())
36             return true;
37     }
38     return false;
39 }
40
41 void
42 Staff_commands_at::set_breakable()
43 {
44     assert(!is_breakable());
45     
46     Command k;
47     k.code = BREAK_PRE;
48     bottom().add(new Command(k));
49     k.code = BREAK_MIDDLE;
50     bottom().add(new Command(k));
51     k.code = BREAK_POST;
52     bottom().add(new Command(k));
53     k.code = BREAK_END;
54     bottom().add(new Command(k));        
55 }
56
57 void
58 Staff_commands_at::insert_between(Command victim, PCursor<Command*> firstc,
59                                   PCursor<Command*> last)
60 {
61     PCursor<Command*> c(firstc+1);
62     assert(firstc < last&&last.ok());
63     
64     while (c < last) { 
65         if (c->priority <= victim.priority) {
66             c.insert(new Command(victim));
67             return;
68         }
69         c++;
70     }
71     last.insert(new Command(victim));    
72 }
73
74 void
75 Staff_commands_at::add_command_to_break(Command pre, Command mid,Command post)
76 {
77     assert(is_breakable());
78     PCursor<Command*> c ( *this), f(c), l(c);
79
80     while (!c->isbreak())
81         c++;
82     f = c++;
83     while (!c->isbreak())
84         c++;
85     l = c++;
86     
87     insert_between(pre, f, l);
88     f = l;
89     while (!c->isbreak())
90         c++;
91     l = c++;    
92     insert_between(mid, f, l);
93     f = l;
94     while (!c->isbreak())
95         c++;
96     l = c++;
97     assert(l.ok() && l->code == BREAK_END);
98     
99     insert_between(post, f, l);
100 }
101   
102 void
103 Staff_commands_at::add(Command c)
104 {
105     bool encapsulate =false;
106     Command pre;
107     Command mid;
108     Command post;
109
110     if (c.code == INTERPRET)
111     {                           // UGH
112         if (c.args[0] == "BAR") {
113             Command typeset;    // kut met peren
114             typeset.code = TYPESET;
115             typeset.args = c.args;
116             typeset.priority = 100;
117             add(typeset);
118         } else if (c.args[0] == "KEY") {
119             Command typeset;
120             typeset.code = TYPESET;
121             typeset.args.add("KEY");
122             typeset.priority = 70;
123             add(typeset);
124         } else if (c.args[0] == "CLEF") {
125             Command typeset;
126             typeset.code = TYPESET;
127             typeset.args=c.args;
128             typeset.priority = 90;
129             add(typeset);
130         } else if (c.args[0] == "METER") {
131             Command typeset;
132             typeset.code = TYPESET;
133             typeset.args=c.args;
134             typeset.priority = 40;
135             add(typeset);
136             return;
137         }
138     }
139
140     // kut en peer
141     if (c.code == TYPESET) {
142         encapsulate  = is_breakable();
143         if (c.args[0] == "BAR") {
144             set_breakable();
145             encapsulate = true;
146             mid = c;
147             pre = c;
148             { /* every line a currentkey. */
149                 Command kc;
150                 kc.code =TYPESET;
151                 kc.args.add( "CURRENTKEY");
152                 kc.priority = 60;
153                 add(kc);
154             }
155             { /* every line a currentclef. */
156                 Command kc;
157                 kc.code =TYPESET;
158                 kc.args.add( "CURRENTCLEF");
159                 kc.priority = 80;
160                 add(kc);
161             }
162         }else if (c.args[0] == "METER" && is_breakable()) {
163             mid = c;
164             pre = c;
165             post =c;
166         }else
167         if( c.args[0] == "KEY" && is_breakable()) {
168
169             mid = c;
170             pre = c;
171             post = c;
172         }else if (c.args[0] == "CURRENTKEY" && is_breakable() ){
173             post = c;
174
175         }else
176         if (c.args[0] == "CURRENTCLEF" && is_breakable() ){
177             post = c;
178
179         }else
180         if (c.args[0] == "CLEF" && is_breakable()) {
181
182             post = c;
183             pre = c;
184             mid = c;                   
185         }
186     }
187     
188     if (encapsulate)
189         add_command_to_break(pre, mid, post);
190     else {
191         bottom().add(new Command(c));
192     }
193 }
194
195
196 /****************************************************************/
197
198 void
199 Staff_commands::OK() const
200 {
201 #ifndef NDEBUG
202     for (PCursor<Staff_commands_at*> i(*this); i.ok() && (i+1).ok(); i++) {
203         assert(i->when <= (i+1)->when);
204         i->OK();
205
206     }
207 #endif
208 }
209
210 void
211 Staff_commands::print() const
212 {
213 #ifndef NPRINT
214     for (PCursor<Staff_commands_at*> i(*this); i.ok() ; i++) {
215         i->print();
216     }
217 #endif
218 }
219
220 Staff_commands_at*
221 Staff_commands::find(Real w)
222 {
223     PCursor<Staff_commands_at*> i(bottom());
224     for (; i.ok() ; i--) {
225         if (i->when == w)
226             return i;
227         if (i->when < w)
228             break;
229     }
230     Staff_commands_at*p =new Staff_commands_at(w);
231     if (!i.ok()) 
232         i.insert(p);
233     else {
234         i.add(p);
235         i++;
236     }
237     return i;
238 }
239
240 void
241 Staff_commands::add(Command c, Real when)
242 {
243     Staff_commands_at* p = find(when);
244     p->add(c);
245 }
246
247 void
248 Staff_commands::clean(Real l)
249 {
250     PCursor<Staff_commands_at*> i(bottom());
251     for (; i->when > l ; i=bottom()) {
252         remove(i);
253     }
254     Staff_commands_at*p = find(l);
255     
256     if (!p->is_breakable()) {
257         p->set_breakable();
258 /*      Command b;
259         b.code = INTERPRET;
260         b.args.add("BAR");*/
261     }
262 }