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