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