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>
13 #include "molecule.hh"
16 #include "paper-def.hh"
17 #include "string-convert.hh"
21 direction_char (Direction y_sign)
42 Lookup::half_slur_middlepart (Real &dx, Direction dir) const
47 WARN<<_("halfslur too large") <<print_dimen (dx)<< _("shrinking (ugh)\n");
50 int widx = int (floor (dx / 4.0));
55 WARN << _("slur too narrow\n");
60 s.dim_[Y_AXIS] = Interval (min (0, 0), max (0, 0)); // todo
61 s.dim_[X_AXIS] = Interval (-dx/2, dx/2);
63 String f = String ("\\hslurchar");
64 f += direction_char (CENTER);
72 f +=String ("{") + String (idx) + "}";
74 s.translate_axis (dx/2, X_AXIS);
80 The halfslurs have their center at the end pointing away from the notehead.
81 This lookup translates so that width() == [0, w]
85 Lookup::half_slur (int dy, Real &dx, Direction dir, int xpart) const
89 return half_slur_middlepart (dx, dir);
95 WARN << _("Slur half too wide.") << print_dimen (orig_dx) << _(" shrinking (ugh)\n");
99 widx = int (rint (dx/12.0));
105 WARN << _("slur too narrow ") << print_dimen (orig_dx)<<"\n";
109 s.dim_[X_AXIS] = Interval (0, dx);
110 s.dim_[Y_AXIS] = Interval (min (0, dy), max (0, dy));
113 String f = String ("\\hslurchar");
115 f+= direction_char (dir);
123 idx = widx * 16 + hidx;
128 f+=String ("{") + String (idx) + "}";
136 Lookup::ps_slur (Real dy , Real dx, Real dir) const
138 String ps = "\\embeddedps{\n";
140 ps += String_convert::double_str (dx) + " "
141 + String_convert::double_str (dy) + " "
142 + String_convert::double_str (dir) +
146 slurs are rarely wider than 100pt:
147 precision of 3 yields maximum (slur spanning page)
148 error of: 1%% * 6*72pt === 0.4pt = 0.14 mm
150 String dx_str = String_convert::precision_str (dx, 4);
151 String dy_str = String_convert::precision_str (dy, 3);
152 String dir_str = String_convert::int_str ((int)dir);
153 String name = "feta-sleur-" + dx_str + "-" + dy_str + "-" + dir_str;
154 int i = name.index_i ('.');
157 *(name.ch_l () + i) = 'x';
158 i = name.index_i ('.');
161 String mf = "\\embeddedmf{" + name + "}{\n";
162 mf += "staffsize\\#:="
163 + String_convert::int_str ((int)paper_l_->get_var ("barsize"), "%d")
165 mf += "input feta-sleur;\n";
166 mf += "drawslur(" + dx_str + "," + dy_str + "," + dir_str + ");\n";
176 Lookup::tex_slur (int dy , Real &dx, Direction dir) const
178 assert (abs (dir) <= 1);
180 Direction y_sign = (Direction) sign (dy);
182 bool large = abs (dy) > 8;
186 large |= dx>= 4*16 PT;
189 large |= dx>= 4*54 PT;
193 s = big_slur (dy, dx, dir);
197 int widx = int (floor (dx/4.0)); // slurs better too small..
203 WARN << _("slur too narrow: ") << print_dimen (orig_dx) << "\n";
212 WARN<<_("slur to steep: ") << dy << _(" shrinking (ugh)\n");
215 String f = String ("\\slurchar") + String (direction_char (y_sign));
220 idx = hidx * 16 + widx;
228 WARN << _("slur too wide: ") << print_dimen (dx) <<
229 _(" shrinking (ugh)\n");
238 f+=String ("{") + String (idx) + "}";
240 s.translate_axis (dx/2, X_AXIS);
245 Lookup::big_slur (int dy , Real &dx, Direction dir) const
249 warning (_("big_slur too small ") + print_dimen (dx) + _(" (stretching)"));
253 Real slur_extra =abs (dy) /2.0 + 2;
254 int l_dy = int (Real (dy)/2 + slur_extra*dir);
255 int r_dy = dy - l_dy;
257 Real internote_f = paper_l_->internote_f();
258 Real left_wid = dx/4.0;
259 Real right_wid = left_wid;
261 Atom l = half_slur (l_dy, left_wid, dir, -1);
264 Atom r = half_slur (r_dy, right_wid, dir, 1);
265 Real mid_wid = dx - left_wid - right_wid;
269 Atom a (half_slur (0, mid_wid, dir, 0));
270 mol.add_at_edge (X_AXIS, RIGHT, a);
271 mol.add_at_edge (X_AXIS, RIGHT, r);
273 mol.translate_axis (l_dy * internote_f, Y_AXIS);
275 s.tex_ = mol.TeX_string();
276 s.dim_ = mol.extent();
282 Lookup::slur (Real &dy_f , Real &dx, Direction dir) const
286 warning (_("Negative slur/tie length: ") + print_dimen (dx));
291 if (postscript_global_b)
292 s = ps_slur (dy_f, dx, dir);
295 Real nh = paper_l_->internote_f ();
296 int dy_i = (int) rint(dy_f / nh);
298 s = tex_slur (dy_i, dx, dir);
302 s.dim_[X_AXIS] = Interval (0, dx);
303 s.dim_[Y_AXIS] = Interval (0 <? dy_f, 0 >? dy_f);