From: fred Date: Fri, 29 Nov 1996 14:25:05 +0000 (+0000) Subject: lilypond-0.0.13 X-Git-Tag: release/1.5.59~6726 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c015c743bf8770f4b20e6bae8512b756dbb78da3;p=lilypond.git lilypond-0.0.13 --- diff --git a/src/staffcommands.cc b/src/staffcommands.cc new file mode 100644 index 0000000000..96647b1de6 --- /dev/null +++ b/src/staffcommands.cc @@ -0,0 +1,318 @@ +#include "staffcommands.hh" +#include "debug.hh" +#include "parseconstruct.hh" + +/* + ARG! + */ + +/* + maybe it's time for a "narrowing" cursor? + */ +PCursor +Staff_commands::first(Real w) +{ + PCursor pc(*this); + while (pc.ok() && pc->when < w) + pc++; + if (!pc.ok() || pc->when != w) { + Command *c = new Command(w); + c->priority = 10000; + if (!pc.ok()) + pc.add(c); + else + pc.insert(c); + } + + return pc; +} +/* + RETURN: pc->when == w && pc.ok + */ + +PCursor +Staff_commands::last_insertion(Real w) +{ + PCursor pc(first(w)), next(pc); + while (next.ok() && next->when == w) { + pc=next; + next++; + } + if (pc->priority != -10000) { + Command*c = new Command(w); + c->priority = -10000; + pc.add(c); + pc++; + } + + return pc; +} + +/* + */ +void +Staff_commands::add_seq(svec com, bool checkbreak) +{ + if (!com.sz()) + return; + + Real when = com[0].when; + + PCursor begin(first(when)); + PCursor end(last_insertion(when)); + if (checkbreak && is_breakable(when)) { + if (com[0].priority < 0) + while (begin->code != BREAK_END) + begin++; + else + while (end->code != BREAK_PRE) + end--; + } + for (int i = 0; i < com.sz(); i++) { + insert_between(com[i], begin, end); + } +} + +void +Staff_commands::set_breakable(Real when) +{ + bool found_typeset(false); + PCursor cc = first(when); + for (; cc.ok() && cc->when == when; cc++) { + if (cc->isbreak()) + return; + if (cc->code == TYPESET) + found_typeset=true; + } + + assert(!found_typeset); + + svec seq; + Command k(when); + k.priority = 5; + k.code = BREAK_PRE; + seq.add(k); + k.priority = 4; + k.code = BREAK_MIDDLE; + seq.add(k); + k.priority = 3; + k.code = BREAK_POST; + seq.add(k); + k.priority = 2; + k.code = BREAK_END; + seq.add(k); + + add_seq(seq,false); +} + +bool +Staff_commands::is_breakable(Real w) +{ + PCursor cc = first(w); + for (; cc.ok() && cc->when == w; cc++) { + if (cc->isbreak()) + return true; + } + return false; +} + +void +Staff_commands::insert_between(Command victim, PCursor firstc, + PCursor last) +{ + PCursor c(firstc+1); + assert(last->when==firstc->when&&firstc < last&&last.ok()); + + while (c < last) { + if (c->priority <= victim.priority) { + c.insert(new Command(victim)); + return; + } + c++; + } + last.insert(new Command(victim)); +} + +void +Staff_commands::add_command_to_break(Command pre, Command mid, Command post) +{ + Real w = pre.when; + assert(w >= 0); + PCursor c ( first(w)), f(c), l(c); + + while (!c->isbreak()) + c++; + f = c++; + while (!c->isbreak()) + c++; + l = c++; + + insert_between(pre, f, l); + f = l; + while (!c->isbreak()) + c++; + l = c++; + insert_between(mid, f, l); + f = l; + while (!c->isbreak()) + c++; + l = c++; + assert(l.ok() && l->when ==w && l->code == BREAK_END); + + insert_between(post, f, l); +} + +void +Staff_commands::process_add(Command c) +{ + bool encapsulate =false; + Real w = c.when; + assert(w >= 0); + + Command pre(w); + Command mid(w); + Command post(w); + + if (c.code == INTERPRET) + { // UGH + if (c.args[0] == "BAR") { + Command typeset(w); // kut met peren + typeset.code = TYPESET; + typeset.args = c.args; + typeset.priority = 100; + process_add(typeset); + } else if (c.args[0] == "KEY") { + Command typeset(w); + typeset.code = TYPESET; + typeset.args.add("KEY"); + typeset.priority = 70; + process_add(typeset); + } else if (c.args[0] == "CLEF") { + Command typeset(w); + typeset.code = TYPESET; + typeset.args=c.args; + typeset.priority = 90; + process_add(typeset); + } else if (c.args[0] == "METER") { + Command typeset(w); + typeset.code = TYPESET; + typeset.args=c.args; + typeset.priority = 40; + process_add(typeset); + return; + } + } + + // kut en peer + if (c.code == TYPESET) { + if (c.args[0] == "BAR") { + set_breakable(w); + encapsulate = true; + mid = c; + pre = c; + { /* every line a currentkey. */ + Command kc(w); + kc.code =TYPESET; + kc.args.add( "CURRENTKEY"); + kc.priority = 60; + process_add(kc); + } + { /* every line a currentclef. */ + Command kc(w); + kc.code =TYPESET; + kc.args.add( "CURRENTCLEF"); + kc.priority = 80; + process_add(kc); + } + }else + if (c.args[0] == "METER" && is_breakable(w)) { + encapsulate = true; + mid = c; + pre = c; + post =c; + }else + if( c.args[0] == "KEY" && is_breakable(c.when)) { + encapsulate = true; + mid = c; + pre = c; + post = c; + }else + if (c.args[0] == "CURRENTKEY" && is_breakable(w)) { + post = c; + encapsulate = true; + }else + if (c.args[0] == "CURRENTCLEF" && is_breakable(w)) { + post = c; + encapsulate = true; + }else + if (c.args[0] == "CLEF" && is_breakable(w)) { + encapsulate = true; + post = c; + pre = c; + mid = c; + } + } + + if (encapsulate) + add_command_to_break(pre, mid, post); + else { + svec seq; + seq.add(c); + add_seq(seq,true); + } +} + +/* + first and last column should be breakable. + Remove any command past the last musical column. + */ +void +Staff_commands::clean(Real l) +{ + assert(l>0); + if (!is_breakable(0.0)) { + Command c(0.0); + c.code = TYPESET; + c.args.add("BAR"); + c.args.add("empty"); + process_add(c); + } + + PCursor bot(bottom()); + + while (bot.ok() && bot->when > l) { + mtor <<"removing "; + bot->print(); + bot.del(); + bot = bottom(); + } + + if (!is_breakable(l)) { + Command c(l); + c.code = TYPESET; + c.args.add("BAR"); + c.args.add("||"); + process_add(c); + } + OK(); +} + +void +Staff_commands::OK() const +{ + for (PCursor cc(*this); cc.ok() && (cc+1).ok(); cc++) { + assert(cc->when <= (cc+1)->when); + if (cc->when == (cc+1)->when && !cc->isbreak() && !(cc+1)->isbreak()) + assert(cc->priority >= (cc+1)->priority); + } +} + +void +Staff_commands::print() const +{ +#ifndef NPRINT + for (PCursor cc(*this); cc.ok() ; cc++) { + cc->print(); + } +#endif +}