]> git.donarmstrong.com Git - lilypond.git/blob - src/staffcommands.cc
release: 0.0.26
[lilypond.git] / src / staffcommands.cc
1 #include "staffcommands.hh"
2 #include "debug.hh"
3 #include "parseconstruct.hh"
4 #include "getcommand.hh"
5
6 Moment
7 Staff_commands_at::when()
8 {
9     return tdescription_.when;
10 }
11
12 void
13 Staff_commands_at::print() const
14 {
15 #ifndef NPRINT
16     iter_top(*this,i);
17     mtor << "Commands at: " ;
18     tdescription_.print();
19     
20     for (; i.ok(); i++)
21         i->print();
22 #endif
23 }
24 void
25 Staff_commands_at::OK()const
26 {
27 #ifndef NDEBUG
28     iter_top(*this,i);
29     for (; i.ok() && (i+1).ok(); i++)
30         if (!i->isbreak() && !(i+1)->isbreak())
31             assert(i->priority >= (i+1)->priority);
32 #endif
33 }
34
35 Staff_commands_at::Staff_commands_at(Time_description m)
36     :tdescription_(m)
37 {
38     
39 }
40
41 bool
42 Staff_commands_at::is_breakable()
43 {
44     iter_top(*this,i);
45     for (; i.ok(); i++) {
46         if (i->isbreak())
47             return true;
48     }
49     return false;
50 }
51
52 void
53 Staff_commands_at::set_breakable()
54 {
55     if (is_breakable()) return;
56     
57     Command k;
58     k.code = BREAK_PRE;
59     bottom().add(new Command(k));
60     k.code = BREAK_MIDDLE;
61     bottom().add(new Command(k));
62     k.code = BREAK_POST;
63     bottom().add(new Command(k));
64     k.code = BREAK_END;
65     bottom().add(new Command(k));        
66 }
67
68 void
69 Staff_commands_at::insert_between(Command victim, PCursor<Command*> firstc,
70                                   PCursor<Command*> last)
71 {
72     PCursor<Command*> c(firstc+1);
73     assert(firstc < last&&last.ok());
74     
75     while (c < last) { 
76         if (c->priority <= victim.priority) {
77             c.insert(new Command(victim));
78             return;
79         }
80         c++;
81     }
82     last.insert(new Command(victim));    
83 }
84
85 void
86 Staff_commands_at::add_command_to_break(Command pre, Command mid,Command post)
87 {
88     assert(is_breakable());
89     iter_top(*this,c), f(c), l(c);
90
91     while (!c->isbreak())
92         c++;
93     f = c++;
94     while (!c->isbreak())
95         c++;
96     l = c++;
97     
98     insert_between(pre, f, l);
99     f = l;
100     while (!c->isbreak())
101         c++;
102     l = c++;    
103     insert_between(mid, f, l);
104     f = l;
105     while (!c->isbreak())
106         c++;
107     l = c++;
108     assert(l.ok() && l->code == BREAK_END);
109     
110     insert_between(post, f, l);
111 }
112
113
114 /*
115   should move this stuff into inputlanguage.
116   */
117 void
118 Staff_commands_at::add(Command c)
119 {
120     bool encapsulate =false;
121     Command pre;
122     Command mid;
123     Command post;
124
125     if (c.code == INTERPRET)
126     {                           // UGH
127         Command typeset;        // kut met peren
128         typeset.code = TYPESET;
129         typeset.args = c.args;
130         if (c.args[0] == "NEWMEASURE") {
131             add(get_defaultbar_command());
132         } else if (c.args[0] == "BAR") {
133             add(typeset);
134             c.code= NOP;        // no INTERPRET (BAR) commands
135         } else if (c.args[0] == "KEY") {
136             typeset.priority = 70;
137             add(typeset);
138         } else if (c.args[0] == "CLEF") {
139             typeset.priority = 90;
140             add(typeset);
141         } else if (c.args[0] == "METER") {
142             typeset.priority = 40;
143             add(typeset);
144             return;
145         }
146     }
147
148     // kut en peer
149     if (c.code == TYPESET) {
150         encapsulate  = is_breakable();
151         if (c.args[0] == "BAR") {
152             set_breakable();
153             encapsulate = true;
154             split_bar_command(pre,mid,post, c.args[1]);
155
156             { /* every line a currentkey. */
157                 Command kc;
158                 kc.code =TYPESET;
159                 kc.args.push( "CURRENTKEY");
160                 kc.priority = 60;
161                 add(kc);
162             }
163             { /* every line a currentclef. */
164                 Command kc;
165                 kc.code =TYPESET;
166                 kc.args.push( "CURRENTCLEF");
167                 kc.priority = 80;
168                 add(kc);
169             }
170         }
171         if (is_breakable()) {
172             if (c.args[0] == "METER") {
173                 mid = c;
174                 pre = c;
175                 post =c;
176             }else if( c.args[0] == "KEY") {
177
178                 mid = c;
179                 pre = c;
180                 post = c;
181             }else if (c.args[0] == "CURRENTKEY" ){
182                 post = c;
183
184             }else
185                 if (c.args[0] == "CURRENTCLEF" ){
186                     post = c;
187
188                 }else if (c.args[0] == "CLEF") {
189
190                     post = c;
191                     pre = c;
192                     mid = c;                   
193                 }
194         }
195     }
196     
197     if (encapsulate)
198         add_command_to_break(pre, mid, post);
199     else {
200         if (c.priority>0)
201             top().insert(new Command(c));
202         else
203             bottom().add(new Command(c));
204     }
205 }
206