]> git.donarmstrong.com Git - lilypond.git/blob - scommands.cc
release: 0.0.4
[lilypond.git] / scommands.cc
1 #include "scommands.hh"
2 #include "debug.hh"
3
4 /*
5   maybe it's time for a "narrowing" cursor?
6   */
7 PCursor<Command*>
8 Score_commands::first(Real w)
9 {
10     PCursor<Command*> pc(*this);    
11     while (pc.ok() && pc->when < w)
12         pc++;
13     
14      return pc;
15 }
16
17 PCursor<Command*>
18 Score_commands::last_insertion(Real w)
19 {    
20     PCursor<Command*> pc(*this);    
21     while (pc.ok() && pc->when <= w)
22         pc++;
23     return pc;
24 }
25
26 void
27 Score_commands::add_seq(svec<Command> com)
28 {
29     if (!com.sz())
30         return;
31     Real when = com[0].when;
32
33     PCursor<Command*> pc(last_insertion(when));
34     for (int i = 0; i < com.sz(); i++) {
35         Command *c = new Command(com[i]);
36         assert(com[i].when == when);
37         if (!pc.ok())
38             pc.add(c);
39         else
40             pc.insert(c);
41     }
42 }
43
44 void
45 Score_commands::set_breakable(Real when)
46 {
47     bool found_typeset(false);
48     PCursor<Command*> cc = first(when);
49     for (; cc.ok() && cc->when == when; cc++) {
50         if (cc->isbreak())
51             return;
52         if (cc->code == TYPESET)
53             found_typeset=true;
54     }
55
56     assert(!found_typeset);
57     
58     svec<Command> seq;
59     Command k(when);
60     k.code = BREAK_PRE;
61     seq.add(k);
62     k.code = BREAK_MIDDLE;
63     seq.add(k);
64     k.code = BREAK_POST;
65     seq.add(k);
66     k.code = BREAK_END;
67     seq.add(k);
68
69     add_seq(seq);
70 }
71 bool
72 Score_commands::is_breakable(Real w)
73 {
74     PCursor<Command*> cc = first(w);
75     for (; cc.ok() && cc->when == w; cc++) {
76         if (cc->isbreak())
77             return true;
78     }
79     return false;
80 }
81 void
82 Score_commands::add_command_to_break(Command pre, Command mid,Command post)
83 {
84     Real w = pre.when;
85     
86     Command k(w);
87     
88     PCursor<Command*> c ( first(w));
89     while (!c->isbreak())
90         c++;
91     c.add(new Command(pre));
92
93     while (!c->isbreak())
94         c++;
95     c.add(new Command(mid));
96
97     while (!c->isbreak())
98         c++;
99     c.add(new Command(post));
100 }
101
102 void
103 Score_commands::add(Command c)
104 {
105     bool encapsulate =false;
106
107     Command pre(c.when);
108     Command mid(c.when);
109     Command post(c.when);
110
111
112     if (c.code == TYPESET) {
113         if (c.args[0] == "BAR") {
114             set_breakable(c.when);
115             encapsulate  = true;
116             mid = c;
117             pre = c;
118         }
119         if (c.args[0] == "METER" && is_breakable(c.when)) {
120             encapsulate = true;
121             mid = c;
122             pre = c;
123             post =c;
124         }
125     }
126     
127     if (encapsulate)
128         add_command_to_break(pre, mid, post);    
129     else {
130         svec<Command> seq;
131         seq.add(c);    
132         add_seq(seq);
133     }
134 }
135
136 /*
137     first and last column should be breakable.
138     Remove any command past the last musical column.
139     */
140 void
141 Score_commands::clean(Real l)
142 {
143     assert(l>0);
144     if (!is_breakable(0.0)) {
145         Command c(0.0);
146         c.code = TYPESET;
147         c.args.add("BAR");
148         c.args.add("empty");
149         add(c);
150     }
151     
152     PCursor<Command*> bot(bottom());
153
154     while (bot.ok() && bot->when > l) {
155
156         mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
157         bot.del();
158         bot = bottom();
159     }
160
161     if (!is_breakable(l)) {
162         Command c(l);
163         c.code = TYPESET;
164         c.args.add("BAR");
165         c.args.add("||");
166         add(c);
167     }
168     OK();
169 }
170
171 void
172 Score_commands::OK() const
173 {
174     for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
175         assert(cc->when <= (cc+1)->when);
176     }
177 }
178
179 void
180 Score_commands::print() const
181 {
182     for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
183         cc->print();
184     }
185 }