]> git.donarmstrong.com Git - lilypond.git/blob - lily/wordwrap.cc
5aefed16f3fc0e55e19a69b2fc4162a5f911777b
[lilypond.git] / lily / wordwrap.cc
1 /*
2   wordwrap.cc -- implement Word_wrap
3
4   source file of the LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "break.hh"
10 #include "p-score.hh"
11 #include "debug.hh"
12 #include "p-col.hh"
13 /** el stupido. This should be done more accurately:
14
15    It would be nice to have a Dynamic Programming type of algorithm
16    similar to TeX's
17    
18     */
19 Array<Col_hpositions>
20 Word_wrap::do_solve()const
21 {
22     problem_OK();
23     iter_top(pscore_.cols,curcol);
24     Array<Col_hpositions> breaking;
25     Line_of_cols breakpoints(find_breaks());
26     assert(breakpoints.size()>=2);
27
28     int break_idx_i=0;                  
29     while ( break_idx_i < breakpoints.size() -1) {
30         Col_hpositions minimum;
31         Col_hpositions current;
32
33         // do  another line
34         PCol *post = breakpoints[break_idx_i]->postbreak_p_;
35         current.add( post);
36         curcol++;               // skip the breakable.
37         break_idx_i++;
38
39         while (break_idx_i < breakpoints.size()) {
40
41             // add another measure.
42             while (breakpoints[break_idx_i] != curcol.ptr()){
43                 current.add(curcol);
44                 curcol++;
45             }
46             current.add(breakpoints[break_idx_i]->prebreak_p_ );
47
48             // try to solve
49             if (!feasible(current.cols)) {
50                 if (!minimum.cols.size()) {
51                     warning("Ugh, this measure is too long, breakpoint: "
52                           + String(break_idx_i) +
53                         " (generating stupido solution)");
54                     current = stupid_solution(current.cols);
55                     current.energy = - 1; // make sure we break out.
56                 } else
57                     current.energy = INFTY;     // make sure we go back
58             } else {
59                 current = solve_line(current.cols);
60                 current.print();
61             }
62
63             // update minimum, or backup.
64             if (current.energy < minimum.energy || current.energy < 0) {                
65                 minimum = current;         
66             } else {            // we're one col too far.
67                 break_idx_i--;
68                 while (curcol.ptr() != breakpoints[break_idx_i])
69                     curcol --;
70                 break;          // do the next line.
71             }
72
73
74             // add nobreak version of breakable column
75             current.cols.top()=breakpoints[break_idx_i];
76             curcol ++;
77             break_idx_i++;
78         }
79
80         *mlog << "[" <<break_idx_i<<"]"<<flush;
81         breaking.push(minimum);
82     }
83     
84     return breaking;
85 }
86
87 Word_wrap::Word_wrap(PScore&ps)
88     : Break_algorithm(ps)
89 {
90 }