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 "line-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
23 UGH. Should think about pre/post break columns.
25 Array
<Column_x_positions
>
26 Word_wrap::do_solve () const
30 Line_of_cols
&allcols (pscore_l_
->col_l_arr_
);
33 Array
<Column_x_positions
> breaking
;
34 Line_of_cols
breakpoints (find_breaks ());
35 assert (breakpoints
.size ()>=2);
38 while (break_idx
< breakpoints
.size () -1)
40 Column_x_positions minimum
;
41 Column_x_positions current
;
46 Item
*post
= breakpoints
[break_idx
]->find_broken_piece (RIGHT
);
47 Paper_column
*postcol
=dynamic_cast<Paper_column
*>(post
);
49 int start_break_idx
= break_idx
;
50 current
.add_paper_column (postcol
);
51 curcol_idx
++; // skip the breakable.
54 while (break_idx
< breakpoints
.size ())
56 // add another measure.
57 while (breakpoints
[break_idx
] != allcols
[curcol_idx
])
59 current
.add_paper_column (allcols
[curcol_idx
]);
63 Item
* pre
= breakpoints
[break_idx
]->find_broken_piece (LEFT
);
64 Paper_column
* precol
= dynamic_cast<Paper_column
*>(pre
);
65 current
.add_paper_column (precol
);
67 current
.spacer_l_
= generate_spacing_problem (current
.cols_
,
68 pscore_l_
->paper_l_
->line_dimensions_int (breaking
.size ()));
71 if (!feasible (current
.cols_
))
73 if (!minimum
.cols_
.size ())
75 warning (_f ("Ugh, this measure is too long, breakpoint: %d",
77 warning (_ ("Generating stupido solution"));
78 current
.stupid_solution ();
79 current
.energy_f_
= - 1; // make sure we break out.
82 current
.energy_f_
= infinity_f
; // make sure we go back
86 current
.solve_line ();
90 delete current
.spacer_l_
;
93 if (!current
.satisfies_constraints_b_
&& start_break_idx
== break_idx
- 1)
95 warning ( _ ("I don't fit; put me on Montignac"));
103 if (current
.energy_f_
< minimum
.energy_f_
|| current
.energy_f_
< 0)
108 { // we're one col too far.
110 while (allcols
[curcol_idx
] != breakpoints
[break_idx
])
112 break; // do the next line.
116 // add nobreak version of breakable column
117 current
.cols_
.top ()=breakpoints
[break_idx
];
122 *mlog
<< "[" << break_idx
<< "]" << flush
;
123 breaking
.push (minimum
);