lilypond-0.1.16
[lilypond.git] / lily / tex-slur.cc
blob664460f8b9c542e4942071d24f8605273d559386
1 /*
2 tex-slur.cc -- implement Lookup::*slur
4 source file of the GNU LilyPond music typesetter
6 (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
9 #include <math.h>
10 #include "misc.hh"
11 #include "lookup.hh"
12 #include "molecule.hh"
13 #include "dimen.hh"
14 #include "debug.hh"
15 #include "paper-def.hh"
18 static char
19 direction_char (Direction y_sign)
21 char c='#';
22 switch (y_sign)
24 case DOWN:
25 c = 'd';
26 break;
27 case CENTER:
28 c = 'h';
29 break;
30 case UP:
31 c = 'u';
32 break;
33 default:
34 assert (false);
36 return c;
39 Atom
40 Lookup::half_slur_middlepart (Real &dx, Direction dir) const
42 // todo
43 if (dx >= 400 PT)
45 WARN<<"halfslur too large" <<print_dimen (dx)<< "shrinking (ugh)\n";
46 dx = 400 PT;
48 int widx = int (floor (dx / 4.0));
49 dx = widx * 4.0;
50 if (widx) widx --;
51 else
53 WARN << "slur too narrow\n";
56 Atom s;
58 s.dim_.y() = Interval (min (0,0), max (0,0)); // todo
59 s.dim_.x() = Interval (0,dx);
61 String f = String ("\\hslurchar");
62 f += direction_char (CENTER);
64 int idx = widx;
65 if (dir < 0)
66 idx += 128;
68 assert (idx < 256);
70 f +=String ("{") + String (idx) + "}";
71 s.tex_ = f;
72 s.translate (dx/2, X_AXIS);
74 return s;
77 Atom
78 Lookup::half_slur (int dy, Real &dx, Direction dir, int xpart) const
80 Real orig_dx = dx;
81 if (!xpart)
82 return half_slur_middlepart (dx, dir);
84 int widx;
86 if (dx >= 96 PT)
88 WARN << "Slur half too wide." << print_dimen (orig_dx) << " shrinking (ugh)\n";
89 dx = 96 PT;
92 widx = int (rint (dx/12.0));
93 dx = widx*12.0;
94 if (widx)
95 widx --;
96 else
98 WARN << "slur too narrow " << print_dimen (orig_dx)<<"\n";
101 Atom s;
102 s.dim_.x() = Interval (0,dx);
103 s.dim_.y() = Interval (min (0,dy), max (0,dy));
106 String f = String ("\\hslurchar");
108 f+= direction_char (dir);
110 int hidx = dy;
111 if (hidx <0)
112 hidx = -hidx;
113 hidx --;
114 int idx =-1;
116 idx = widx * 16 + hidx;
117 if (xpart < 0)
118 idx += 128;
120 assert (idx < 256);
121 f+=String ("{") + String (idx) + "}";
124 s.tex_ = f;
126 return s;
129 Atom
130 Lookup::slur (int dy , Real &dx, Direction dir) const
133 assert (abs (dir) <= 1);
134 if (dx < 0)
136 warning ("Negative slur/tie length: " + print_dimen (dx));
137 dx = 4.0 PT;
139 Direction y_sign = (Direction) sign (dy);
141 bool large = abs (dy) > 8;
143 if (y_sign)
145 large |= dx>= 4*16 PT;
147 else
148 large |= dx>= 4*54 PT;
150 if (large)
152 return big_slur (dy, dx, dir);
154 Real orig_dx = dx;
155 int widx = int (floor (dx/4.0)); // slurs better too small..
156 dx = 4.0 * widx;
157 if (widx)
158 widx --;
159 else
161 WARN << "slur too narrow: " << print_dimen (orig_dx) << "\n";
164 int hidx = dy;
165 if (hidx <0)
166 hidx = -hidx;
167 hidx --;
168 if (hidx > 8)
170 WARN<<"slur to steep: " << dy << " shrinking (ugh)\n";
173 Atom s;
174 s.dim_.x() = Interval (-dx/2,dx/2);
175 s.dim_.y() = Interval (min (0,dy), max (0,dy));
177 String f = String ("\\slurchar") + String (direction_char (y_sign));
179 int idx=-1;
180 if (y_sign) {
181 idx = hidx * 16 + widx;
182 if (dir < 0)
183 idx += 128;
185 else
187 if (dx >= 4*54 PT)
189 WARN << "slur too wide: " << print_dimen (dx) <<
190 " shrinking (ugh)\n";
191 dx = 4*54 PT;
193 idx = widx;
194 if (dir < 0)
195 idx += 54;
198 assert (idx < 256);
199 f+=String ("{") + String (idx) + "}";
200 s.tex_ = f;
203 s.translate (dx/2, X_AXIS);
204 return s;
207 Atom
208 Lookup::big_slur (int dy , Real &dx, Direction dir) const
210 if (dx < 24 PT)
212 warning ("big_slur too small " + print_dimen (dx) + " (stretching)");
213 dx = 24 PT;
216 Real slur_extra =abs (dy) /2.0 + 2;
217 int l_dy = int (Real (dy)/2 + slur_extra*dir);
218 int r_dy = dy - l_dy;
220 Real internote_f = paper_l_->internote_f();
221 Real left_wid = dx/4.0;
222 Real right_wid = left_wid;
224 Atom l = half_slur (l_dy, left_wid, dir, -1);
225 Atom r = half_slur (r_dy, right_wid, dir, 1);
226 Real mid_wid = dx - left_wid - right_wid;
228 Molecule mol;
229 mol.add (l);
230 Atom a (half_slur (0, mid_wid, dir, 0));
231 a.translate (slur_extra * internote_f, Y_AXIS);
232 mol.add_at_edge (X_AXIS, RIGHT, a);
233 mol.add_at_edge (X_AXIS, RIGHT, r);
234 mol.translate (l_dy * internote_f, Y_AXIS);
236 Atom s;
237 s.tex_ = mol.TeX_string();
238 s.dim_ = mol.extent();
239 return s;