lilypond-0.0.9
[lilypond.git] / scommands.cc
blob82fe9a169100ddaba1d6674818a32fbbc640c0fa
1 #include "scommands.hh"
2 #include "debug.hh"
4 /*
5 maybe it's time for a "narrowing" cursor?
6 */
7 PCursor<Command*>
8 Score_commands::first(Real w)
10 PCursor<Command*> pc(*this);
11 while (pc.ok() && pc->when < w)
12 pc++;
14 return pc;
17 PCursor<Command*>
18 Score_commands::last_insertion(Real w)
20 PCursor<Command*> pc(*this);
21 while (pc.ok() && pc->when <= w)
22 pc++;
23 return pc;
26 void
27 Score_commands::add_seq(svec<Command> com)
29 if (!com.sz())
30 return;
31 Real when = com[0].when;
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);
44 void
45 Score_commands::set_breakable(Real when)
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;
56 assert(!found_typeset);
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);
69 add_seq(seq);
71 bool
72 Score_commands::is_breakable(Real w)
74 PCursor<Command*> cc = first(w);
75 for (; cc.ok() && cc->when == w; cc++) {
76 if (cc->isbreak())
77 return true;
79 return false;
81 void
82 Score_commands::add_command_to_break(Command pre, Command mid,Command post)
84 Real w = pre.when;
86 Command k(w);
88 PCursor<Command*> c ( first(w));
89 while (!c->isbreak())
90 c++;
91 c.add(new Command(pre));
93 while (!c->isbreak())
94 c++;
95 c.add(new Command(mid));
97 while (!c->isbreak())
98 c++;
99 c.add(new Command(post));
102 void
103 Score_commands::add(Command c)
105 bool encapsulate =false;
107 Command pre(c.when);
108 Command mid(c.when);
109 Command post(c.when);
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;
119 if (c.args[0] == "METER" && is_breakable(c.when)) {
120 encapsulate = true;
121 mid = c;
122 pre = c;
123 post =c;
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);
137 first and last column should be breakable.
138 Remove any command past the last musical column.
140 void
141 Score_commands::clean(Real l)
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);
152 PCursor<Command*> bot(bottom());
154 while (bot.ok() && bot->when > l) {
156 mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
157 bot.del();
158 bot = bottom();
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);
168 OK();
171 void
172 Score_commands::OK() const
174 for (PCursor<Command*> cc(*this); cc.ok() && (cc+1).ok(); cc++) {
175 assert(cc->when <= (cc+1)->when);
179 void
180 Score_commands::print() const
182 for (PCursor<Command*> cc(*this); cc.ok() ; cc++) {
183 cc->print();