]> git.donarmstrong.com Git - lilypond.git/blob - lily/lookup.cc
release: 1.1.3
[lilypond.git] / lily / lookup.cc
1 /*
2   lookup.cc -- implement simple Lookup methods.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8   Jan Nieuwenhuizen <janneke@gnu.org>
9
10   TODO
11       Read spacing info from AFMs
12       Glissando
13 */
14
15 #include "lookup.hh"
16 #include "debug.hh"
17 #include "dimensions.hh"
18 #include "symtable.hh"
19 #include "scalar.hh"
20 #include "paper-def.hh"
21 #include "string-convert.hh"
22 #include "main.hh"
23 #include "lily-guile.hh"
24
25
26 Lookup::Lookup ()
27 {
28   paper_l_ = 0;
29   symtables_p_ = new Symtables;
30   afm_p_ =0;
31 }
32
33 Lookup::Lookup (Lookup const& s)
34 {
35   font_ = s.font_;
36   font_path_ = s.font_path_;
37   paper_l_ = s.paper_l_;
38   symtables_p_ = new Symtables (*s.symtables_p_);
39   afm_p_ = 0;
40 }
41
42 Lookup::Lookup (Symtables const& s)
43 {
44   font_ = s.font_;
45   font_path_ = s.font_path_;
46   paper_l_ = 0;
47   symtables_p_ = new Symtables (s);
48   afm_p_ = 0;
49 }
50
51 Lookup::~Lookup ()
52 {
53   delete afm_p_;
54   delete symtables_p_;
55 }
56
57 Molecule
58 Lookup::accidental (int j, bool cautionary) const
59 {
60   Molecule m(afm_find (String ("accidentals") + String ("-") + to_str (j)));
61   if (cautionary) 
62     {
63       m.add_at_edge(X_AXIS, LEFT, 
64                     Molecule(afm_find (String ("accidentals") + String ("-("))))
65 ;
66       m.add_at_edge(X_AXIS, RIGHT, 
67                     Molecule(afm_find (String ("accidentals") + String ("-)"))))
68 ;
69     }
70   return m;
71 }
72
73 void
74 Lookup::add (String s, Symtable*p)
75 {
76   symtables_p_->add (s, p);
77 }
78
79 Atom
80 Lookup::afm_find (String s, bool warn) const
81 {
82   if (!afm_p_)
83     {
84       *mlog << "[" << font_path_;
85       ( (Lookup*)this)->afm_p_ = new Adobe_font_metric (read_afm (font_path_));
86       *mlog << "]" << flush ;
87       DOUT << this->afm_p_->str ();
88     }
89   Adobe_font_char_metric m = afm_p_->find_char (s, warn);
90
91   Atom a;
92   if (m.code () < 0)
93     return a;
94   
95   a.dim_ = m.B_;
96   a.dim_[X_AXIS] *= 1 / 1000.0;
97   a.dim_[Y_AXIS] *= 1 / 1000.0;
98   Array<Real> arr;
99   arr.push (m.code ());
100   a.lambda_ =  (lambda_scm ("char", arr));
101   a.str_ = "afm_find: " + s;
102   a.font_ = font_;
103   return a;
104 }
105
106 Atom
107 Lookup::ball (int j) const
108 {
109   if (j > 2)
110     j = 2;
111
112   return afm_find (String ("balls") + String ("-") + to_str (j));
113 }
114
115 Atom
116 Lookup::bar (String str, Real h) const
117 {
118   Array<Real> arr;
119   arr.push (h);
120   Atom a = (*symtables_p_) ("bars")->lookup (str);
121   a.lambda_ =  (lambda_scm (a.str_, arr));
122   a.str_ = "bar";
123   a.dim_.y () = Interval (-h/2, h/2);
124   a.font_ = font_;
125   return a;
126 }
127
128 Atom 
129 Lookup::beam (Real slope, Real width, Real thick) const
130 {
131   Real height = slope * width; 
132   Real min_y = (0 <? height) - thick/2;
133   Real max_y = (0 >? height) + thick/2;
134
135   Array<Real> arr;
136   arr.push (width);
137   arr.push (slope);
138   arr.push (thick);
139
140   Atom a;
141   a.lambda_ =  (lambda_scm ("beam", arr));
142   a.str_ = "beam";
143   a.dim_[X_AXIS] = Interval (0, width);
144   a.dim_[Y_AXIS] = Interval (min_y, max_y);
145   return a;
146 }
147
148 Atom
149 Lookup::clef (String st) const
150 {
151   return afm_find (String ("clefs") + String ("-") + st);
152 }
153
154 SCM
155 offset2scm (Offset o)
156 {
157   return gh_list (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]), SCM_UNDEFINED);
158 }
159
160 Atom
161 Lookup::dashed_slur (Array<Offset> controls, Real thick, Real dash) const
162 {
163   assert (controls.size () == 8);
164   Offset d = controls[3] - controls[0];
165   
166   Real dx = d[X_AXIS];
167   Real dy = d[Y_AXIS];
168
169   Atom a;
170   a.font_ = font_;
171   a.dim_[X_AXIS] = Interval (0, dx);
172   a.dim_[Y_AXIS] = Interval (0 <? dy,  0 >? dy);
173
174   SCM sc[4];
175   for (int i=0; i<  4; i++)
176     {
177       sc[i] =  offset2scm (controls[i]);
178     }
179
180   // (lambda (o) (dashed-slur o thick dash '(stuff))
181   a.lambda_ = gh_list (gh_append3 (ly_lambda_o (),
182                                   ly_func_o ("dashed-slur"),
183                                   gh_list (gh_double2scm (thick),
184                                            gh_double2scm (dash),
185                                            ly_quote_scm (gh_list (sc[0], sc[1], sc[2], sc[3], SCM_UNDEFINED)),
186                                            SCM_UNDEFINED)
187                                   ), SCM_UNDEFINED);
188
189   a.str_ = "dashed_slur";
190   return a;
191 }
192
193 Atom
194 Lookup::dots () const
195 {
196   return afm_find (String ("dots") + String ("-") + String ("dot"));
197 }
198
199 Atom
200 Lookup::dynamic (String st) const
201 {
202   return (*symtables_p_) ("dynamics")->lookup (st);
203 }
204
205 Atom
206 Lookup::fill (Box b) const
207 {
208   Atom a;
209   a.dim_ = b;
210   return a;
211 }
212
213 Atom
214 Lookup::flag (int j, Direction d) const
215 {
216   char c = (d == UP) ? 'u' : 'd';
217   Atom a = afm_find (String ("flags") + String ("-") + to_str (c) + to_str (j));
218   return a;
219 }
220
221 void
222 Lookup::print () const
223 {
224 #ifndef NPRINT
225   DOUT << "Lookup {\n";
226   symtables_p_->print ();
227   DOUT << "}\n";
228 #endif
229 }
230
231 Atom
232 Lookup::rest (int j, bool o) const
233 {
234    return afm_find (String ("rests")
235                     + String ("-") + to_str (j) + (o ? "o" : ""));
236 }
237
238 Atom
239 Lookup::rule_symbol (Real height, Real width) const
240 {
241   Atom a = (*symtables_p_) ("param")->lookup ("rule");
242   Array<Real> arr;
243   arr.push (height);
244   arr.push (width);
245   a.lambda_ = (lambda_scm (a.str_, arr));
246   a.str_ = "rule_symbol";
247   a.dim_.x () = Interval (0, width);
248   a.dim_.y () = Interval (0, height);
249   return a;
250 }
251
252 Atom
253 Lookup::script (String str) const
254 {
255   return afm_find (String ("scripts") + String ("-") + str);
256 }
257
258 Atom
259 Lookup::special_time_signature (String s, Array<int> arr) const
260 {
261   // First guess: s contains only the signature style
262   assert (arr.size () >1);
263   String symbolname = "timesig-" + s + to_str (arr[0]) + "/" + to_str (arr[1]);
264   
265   Atom a = afm_find (symbolname, false);
266   if (!a.empty ()) 
267     return a;
268
269   // Second guess: s contains the full signature name
270   a = afm_find ("timesig-"+s, false);
271   if (!a.empty ()) 
272     return a;
273
274   // Resort to default layout with numbers
275   return time_signature (arr);
276 }
277
278 Atom
279 Lookup::stem (Real y1, Real y2) const
280 {
281   if (y1 > y2)
282     {
283       Real t = y1;
284       y1 = y2;
285       y2 = t;
286     }
287   Atom a;
288
289   a.dim_.x () = Interval (0,0);
290   a.dim_.y () = Interval (y1,y2);
291
292   Array<Real> arr;
293
294   Real stem_width = paper_l_->get_var ("stemthickness");
295   arr.push (-stem_width /2);
296   arr.push (stem_width);
297   arr.push (y2);
298   arr.push (-y1);
299
300   a.lambda_ = (lambda_scm ("stem", arr));
301   a.str_ = "stem";
302   a.font_ = font_;
303   return a;
304 }
305
306 Atom
307 Lookup::streepje (int type) const
308 {
309   if (type > 2)
310     type = 2;
311
312   return  afm_find ("balls" + String ("-") +to_str (type) + "l");
313 }
314
315 Atom
316 Lookup::text (String style, String text) const
317 {
318   Array<Scalar> arr;
319
320   arr.push (text);
321   Atom a =  (*symtables_p_) ("style")->lookup (style);
322   a.lambda_ = lambda_scm (a.str_, arr);
323   a.str_ = "text";
324   a.font_ = font_;
325   return a;
326    
327 }
328   
329
330 Atom
331 Lookup::time_signature (Array<int> a) const
332 {
333   Atom s ((*symtables_p_) ("param")->lookup ("time_signature"));
334   s.lambda_ =  (lambda_scm (s.str_, a));
335
336   return s;
337 }
338
339 /*
340   should be handled via Tex_ code and Lookup::bar ()
341  */
342 Atom
343 Lookup::vbrace (Real &y) const
344 {
345   Atom a = (*symtables_p_) ("param")->lookup ( "brace");
346   Interval ydims = a.dim_[Y_AXIS];
347   Real min_y = ydims[LEFT];
348   Real max_y = ydims[RIGHT];
349   Real step = 1.0 PT;
350  
351   if (y < min_y)
352     {
353       warning (_ ("piano brace") 
354                + " " + _ ("too small") +  " (" + print_dimen (y) + ")");
355       y = min_y;
356     }
357   if (y > max_y)
358     {
359       warning (_ ("piano brace")
360                + " " + _ ("too big") + " (" + print_dimen (y) + ")");
361       y = max_y;
362     }
363
364   
365   int idx = int (rint ( (y- min_y)/step)) + 1;
366   
367   Array<Real> arr;
368   arr.push (idx);
369   a.lambda_ = (lambda_scm (a.str_, arr));
370   a.str_ = "brace";
371   a.dim_[Y_AXIS] = Interval (-y/2,y/2);
372   a.font_ = font_;
373   return a;
374 }
375
376 Atom
377 Lookup::hairpin (Real width, bool decresc, bool continued) const
378 {
379   Atom a;  
380   Real height = paper_l_->staffheight_f () / 6;
381   String ps;
382   ps += to_str (width) + " " 
383     + to_str (height) + " " 
384     + to_str (continued ? height/2 : 0) + 
385     + " draw_"  + String (decresc ? "de" : "") + "cresc\n";
386   a.str_ = ps;
387   a.dim_.x () = Interval (0, width);
388   a.dim_.y () = Interval (-2*height, 2*height);
389   a.font_ = font_;
390   return a;
391 }
392
393 Atom
394 Lookup::plet (Real dy , Real dx, Direction dir) const
395 {
396   String ps;
397     
398   ps += String_convert::double_str (dx) + " " 
399     + String_convert::double_str (dy) + " "
400     + String_convert::int_str ( (int)dir) +
401     " draw_plet ";
402
403   Atom a;
404   a.str_ = ps;
405   return a;
406 }
407
408 Atom
409 Lookup::slur (Array<Offset> controls) const
410 {
411   assert (controls.size () == 8);
412
413   String ps;
414   
415   Real dx = controls[3].x () - controls[0].x ();
416   Real dy = controls[3].y () - controls[0].y ();
417   Atom a;
418
419   SCM scontrols [8];
420   int indices[] = {5,6,7,4,1,2,3,0};
421
422   for (int i= 0; i < 8; i++)
423     scontrols[i] = offset2scm (controls[indices[i]]);
424
425
426   a.lambda_ =
427     gh_append2 (ly_lambda_o (),
428                 gh_list (gh_append2 (ly_func_o ("slur"),
429                                      gh_list (ly_quote_scm (gh_list (scontrols[0],
430                                                                      scontrols[1],
431                                                                      scontrols[2],
432                                                                      scontrols[3],
433                                                                      scontrols[4],
434                                                                      scontrols[5],
435                                                                      scontrols[6],
436                                                                      scontrols[7],
437                                                                      SCM_UNDEFINED)),
438                                               SCM_UNDEFINED)
439                                      ),
440                          SCM_UNDEFINED)
441                 );
442
443
444   a.str_ = "slur";
445
446   a.dim_[X_AXIS] = Interval (0, dx);
447   a.dim_[Y_AXIS] = Interval (0 <? dy,  0 >? dy);
448   a.font_ = font_;
449   return a;
450 }
451
452 Atom
453 Lookup::vbracket (Real &y) const
454 {
455   Atom a;
456   Real min_y = paper_l_->staffheight_f ();
457   if (y < min_y)
458     {
459       warning (_ ("bracket")
460                + " " + _ ("too small") +  " (" + print_dimen (y) + ")");
461       //      y = min_y;
462     }
463   Array<Real> arr;
464   arr.push (y);
465   a.lambda_ =  (lambda_scm ("bracket", arr));
466   a.str_ = "vbracket";
467   a.dim_[Y_AXIS] = Interval (-y/2,y/2);
468   a.dim_[X_AXIS] = Interval (0,4 PT);
469   return a;
470 }
471
472