2 lookup.cc -- implement simple Lookup methods.
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 Jan Nieuwenhuizen <janneke@gnu.org>
17 #include "dimensions.hh"
19 #include "string-convert.hh"
20 #include "file-path.hh"
22 #include "lily-guile.hh"
23 #include "molecule.hh"
25 #include "font-metric.hh"
28 Lookup::beam (Real slope, Real width, Real thick)
30 Real height = slope * width;
31 Real min_y = (0 <? height) - thick/2;
32 Real max_y = (0 >? height) + thick/2;
36 Box b (Interval (0, width),
37 Interval (min_y, max_y));
40 SCM at = scm_list_n (ly_symbol2scm ("beam"),
41 gh_double2scm (width),
42 gh_double2scm (slope),
43 gh_double2scm (thick),
45 return Molecule (b, at);
51 Lookup::dashed_slur (Bezier b, Real thick, Real dash)
55 for (int i= 4; i -- ;)
57 l = gh_cons (ly_offset2scm (b.control_[i]), l);
60 SCM at = (scm_list_n (ly_symbol2scm ("dashed-slur"),
61 gh_double2scm (thick),
66 Box box (Interval (0,0),Interval (0,0));
67 return Molecule (box, at);
76 return Molecule (b, SCM_EOL);
81 Lookup::filledbox (Box b)
83 SCM at = (scm_list_n (ly_symbol2scm ("filledbox"),
84 gh_double2scm (-b[X_AXIS][LEFT]),
85 gh_double2scm (b[X_AXIS][RIGHT]),
86 gh_double2scm (-b[Y_AXIS][DOWN]),
87 gh_double2scm (b[Y_AXIS][UP]),
90 return Molecule (b,at);
94 Lookup::frame (Box b, Real thick)
103 Axis o = Axis ((a+1)%NO_AXES);
106 edges[a] = b[a][d] + 0.5 * thick * Interval (-1, 1);
107 edges[o][DOWN] = b[o][DOWN] - thick/2;
108 edges[o][UP] = b[o][UP] + thick/2;
111 m.add_molecule (filledbox (edges));
113 while (flip (&d) != LEFT);
121 Make a smooth curve along the points
124 Lookup::slur (Bezier curve, Real curvethick, Real linethick)
126 Real alpha = (curve.control_[3] - curve.control_[0]).arg ();
128 Offset perp = curvethick * complex_exp (Offset (0, alpha + M_PI/2)) * 0.5;
130 back.control_[1] += perp;
131 back.control_[2] += perp;
133 curve.control_[1] -= perp;
134 curve.control_[2] -= perp;
139 scontrols[ i ] = ly_offset2scm (back.control_[i]);
141 scontrols[i+4] = ly_offset2scm (curve.control_[i]);
144 Need the weird order b.o. the way PS want its arguments
146 int indices[]= {5, 6, 7, 4, 1, 2, 3, 0};
150 list = gh_cons (scontrols[indices[i]], list);
154 SCM at = (scm_list_n (ly_symbol2scm ("bezier-sandwich"),
156 gh_double2scm (linethick),
158 Box b(curve.extent (X_AXIS),
159 curve.extent (Y_AXIS));
161 b[X_AXIS].unite (back.extent (X_AXIS));
162 b[Y_AXIS].unite (back.extent (Y_AXIS));
164 return Molecule (b, at);
168 Lookup::accordion (SCM s, Real staff_space, Font_metric *fm)
171 String sym = ly_scm2string (ly_car (s));
172 String reg = ly_scm2string (ly_car (ly_cdr (s)));
174 if (sym == "Discant")
176 Molecule r = fm->find_by_name ("accordion-accDiscant");
178 if (reg.left_str (1) == "F")
180 Molecule d = fm->find_by_name ("accordion-accDot");
181 d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
183 reg = reg.right_str (reg.length_i ()-1);
186 if (reg.left_str (3) == "EEE")
189 reg = reg.right_str (reg.length_i ()-3);
191 else if (reg.left_str (2) == "EE")
194 reg = reg.right_str (reg.length_i ()-2);
196 else if (reg.left_str (2) == "Eh")
199 reg = reg.right_str (reg.length_i ()-2);
201 else if (reg.left_str (1) == "E")
204 reg = reg.right_str (reg.length_i ()-1);
208 Molecule d = fm->find_by_name ("accordion-accDot");
209 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
214 Molecule d = fm->find_by_name ("accordion-accDot");
215 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
216 d.translate_axis (0.8 * staff_space PT, X_AXIS);
221 Molecule d = fm->find_by_name ("accordion-accDot");
222 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
223 d.translate_axis (-0.8 * staff_space PT, X_AXIS);
226 if (reg.left_str (2) == "SS")
228 Molecule d = fm->find_by_name ("accordion-accDot");
229 d.translate_axis (0.5 * staff_space PT, Y_AXIS);
230 d.translate_axis (0.4 * staff_space PT, X_AXIS);
232 d.translate_axis (-0.8 * staff_space PT, X_AXIS);
234 reg = reg.right_str (reg.length_i ()-2);
236 if (reg.left_str (1) == "S")
238 Molecule d = fm->find_by_name ("accordion-accDot");
239 d.translate_axis (0.5 * staff_space PT, Y_AXIS);
241 reg = reg.right_str (reg.length_i ()-1);
244 else if (sym == "Freebase")
246 Molecule r = fm->find_by_name ("accordion-accFreebase");
248 if (reg.left_str (1) == "F")
250 Molecule d = fm->find_by_name ("accordion-accDot");
251 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
253 reg = reg.right_str (reg.length_i ()-1);
257 Molecule d = fm->find_by_name ("accordion-accDot");
258 d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
262 else if (sym == "Bayanbase")
264 Molecule r = fm->find_by_name ("accordion-accBayanbase");
266 if (reg.left_str (1) == "T")
268 Molecule d = fm->find_by_name ("accordion-accDot");
269 d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
271 reg = reg.right_str (reg.length_i ()-1);
273 /* include 4' reed just for completeness. You don't want to use this. */
274 if (reg.left_str (1) == "F")
276 Molecule d = fm->find_by_name ("accordion-accDot");
277 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
279 reg = reg.right_str (reg.length_i ()-1);
281 if (reg.left_str (2) == "EE")
283 Molecule d = fm->find_by_name ("accordion-accDot");
284 d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
285 d.translate_axis (0.4 * staff_space PT, X_AXIS);
287 d.translate_axis (-0.8 * staff_space PT, X_AXIS);
289 reg = reg.right_str (reg.length_i ()-2);
291 if (reg.left_str (1) == "E")
293 Molecule d = fm->find_by_name ("accordion-accDot");
294 d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
296 reg = reg.right_str (reg.length_i ()-1);
299 else if (sym == "Stdbase")
301 Molecule r = fm->find_by_name ("accordion-accStdbase");
303 if (reg.left_str (1) == "T")
305 Molecule d = fm->find_by_name ("accordion-accDot");
306 d.translate_axis (staff_space * 3.5 PT, Y_AXIS);
308 reg = reg.right_str (reg.length_i ()-1);
310 if (reg.left_str (1) == "F")
312 Molecule d = fm->find_by_name ("accordion-accDot");
313 d.translate_axis (staff_space * 2.5 PT, Y_AXIS);
315 reg = reg.right_str (reg.length_i ()-1);
317 if (reg.left_str (1) == "M")
319 Molecule d = fm->find_by_name ("accordion-accDot");
320 d.translate_axis (staff_space * 2 PT, Y_AXIS);
321 d.translate_axis (staff_space PT, X_AXIS);
323 reg = reg.right_str (reg.length_i ()-1);
325 if (reg.left_str (1) == "E")
327 Molecule d = fm->find_by_name ("accordion-accDot");
328 d.translate_axis (staff_space * 1.5 PT, Y_AXIS);
330 reg = reg.right_str (reg.length_i ()-1);
332 if (reg.left_str (1) == "S")
334 Molecule d = fm->find_by_name ("accordion-accDot");
335 d.translate_axis (staff_space * 0.5 PT, Y_AXIS);
337 reg = reg.right_str (reg.length_i ()-1);
340 /* ugh maybe try to use regular font for S.B. and B.B and only use one font
342 else if (sym == "SB")
344 Molecule r = fm->find_by_name ("accordion-accSB");
347 else if (sym == "BB")
349 Molecule r = fm->find_by_name ("accordion-accBB");
352 else if (sym == "OldEE")
354 Molecule r = fm->find_by_name ("accordion-accOldEE");
357 else if (sym == "OldEES")
359 Molecule r = fm->find_by_name ("accordion-accOldEES");
366 TODO: should use slope instead? Angle gives nasty rad <-> degree
370 Lookup::repeat_slash (Real w, Real s, Real t)
372 SCM wid = gh_double2scm (w);
373 SCM sl = gh_double2scm (s);
374 SCM thick = gh_double2scm (t);
375 SCM slashnodot = scm_list_n (ly_symbol2scm ("repeat-slash"),
376 wid, sl, thick, SCM_UNDEFINED);
378 Box b (Interval (0, w + sqrt (sqr(t/s) + sqr (t))),
379 Interval (0, w * s));
381 return Molecule (b, slashnodot); // http://slashnodot.org