]> git.donarmstrong.com Git - lilypond.git/blob - lily/word-wrap.cc
release: 0.1.11
[lilypond.git] / lily / word-wrap.cc
1 /*
2   word-wrap.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. 
17    
18   
19    A Dynamic Programming type of algorithm
20    similar to TeX's is in Gourlay_breaking
21
22    */
23 Array<Col_hpositions>
24 Word_wrap::do_solve() const
25 {
26   problem_OK();
27   
28   PCursor<Paper_column*> curcol (pscore_l_->col_p_list_.top());
29   Array<Col_hpositions> breaking;
30   Line_of_cols breakpoints (find_breaks());
31   assert (breakpoints.size()>=2);
32
33   int break_idx_i=0;                    
34   while (break_idx_i < breakpoints.size() -1) 
35     {
36       Col_hpositions minimum;
37       Col_hpositions current;
38
39       // do  another line
40       Paper_column *post = breakpoints[break_idx_i]->postbreak_l();
41       current.add (post);
42       curcol++;         // skip the breakable.
43       break_idx_i++;
44
45       while (break_idx_i < breakpoints.size()) 
46         {
47         
48           // add another measure.
49           while (breakpoints[break_idx_i] != curcol.ptr())
50             {
51               current.add (curcol);
52               curcol++;
53             }
54           current.add (breakpoints[break_idx_i]->prebreak_l());
55
56           current.spacer_l_ = generate_spacing_problem (current.cols);
57
58           // try to solve
59           if (!feasible (current.cols)) 
60             {
61               if (!minimum.cols.size()) 
62                 {
63                   warning ("Ugh, this measure is too long, breakpoint: "
64                            + String (break_idx_i) +
65                            " (generating stupido solution)");
66                   current.stupid_solution();
67                   current.energy_f_ = - 1; // make sure we break out.
68                 }
69               else
70                 current.energy_f_ = infinity_f; // make sure we go back
71             }
72           else 
73             {
74                 
75               current.solve_line();
76               current.print();
77             }
78
79           delete current.spacer_l_;
80           current.spacer_l_ =0;
81
82           // update minimum, or backup.
83           if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0) 
84             {
85               minimum = current;
86             }
87           else {                // we're one col too far.
88             break_idx_i--;
89             while (curcol.ptr() != breakpoints[break_idx_i])
90               curcol --;
91             break;              // do the next line.
92           }
93
94
95           // add nobreak version of breakable column
96           current.cols.top()=breakpoints[break_idx_i];
97           curcol ++;
98           break_idx_i++;
99         }
100
101       *mlog << "[" <<break_idx_i<<"]"<<flush;
102       breaking.push (minimum);
103     }
104   print_stats();
105   return breaking;
106 }
107
108 Word_wrap::Word_wrap()
109 {
110   get_line_spacer = Spring_spacer::constructor;
111 }