]> git.donarmstrong.com Git - lilypond.git/blob - break.cc
release: 0.0.5
[lilypond.git] / break.cc
1 /*
2     do calculations for breaking problem
3     
4     */
5
6 #include "linespace.hh"
7 #include "debug.hh"
8 #include "line.hh"
9 #include "pscore.hh"
10
11 // construct an appropriate Spacing_problem and solve it. 
12 svec<Real>
13 PScore::solve_line(svec<const PCol *> curline) const
14 {
15    Spacing_problem sp;
16
17    sp.add_column(curline[0], true, 0.0);
18    for (int i=1; i< curline.sz()-1; i++)
19        sp.add_column(curline[i]);
20    sp.add_column(curline.last(), true, linewidth);
21
22    // misschien  moeven uit Spacing_problem? 
23    for (PCursor<Idealspacing *> i(suz); i.ok(); i++) {
24        sp.add_ideal(i);
25    }
26    svec<Real> the_sol=sp.solve();
27    return the_sol;
28 }
29
30
31 void
32 PScore::problem_OK() const
33 {
34     if (!cols.size())
35         error("PScore::problem_OK(): Score does not have any columns");
36     PCursor<PCol *> start(cols);
37     PCursor<PCol *> end (((PScore*)this)->cols.bottom());
38     
39     assert(start->breakable());    
40     assert(end->breakable());
41 }
42
43 struct Col_configuration {
44     svec<const PCol*> line;
45     svec<Real> config;
46     Real energy;
47
48     Col_configuration() {
49         energy = INFTY;
50     }
51     void add(const PCol*c) { line.add(c);}
52     void setsol(svec<Real> sol) {
53         config = sol;
54         energy = config.last();
55         config.pop();
56     }
57     void print() const {
58 #ifndef NPRINT
59         mtor << "energy : " << energy << '\n';
60         mtor << "line of " << config.sz() << " cols\n";
61 #endif
62     }
63 };
64
65 /// wordwrap type algorithm
66 /* el stupido. This should be done more accurately:
67
68    It would be nice to have a Dynamic Programming type of algorithm
69    similar to TeX's
70    
71     */
72
73 void
74 PScore::calc_breaking()
75 {
76     OK();
77     problem_OK();
78     PCursor<PCol *> curcol(cols);
79             
80     svec<const PCol *> breakpoints(find_breaks());
81     assert(breakpoints.sz()>=2);
82     for (int i=0 ; i < breakpoints.sz() -1; ) {
83         Col_configuration minimum;
84         Col_configuration current;
85
86         // do  another line
87         PCol *post = breakpoints[i]->postbreak;
88         current.add( post);
89         curcol++;               // skip the breakable.
90         i++;
91
92         while (i < breakpoints.sz()) {
93
94             // add another measure.
95             while(breakpoints[i] !=curcol){
96                 
97                 current.add(curcol);
98                 curcol++;
99             }
100             current.add(breakpoints[i]->prebreak );
101             current.setsol(solve_line(current.line));
102             current.print();
103             
104             if (current.energy < minimum.energy) {
105                 minimum = current;
106             } else {            // we're one col too far.
107                 i--;
108                 while (curcol != breakpoints[i])
109                     curcol --;
110                 
111                 break;
112             }
113         
114             current.line.last()=breakpoints[i];
115             curcol ++;
116             i++;
117         }
118         mtor << "Adding line, next breakpoint " << i << '\n';
119         add_line(minimum.line, minimum.config); 
120     }
121 }
122