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 ht
, 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 (ht
) + " "
143 + String_convert::double_str (dir
) +
147 slurs are rarely wider than 100pt:
148 precision of 3 yields maximum (slur spanning page)
149 error of: 1%% * 6*72pt === 0.4pt = 0.14 mm
151 String dx_str
= String_convert::precision_str (dx
, 4);
152 String dy_str
= String_convert::precision_str (dy
, 3);
153 String ht_str
= String_convert::precision_str (ht
, 3);
154 String dir_str
= String_convert::int_str ((int)dir
);
155 String name
= "feta-sleur-" + dx_str
+ "-" + dy_str
+ "-" + ht_str
+ "-" + dir_str
;
156 int i
= name
.index_i ('.');
159 *(name
.ch_l () + i
) = 'x';
160 i
= name
.index_i ('.');
163 String mf
= "\\embeddedmf{" + name
+ "}{\n";
164 mf
+= "mode_setup;\n";
165 mf
+= "staffsize\\#:="
166 + String_convert::int_str ((int)paper_l_
->get_var ("barsize"), "%d")
168 mf
+= "interline#:=staffsize#/4;\n";
169 mf
+= "stafflinethickness#:=0.1interline#;\n";
170 mf
+= "input feta-sleur;\n";
171 mf
+= "slurchar(" + dx_str
+ "," + dy_str
+ "," + ht_str
+ "," + dir_str
+ ");\n";
177 if (embedded_mf_global_b
)
183 Lookup::tex_slur (int dy
, Real
&dx
, Direction dir
) const
185 assert (abs ((int)dir
) <= 1);
187 Direction y_sign
= (Direction
) sign (dy
);
189 bool large
= abs (dy
) > 8;
193 large
|= dx
>= 4*16 PT
;
196 large
|= dx
>= 4*54 PT
;
200 s
= big_slur (dy
, dx
, dir
);
204 int widx
= int (floor (dx
/4.0)); // slurs better too small..
210 WARN
<< _("slur too narrow: ") << print_dimen (orig_dx
) << "\n";
219 WARN
<<_("slur to steep: ") << dy
<< _(" shrinking (ugh)\n");
222 String f
= String ("\\slurchar") + String (direction_char (y_sign
));
227 idx
= hidx
* 16 + widx
;
235 WARN
<< _("slur too wide: ") << print_dimen (dx
) <<
236 _(" shrinking (ugh)\n");
245 f
+=String ("{") + String (idx
) + "}";
247 s
.translate_axis (dx
/2, X_AXIS
);
252 Lookup::big_slur (int dy
, Real
&dx
, Direction dir
) const
256 warning (_("big_slur too small ") + print_dimen (dx
) + _(" (stretching)"));
260 Real slur_extra
=abs (dy
) /2.0 + 2;
261 int l_dy
= int (Real (dy
)/2 + slur_extra
*dir
);
262 int r_dy
= dy
- l_dy
;
264 Real internote_f
= paper_l_
->internote_f();
265 Real left_wid
= dx
/4.0;
266 Real right_wid
= left_wid
;
268 Atom l
= half_slur (l_dy
, left_wid
, dir
, -1);
271 Atom r
= half_slur (r_dy
, right_wid
, dir
, 1);
272 Real mid_wid
= dx
- left_wid
- right_wid
;
276 Atom
a (half_slur (0, mid_wid
, dir
, 0));
277 mol
.add_at_edge (X_AXIS
, RIGHT
, a
);
278 mol
.add_at_edge (X_AXIS
, RIGHT
, r
);
280 mol
.translate_axis (l_dy
* internote_f
, Y_AXIS
);
282 s
.tex_
= mol
.TeX_string();
283 s
.dim_
= mol
.extent();
289 Lookup::slur (Real
&dy_f
, Real
&dx
, Real ht
, Direction dir
) const
293 warning (_("Negative slur/tie length: ") + print_dimen (dx
));
298 if (postscript_global_b
)
299 s
= ps_slur (dy_f
, dx
, ht
, dir
);
302 Real nh
= paper_l_
->internote_f ();
303 int dy_i
= (int) rint(dy_f
/ nh
);
305 s
= tex_slur (dy_i
, dx
, dir
);
309 s
.dim_
[X_AXIS
] = Interval (0, dx
);
310 s
.dim_
[Y_AXIS
] = Interval (0 <? dy_f
, 0 >? dy_f
);
315 Lookup::control_slur (Array
<Offset
> controls
, Real dx
, Real dy
) const
317 assert (postscript_global_b
);
318 assert (controls
.size () == 8);
320 String ps
= "\\embeddedps{\n";
322 for (int i
= 1; i
< 4; i
++)
323 ps
+= String_convert::double_str (controls
[i
].x ()) + " "
324 + String_convert::double_str (controls
[i
].y ()) + " ";
326 for (int i
= 5; i
< 8; i
++)
327 // ps += String_convert::double_str (controls[i].x () + controls[0].x () - controls[3].x ()) + " "
328 // + String_convert::double_str (controls[i].y () - controls[0].y () + controls[3].y ()) + " ";
329 ps
+= String_convert::double_str (controls
[i
].x () - dx
) + " "
330 + String_convert::double_str (controls
[i
].y () - dy
) + " ";
332 ps
+= " draw_control_slur}";
337 s
.dim_
[X_AXIS
] = Interval (0, dx
);
338 s
.dim_
[Y_AXIS
] = Interval (0 <? dy
, 0 >? dy
);