From: fred Date: Sat, 4 Jan 1997 19:12:03 +0000 (+0000) Subject: lilypond-0.0.21 X-Git-Tag: release/1.5.59~6442 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1d4fbe9e63381cfb899be4d911208886c541977f;p=lilypond.git lilypond-0.0.21 --- diff --git a/src/break.cc b/src/break.cc index ff86e848af..e27abd9b84 100644 --- a/src/break.cc +++ b/src/break.cc @@ -2,134 +2,109 @@ do calculations for breaking problem */ +#include "break.hh" #include "paper.hh" #include "linespace.hh" #include "debug.hh" #include "scoreline.hh" #include "pscore.hh" + +/* + return all breakable columns + */ +svec +Break_algorithm::find_breaks() const +{ + svec retval; + for (iter_top(pscore_.cols,c); c.ok(); c++) + if (c->breakable()) + + + retval.add(c); + + return retval; +} + // construct an appropriate Spacing_problem and solve it. svec -PScore::solve_line(svec< PCol *> curline) const +Break_algorithm::solve_line(Line_of_cols curline) const { Spacing_problem sp; sp.add_column(curline[0], true, 0.0); for (int i=1; i< curline.sz()-1; i++) sp.add_column(curline[i]); - sp.add_column(curline.last(), true, paper_->linewidth); + sp.add_column(curline.last(), true, linelength); // misschien moeven uit Spacing_problem? - for (PCursor i(suz); i.ok(); i++) { + for (iter_top(pscore_.suz,i); i.ok(); i++) { sp.add_ideal(i); } svec the_sol=sp.solve(); return the_sol; } +Break_algorithm::Break_algorithm(PScore&s) + :pscore_(s) +{ + linelength = s.paper_->linewidth; +} + bool -PScore::feasible(svec< PCol *> curline) const +Break_algorithm::feasible(Line_of_cols curline) const { Real l =0; for (int i=0; i < curline.sz(); i++) l +=curline[i]->width().length(); - return l < paper_->linewidth; + return l < linelength; } void -PScore::problem_OK() const +Break_algorithm::problem_OK() const { - if (!cols.size()) - error("PScore::problem_OK(): Score does not have any columns"); - PCursor start(cols); - PCursor end (((PScore*)this)->cols.bottom()); + if (!pscore_.cols.size()) + error("Score does not have any columns"); +#ifndef NDEBUG + iter_top(pscore_.cols,start); + PCursor end (pscore_.cols.bottom()); assert(start->breakable()); assert(end->breakable()); +#endif } -struct Col_configuration { - svec< PCol*> line; - svec config; - Real energy; - - Col_configuration() { - energy = INFTY; - } - void add( PCol*c) { line.add(c);} - void setsol(svec sol) { - config = sol; - energy = config.last(); - config.pop(); - } - void print() const { -#ifndef NPRINT - mtor << "energy : " << energy << '\n'; - mtor << "line of " << config.sz() << " cols\n"; -#endif - } -}; +/****************/ -/// wordwrap type algorithm -/* el stupido. This should be done more accurately: +Col_configuration::Col_configuration() +{ + energy = INFTY; +} - It would be nice to have a Dynamic Programming type of algorithm - similar to TeX's - - */ +void +Col_configuration::add( PCol*c) +{ + cols.add(c); +} void -PScore::calc_breaking() +Col_configuration::setsol(svec sol) { - OK(); - problem_OK(); - PCursor curcol(cols); - - svec breakpoints(find_breaks()); - assert(breakpoints.sz()>=2); - for (int i=0 ; i < breakpoints.sz() -1; ) { - Col_configuration minimum; - Col_configuration current; - - // do another line - PCol *post = breakpoints[i]->postbreak; - current.add( post); - curcol++; // skip the breakable. - i++; - - while (i < breakpoints.sz()) { - - // add another measure. - while (breakpoints[i] != curcol.ptr()){ - - current.add(curcol); - curcol++; - } - current.add(breakpoints[i]->prebreak ); - if (!feasible(current.line)) { - if (!minimum.line.sz()) - error("sorry, this measure is too long"); - break; - } - current.setsol(solve_line(current.line)); - current.print(); - - if (current.energy < minimum.energy) { - minimum = current; - } else { // we're one col too far. - i--; - while (curcol.ptr() != breakpoints[i]) - curcol --; - - break; - } - - current.line.last()=breakpoints[i]; - curcol ++; - i++; - } - mtor << "Adding line, next breakpoint " << i << '\n'; - add_line(minimum.line, minimum.config); - } + config = sol; + energy = config.last(); + config.pop(); } +void +Col_configuration::print() const +{ +#ifndef NPRINT + mtor << "energy : " << energy << '\n'; + mtor << "line of " << config.sz() << " cols\n"; +#endif +} +void +Col_configuration::OK()const +{ + assert(config.sz() == cols.sz()); +} diff --git a/src/wordwrap.cc b/src/wordwrap.cc new file mode 100644 index 0000000000..ec6ac16395 --- /dev/null +++ b/src/wordwrap.cc @@ -0,0 +1,71 @@ +#include "break.hh" +#include "pscore.hh" +#include "debug.hh" + +/* el stupido. This should be done more accurately: + + It would be nice to have a Dynamic Programming type of algorithm + similar to TeX's + + */ + +svec +Word_wrap::solve() +{ + problem_OK(); + iter_top(pscore_.cols,curcol); + svec breaking; + svec breakpoints(find_breaks()); + assert(breakpoints.sz()>=2); + for (int i=0 ; i < breakpoints.sz() -1; ) { + Col_configuration minimum; + Col_configuration current; + + // do another line + PCol *post = breakpoints[i]->postbreak; + current.add( post); + curcol++; // skip the breakable. + i++; + + while (i < breakpoints.sz()) { + + // add another measure. + while (breakpoints[i] != curcol.ptr()){ + + current.add(curcol); + curcol++; + } + current.add(breakpoints[i]->prebreak ); + if (!feasible(current.cols)) { + if (!minimum.cols.sz()) + error("sorry, this measure is too long"); + break; + } + current.setsol(solve_line(current.cols)); + current.print(); + + if (current.energy < minimum.energy) { + minimum = current; + } else { // we're one col too far. + i--; + while (curcol.ptr() != breakpoints[i]) + curcol --; + + break; + } + + current.cols.last()=breakpoints[i]; + curcol ++; + i++; + } + mtor << "Adding cols~, next breakpoint " << i << '\n'; + breaking.add(minimum); + } + + return breaking; +} + +Word_wrap::Word_wrap(PScore&ps) + : Break_algorithm(ps) +{ +}