lilypond-1.1.31
[lilypond.git] / src / texslur.cc
blob71cded95299cdebe83f02da7c43dadc746320640
1 #include <math.h>
2 #include "misc.hh"
3 #include "lookup.hh"
4 #include "molecule.hh"
5 #include "dimen.hh"
6 #include "debug.hh"
8 static
9 char direction_char(int y_sign)
11 char c='#';
12 switch(y_sign){
13 case -1:
14 c = 'd';
15 break;
16 case 0:
17 c = 'h';
18 break;
19 case 1:
20 c = 'u';
21 break;
22 default:
23 assert(false);
25 return c;
28 Symbol
29 Lookup::half_slur_middlepart(Real &dx, int dir)
31 if (dx >= 400 PT) {// todo
32 WARN<<"halfslur too large" <<print_dimen(dx)<< "shrinking (ugh)\n";
33 dx = 400 PT;
35 int widx = int(floor(dx / 4.0));
36 dx = widx * 4.0;
37 if (widx) widx --;
38 else {
39 WARN << "slur too narrow\n";
42 Symbol s;
44 s.dim.y = Interval(min(0,0), max(0,0)); // todo
45 s.dim.x = Interval(0,dx);
47 String f = String("\\hslurchar");
48 f += direction_char(0);
50 int idx = widx;
51 if (dir < 0)
52 idx += 128;
55 f+=String( "{" ) + String( idx ) + "}";
56 s.tex = f;
57 Atom a(s);
58 a.translate(Offset(dx/2,0));
59 s.tex = a.TeXstring();
61 return s;
63 Symbol
64 Lookup::half_slur(int dy, Real &dx, int dir, int xpart)
66 Real orig_dx = dx;
67 if (!xpart)
68 return half_slur_middlepart(dx, dir);
70 int widx;
72 if (dx >= 96 PT) {
73 WARN << "Slur half too wide." << print_dimen(orig_dx) << " shrinking (ugh)\n";
74 dx = 96 PT;
77 widx = int(rint(dx/12.0));
78 dx = widx*12.0;
79 if (widx)
80 widx --;
81 else {
82 WARN << "slur too narrow " << print_dimen(orig_dx)<<"\n";
85 Symbol s;
86 s.dim.x = Interval(0,dx);
87 s.dim.y = Interval(min(0,dy), max(0,dy));
90 String f = String("\\hslurchar");
92 f+= direction_char(dir);
94 int hidx = dy;
95 if (hidx <0)
96 hidx = -hidx;
97 hidx --;
98 int idx =-1;
101 idx = widx * 16 + hidx;
102 if (xpart < 0)
103 idx += 128;
105 f+=String( "{" ) + String( idx ) + "}";
108 s.tex = f;
110 return s;
113 Symbol
114 Lookup::slur (int dy , Real &dx, int dir)
116 assert(dx >=0 && abs(dir) <= 1);
117 int y_sign = sign(dy);
119 bool large = dy > 16;
121 if (y_sign) {
122 large |= dx>= 4*16 PT;
123 } else
124 large |= dx>= 4*54 PT;
126 if (large) {
127 return big_slur(dy, dx, dir);
129 Real orig_dx = dx;
130 int widx = int(floor(dx/4.0)); // slurs better too small..
131 dx = 4.0 * widx;
132 if (widx)
133 widx --;
134 else {
135 WARN << "slur too narrow: " << print_dimen(orig_dx) << "\n";
138 int hidx = dy;
139 if (hidx <0)
140 hidx = -hidx;
141 hidx --;
142 if (hidx > 16) {
143 WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
146 Symbol s;
147 s.dim.x = Interval(0,dx);
148 s.dim.y = Interval(min(0,dy), max(0,dy));
150 String f = String("\\slurchar") + String( direction_char(y_sign) );
152 int idx=-1;
153 if (y_sign) {
154 idx = hidx * 16 + widx;
155 if (dir < 0)
156 idx += 128;
157 } else {
158 if (dx >= 4*54 PT) {
159 WARN << "slur too wide: " << print_dimen(dx) <<
160 " shrinking (ugh)\n";
161 dx = 4*54 PT;
163 idx = widx;
164 if (dir < 0)
165 idx += 54;
168 f+=String( "{" ) + String( idx ) + "}";
169 s.tex = f;
171 Atom a(s);
172 a.translate(Offset(dx/2,0));
173 s.dim = a.extent();
174 s.tex = a.TeXstring();
175 return s;
178 Symbol
179 Lookup::big_slur(int dy , Real &dx, int dir)
181 assert(dx >= 24 PT);
182 Real slur_extra =abs(dy) /2.0 + 2;
183 int l_dy = int(Real (dy)/2 + slur_extra*dir);
184 int r_dy = dy - l_dy;
186 Real left_wid = dx/4.0;
187 Real right_wid = left_wid;
189 Atom l = half_slur(l_dy, left_wid, dir, -1);
190 Atom r = half_slur(r_dy, right_wid, dir, 1);
191 Real mid_wid = dx - left_wid - right_wid;
193 Atom m = half_slur(0, mid_wid, dir, 0);
195 Molecule mol;
196 mol.add(l);
197 Atom a(m);
198 a.translate(Offset(0,slur_extra * internote()));
199 mol.add_right(m);
200 mol.add_right(r);
201 mol.translate(Offset(0, l_dy * internote()));
202 Symbol s;
203 s.tex = mol.TeXstring();
204 s.dim = mol.extent();
205 return s;