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