]> git.donarmstrong.com Git - lilypond.git/blob - lily/word-wrap.cc
beddf0d7531b1b3a658b8b6bcb143933f6172525
[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<PCol*> 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         PCol *post = breakpoints[break_idx_i]->postbreak_p_;
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_p_);
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 }