From: fred Date: Thu, 7 Nov 1996 22:27:06 +0000 (+0000) Subject: lilypond-0.0.9 X-Git-Tag: release/1.5.59~6873 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=6a7a09f504eed2ed83bec4ea4b417ce885ce8b33;p=lilypond.git lilypond-0.0.9 --- diff --git a/src/scommands.cc b/src/scommands.cc new file mode 100644 index 0000000000..7b8c8ed9c5 --- /dev/null +++ b/src/scommands.cc @@ -0,0 +1,266 @@ +#include "scommands.hh" +#include "debug.hh" +#include "parseconstruct.hh" + +/* + maybe it's time for a "narrowing" cursor? + */ +PCursor +Score_commands::first(Real w) +{ + PCursor pc(*this); + while (pc.ok() && pc->when < w) + pc++; + + return pc; +} + +PCursor +Score_commands::last_insertion(Real w) +{ + PCursor pc(*this); + while (pc.ok() && pc->when <= w) + pc++; + return pc; +} + +void +Score_commands::add_seq(svec com) +{ + if (!com.sz()) + return; + Real when = com[0].when; + + PCursor pc(last_insertion(when)); + for (int i = 0; i < com.sz(); i++) { + Command *c = new Command(com[i]); + assert(com[i].when == when); + if (!pc.ok()) + pc.add(c); + else + pc.insert(c); + } +} + +void +Score_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.code = BREAK_PRE; + seq.add(k); + k.code = BREAK_MIDDLE; + seq.add(k); + k.code = BREAK_POST; + seq.add(k); + k.code = BREAK_END; + seq.add(k); + + add_seq(seq); +} + +bool +Score_commands::is_breakable(Real w) +{ + PCursor cc = first(w); + for (; cc.ok() && cc->when == w; cc++) { + if (cc->isbreak()) + return true; + } + return false; +} + +void +Score_commands::insert_between(Command victim, PCursor firstc, + PCursor last) +{ + assert(last->when==firstc->when); + PCursor c(firstc+1); + while (c != last) { // hmm what if !last.ok()? + if (victim.priority > c->priority) { + c.insert(new Command(victim)); + return; + } + c++; + } + last.insert(new Command(victim)); +} + +void +Score_commands::add_command_to_break(Command pre, Command mid, Command post) +{ + Real w = pre.when; + 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++; + insert_between(post, f, l); + assert(l.ok() && l->when ==w && l->code == BREAK_END); +} + +void +Score_commands::parser_add(Command *c) +{ + bottom().add(c); +} + +void +Score_commands::process_add(Command c) +{ + bool encapsulate =false; + Real w = c.when; + Command pre(w); + Command mid(w); + Command post(w); + + + if (c.code == TYPESET) { + if (c.args[0] == "BAR") { + set_breakable(w); + encapsulate = true; + mid = c; + pre = c; + } + if (c.args[0] == "METER" && is_breakable(w)) { + encapsulate = true; + mid = c; + pre = c; + post =c; + } + } + + if (encapsulate) + add_command_to_break(pre, mid, post); + else { + svec seq; + seq.add(c); + add_seq(seq); + } +} + +/* + first and last column should be breakable. + Remove any command past the last musical column. + */ +void +Score_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 +Score_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 +Score_commands::print() const +{ + for (PCursor cc(*this); cc.ok() ; cc++) { + cc->print(); + } +} + +/* + TODO + */ +Score_commands* +Score_commands::parse(Real l) const +{ + Score_commands*nc = new Score_commands; + int beats_per_meas=4; + Real measlen = 1.0; // 4/4 by default + + Real inbar=0.0; + int barcount=0; + Real wholes=0.0; + Real stoppos=0.0; + + { + Command c(0.0); + c.code = TYPESET; + c.args.add("BAR"); + c.args.add("empty"); + nc->process_add(c); + } + for (PCursor cc(*this); cc.ok() && cc->when <= l; cc++) { + assert (cc->code==INTERPRET); + if (cc->args[0] == "METER") { + beats_per_meas = cc->args[1].value(); + int one_beat = cc->args[2].value(); + measlen = beats_per_meas/Real(one_beat); + nc->process_add(*get_meter_command(wholes, beats_per_meas, one_beat)); + } + if (cc->args[0] == "SKIP") { + stoppos = wholes + cc->args[1].value() * measlen + + cc->args[2].fvalue(); + wholes += (measlen-inbar); // skip at least 1 measure + barcount++; + while (wholes <= stoppos) { + nc->process_add(*get_bar_command(wholes)); // liek + wholes += measlen; + barcount ++; + } + wholes = stoppos; + //something + } + } + + return nc; +}