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