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<PCol *>
+Break_algorithm::find_breaks() const
+{
+ svec<PCol *> 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<Real>
-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<Idealspacing *> i(suz); i.ok(); i++) {
+ for (iter_top(pscore_.suz,i); i.ok(); i++) {
sp.add_ideal(i);
}
svec<Real> 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<PCol *> start(cols);
- PCursor<PCol *> end (((PScore*)this)->cols.bottom());
+ if (!pscore_.cols.size())
+ error("Score does not have any columns");
+#ifndef NDEBUG
+ iter_top(pscore_.cols,start);
+ PCursor<PCol *> end (pscore_.cols.bottom());
assert(start->breakable());
assert(end->breakable());
+#endif
}
-struct Col_configuration {
- svec< PCol*> line;
- svec<Real> config;
- Real energy;
-
- Col_configuration() {
- energy = INFTY;
- }
- void add( PCol*c) { line.add(c);}
- void setsol(svec<Real> 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<Real> sol)
{
- OK();
- problem_OK();
- PCursor<PCol *> curcol(cols);
-
- svec<PCol *> 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());
+}
--- /dev/null
+#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<Col_configuration>
+Word_wrap::solve()
+{
+ problem_OK();
+ iter_top(pscore_.cols,curcol);
+ svec<Col_configuration> breaking;
+ svec<PCol *> 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)
+{
+}