]> git.donarmstrong.com Git - lilypond.git/blob - lily/word-wrap.cc
release: 0.1.61
[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--1998 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "word-wrap.hh"
10 #include "paper-def.hh"
11 #include "p-score.hh"
12 #include "debug.hh"
13 #include "p-col.hh"
14 #include "spring-spacer.hh"
15
16
17 /** el stupido.
18
19
20    A Dynamic Programming type of algorithm
21    similar to TeX's is in Gourlay_breaking
22
23    */
24 Array<Col_hpositions>
25 Word_wrap::do_solve() const
26 {
27   problem_OK();
28
29   PCursor<Paper_column*> curcol (pscore_l_->col_p_list_.top());
30   Array<Col_hpositions> breaking;
31   Line_of_cols breakpoints (find_breaks());
32   assert (breakpoints.size()>=2);
33
34   int break_idx_i=0;
35   int line_no_i = 0;
36   while (break_idx_i < breakpoints.size() -1)
37     {
38       Col_hpositions minimum;
39       Col_hpositions current;
40
41       // do  another line
42       line_no_i ++;
43       Paper_column *post = breakpoints[break_idx_i]->postbreak_l();
44       int start_break_idx = break_idx_i;
45       current.add (post);
46       curcol++;         // skip the breakable.
47       break_idx_i++;
48
49       while (break_idx_i < breakpoints.size())
50         {
51
52           // add another measure.
53           while (breakpoints[break_idx_i] != curcol.ptr())
54             {
55               current.add (curcol);
56               curcol++;
57             }
58           current.add (breakpoints[break_idx_i]->prebreak_l());
59
60           current.spacer_l_ = generate_spacing_problem (current.cols, 
61             pscore_l_->paper_l_->line_dimensions_int (line_no_i));
62
63           // try to solve
64           if (!feasible (current.cols))
65             {
66               if (!minimum.cols.size())
67                 {
68                   warning (_("Ugh, this measure is too long, breakpoint: ")
69                            + String (break_idx_i) +
70                            _(" (generating stupido solution)"));
71                   current.stupid_solution();
72                   current.energy_f_ = - 1; // make sure we break out.
73                 }
74               else
75                 current.energy_f_ = infinity_f; // make sure we go back
76             }
77           else
78             {
79               current.solve_line();
80               current.print();
81             }
82
83           delete current.spacer_l_;
84           current.spacer_l_ =0;
85
86           if (!current.satisfies_constraints_b_ && start_break_idx == break_idx_i - 1)
87             {
88               warning ( _ ("I don't fit.  Put me on Montignac"));
89               minimum = current;
90               break;
91             }
92
93           if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0)
94             {
95               minimum = current;
96             }
97           else {                // we're one col too far.
98             break_idx_i--;
99             while (curcol.ptr() != breakpoints[break_idx_i])
100               curcol --;
101             break;              // do the next line.
102           }
103
104
105           // add nobreak version of breakable column
106           current.cols.top()=breakpoints[break_idx_i];
107           curcol ++;
108           break_idx_i++;
109         }
110
111       *mlog << "[" <<break_idx_i<<"]"<<flush;
112       breaking.push (minimum);
113     }
114   return breaking;
115 }
116
117 Word_wrap::Word_wrap()
118 {
119   get_line_spacer = Spring_spacer::constructor;
120 }