]> git.donarmstrong.com Git - lilypond.git/blob - lily/word-wrap.cc
6b7abf398bd089b3512dc3128adcddc43ba07759
[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 "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       current.add (post);
45       curcol++;         // skip the breakable.
46       break_idx_i++;
47
48       while (break_idx_i < breakpoints.size())
49         {
50
51           // add another measure.
52           while (breakpoints[break_idx_i] != curcol.ptr())
53             {
54               current.add (curcol);
55               curcol++;
56             }
57           current.add (breakpoints[break_idx_i]->prebreak_l());
58
59           current.spacer_l_ = generate_spacing_problem (current.cols, 
60             pscore_l_->paper_l_->line_dimensions_int (line_no_i));
61
62           // try to solve
63           if (!feasible (current.cols))
64             {
65               if (!minimum.cols.size())
66                 {
67                   warning (_("Ugh, this measure is too long, breakpoint: ")
68                            + String (break_idx_i) +
69                            _(" (generating stupido solution)"));
70                   current.stupid_solution();
71                   current.energy_f_ = - 1; // make sure we break out.
72                 }
73               else
74                 current.energy_f_ = infinity_f; // make sure we go back
75             }
76           else
77             {
78
79               current.solve_line();
80               current.print();
81             }
82
83           delete current.spacer_l_;
84           current.spacer_l_ =0;
85
86           // update minimum, or backup.
87           if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0)
88             {
89               minimum = current;
90             }
91           else {                // we're one col too far.
92             break_idx_i--;
93             while (curcol.ptr() != breakpoints[break_idx_i])
94               curcol --;
95             break;              // do the next line.
96           }
97
98
99           // add nobreak version of breakable column
100           current.cols.top()=breakpoints[break_idx_i];
101           curcol ++;
102           break_idx_i++;
103         }
104
105       *mlog << "[" <<break_idx_i<<"]"<<flush;
106       breaking.push (minimum);
107     }
108   return breaking;
109 }
110
111 Word_wrap::Word_wrap()
112 {
113   get_line_spacer = Spring_spacer::constructor;
114 }