2 word-wrap.cc -- implement Word_wrap
4 source file of the LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "word-wrap.hh"
10 #include "paper-def.hh"
11 #include "paper-score.hh"
13 #include "paper-column.hh"
14 #include "spring-spacer.hh"
17 /** El stupido. Add a measure until we're past the optimum.
20 A Dynamic Programming type of algorithm
21 similar to TeX's is in Gourlay_breaking
24 UGH. Should think about pre/post break columns.
26 Array<Column_x_positions>
27 Word_wrap::do_solve () const
31 Line_of_cols &allcols (pscore_l_->col_l_arr_);
34 Array<Column_x_positions> breaking;
35 Line_of_cols breakpoints (find_breaks ());
36 assert (breakpoints.size ()>=2);
40 while (break_idx < breakpoints.size () -1)
42 Column_x_positions minimum;
43 Column_x_positions current;
48 Item *post = breakpoints[break_idx]->find_prebroken_piece (RIGHT);
49 Paper_column *postcol =dynamic_cast<Paper_column*>(post);
51 int start_break_idx = break_idx;
52 current.add_paper_column (postcol);
53 curcol_idx++; // skip the breakable.
56 while (break_idx < breakpoints.size ())
58 // add another measure.
59 while (breakpoints[break_idx] != allcols[curcol_idx])
61 current.add_paper_column (allcols[curcol_idx]);
65 Item * pre = breakpoints[break_idx]->find_prebroken_piece (LEFT);
66 Paper_column* precol = dynamic_cast<Paper_column*>(pre);
67 current.add_paper_column (precol);
69 current.spacer_l_ = generate_spacing_problem (current.cols,
70 pscore_l_->paper_l_->line_dimensions_int (line_no));
73 if (!feasible (current.cols))
75 if (!minimum.cols.size ())
77 warning (_ ("ugh, this measure is too long")
78 + ", " + _f ("breakpoint: %d", break_idx)
79 + "(" + _ ("generating stupido solution") + ")");
80 current.stupid_solution ();
81 current.energy_f_ = - 1; // make sure we break out.
84 current.energy_f_ = infinity_f; // make sure we go back
88 current.solve_line ();
92 delete current.spacer_l_;
95 if (!current.satisfies_constraints_b_ && start_break_idx == break_idx - 1)
97 warning ( _ ("I don't fit; put me on Montignac"));
105 if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0)
110 { // we're one col too far.
112 while (allcols[curcol_idx] != breakpoints[break_idx])
114 break; // do the next line.
118 // add nobreak version of breakable column
119 current.cols.top ()=breakpoints[break_idx];
124 *mlog << "[" << break_idx << "]" << flush;
125 breaking.push (minimum);
130 Word_wrap::Word_wrap ()
132 get_line_spacer = Spring_spacer::constructor;