lilypond-0.1.47
[lilypond.git] / src / texbeam.cc
blobc9f3c954812171495e0b53087f68f7a62b90a731
1 /*
3 Code to generate beams for TeX
5 */
7 #include <math.h>
8 #include "symbol.hh"
9 #include "molecule.hh"
10 #include "tex.hh"
11 #include "symtable.hh"
12 #include "dimen.hh"
13 #include "debug.hh"
14 #include "lookup.hh"
16 Symbol
17 Lookup::beam_element(int sidx, int widx, Real slope)
19 Symbol bs=(*symtables_)("beamslopes")->lookup("slope");
21 Array<String> args;
22 args.push(sidx);
23 args.push(widx);
24 bs.tex = substitute_args(bs.tex,args);
25 int w = 2 << widx;
26 Real width = w PT;
27 bs.dim.x = Interval(0,width);
28 bs.dim.y = Interval(0,width*slope);
29 return bs;
32 // ugh.. hard wired tex-code.
33 static int
34 slope_index(Real &s)
36 if (abs(s) > 0.5) {
37 WARN << "beam steeper than 0.5 (" << s << ")\n";
38 s = sign(s) * 0.5;
41 int i = int(rint(s * 20.0));
43 s = i/20.0;
44 if (s>0)
45 return 6*i +122;
46 else
47 return -6 * i+ 186;
50 Symbol
51 Lookup::rule_symbol(Real height, Real width)
53 Symbol bs=(*symtables_)("beamslopes")->lookup("horizontal");
54 Array<String> args;
55 args.push(print_dimen(height));
56 args.push(print_dimen(width));
57 bs.tex = substitute_args(bs.tex,args);
58 bs.dim.x = Interval(0,width);
59 bs.dim.y = Interval(0,height);
60 return bs;
63 Symbol
64 Lookup::beam(Real &slope, Real width)
66 int sidx = slope_index(slope);
67 if (!slope)
68 return rule_symbol(2 PT, width);
69 if (width < 2 PT) {
70 WARN<<"Beam too narrow. (" << print_dimen(width) <<")\n";
71 width = 2 PT;
73 Real elemwidth = 64 PT;
74 int widx = 5;
76 Molecule m;
78 while (elemwidth > width) {
79 widx --;
80 elemwidth /= 2.0;
82 Real overlap = elemwidth/4;
83 Real last_x = width - elemwidth;
84 Real x = overlap;
85 Atom elem(beam_element(sidx, widx, slope));
86 Atom a(elem);
87 m.add(a);
88 while (x < last_x) {
89 a=elem;
90 a.translate(Offset(x-overlap, (x-overlap)*slope));
91 m.add(a);
92 x += elemwidth - overlap;
94 a=elem;
95 a.translate(Offset(last_x, (last_x) * slope));
96 m.add(a);
98 Symbol ret;
99 ret.tex = m.TeXstring();
100 ret.dim.y = Interval(0,width*slope);
101 ret.dim.x = Interval(0,width);
103 return ret;