]> git.donarmstrong.com Git - lilypond.git/blob - lily/lookup.cc
release: 1.1.42
[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--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8   Jan Nieuwenhuizen <janneke@gnu.org>
9
10   TODO
11       Glissando
12 */
13
14 #include <ctype.h>
15 #include "lookup.hh"
16 #include "debug.hh"
17 #include "dimensions.hh"
18 #include "scalar.hh"
19 #include "paper-def.hh"
20 #include "string-convert.hh"
21 #include "file-path.hh"
22 #include "main.hh"
23 #include "lily-guile.hh"
24 #include "all-fonts.hh"
25 #include "afm.hh"
26 #include "scope.hh"
27 #include "molecule.hh"
28 #include "atom.hh"
29 #include "lily-guile.hh"
30
31
32 Lookup::Lookup ()
33 {
34   paper_l_ = 0;
35   afm_l_ = 0;  
36 }
37
38 Lookup::Lookup (Lookup const& s)
39 {
40   font_name_ = s.font_name_;
41   paper_l_ = 0;
42   afm_l_ = 0;  
43 }
44
45
46 /*
47   build a ledger line for small pieces.
48  */
49 Molecule
50 Lookup::ledger_line (Interval xwid) const
51 {
52   Drul_array<Molecule> endings;
53   endings[LEFT] = afm_find ("noteheads-ledgerending");
54   Molecule * e = &endings[LEFT];
55   endings[RIGHT] = *e;
56   
57   Real thick = e->dim_[Y_AXIS].length();
58   Real len = e->dim_[X_AXIS].length () - thick;
59
60   Molecule total;
61   Direction d = LEFT;
62   do {
63     endings[d].translate_axis (xwid[d] - endings[d].dim_[X_AXIS][d], X_AXIS);
64     total.add_molecule (endings[d]);    
65   } while ((flip(&d)) != LEFT);
66
67   Real xpos = xwid [LEFT] + len;
68
69   while (xpos + len + thick /2 <= xwid[RIGHT])
70     {
71       e->translate_axis (len, X_AXIS);
72       total.add_molecule (*e);
73       xpos += len;
74     }
75
76   return total;
77 }
78
79
80 Molecule
81 Lookup::accidental (int j, bool cautionary) const
82 {
83   Molecule m(afm_find (String ("accidentals-") + to_str (j)));
84   if (cautionary) 
85     {
86       Molecule open = afm_find (String ("accidentals-("));
87       Molecule close = afm_find (String ("accidentals-)"));
88       m.add_at_edge(X_AXIS, LEFT, Molecule(open), 0);
89       m.add_at_edge(X_AXIS, RIGHT, Molecule(close), 0);
90     }
91   return m;
92 }
93
94
95
96 Molecule
97 Lookup::afm_find (String s, bool warn) const
98 {
99   if (!afm_l_)      
100     {
101       Lookup * me =     (Lookup*)(this);
102       me->afm_l_ = all_fonts_global_p->find_afm (font_name_);
103       if (!me->afm_l_)
104         {
105           warning (_f("Can't open `%s'\n", font_name_));
106           warning (_f("Search path %s\n", global_path.str ().ch_C()));
107           error (_f("Aborting"));
108         }
109     }
110   Adobe_font_char_metric cm = afm_l_->find_char (s, warn);
111   Molecule m;
112   if (cm.code () < 0)
113     {
114       /*
115         don't want people relying on this kind of dimension. 
116        */
117       m.set_empty (false);
118       return m;
119     }
120   
121   Atom at (gh_list (char_scm_sym,
122                     gh_int2scm (cm.code ()),
123                     SCM_UNDEFINED));
124   at.font_ = ly_symbol (font_name_.ch_C());
125   m.dim_ = cm.dimensions();
126   m.add_atom (&at);
127   return m;
128 }
129
130 Molecule
131 Lookup::notehead (int j, String type) const
132 {
133   if (j > 2)
134     j = 2;
135
136   return afm_find (String ("noteheads-") + to_str (j) + type);
137 }
138
139 Molecule
140 Lookup::simple_bar (String type, Real h) const
141 {
142   SCM thick = ly_symbol ("barthick_" + type);
143   Real w = 0.0;
144   
145   if (paper_l_->scope_p_->elem_b (thick))
146     {
147       w = paper_l_->get_realvar (thick);
148     }
149   else
150     {
151       programming_error ("No bar thickness set ! ");
152       w = 1 PT;
153     }
154   return filledbox (Box (Interval(0,w), Interval(-h/2, h/2)));
155 }
156
157   
158 Molecule
159 Lookup::bar (String str, Real h) const
160 {
161   if (str == "[")
162     return staff_bracket (h);
163   else if (str == "{")
164     return staff_brace (h);
165   
166   Real kern = paper_l_->get_var ("bar_kern");
167   Real thinkern = paper_l_->get_var ("bar_thinkern");  
168   Molecule thin = simple_bar ("thin", h);
169   Molecule thick = simple_bar ("thick", h);
170   Molecule colon = afm_find ("dots-repeatcolon");  
171
172   Molecule m;
173   
174   if (str == "")
175     {
176       return fill (Box (Interval(0, 0), Interval (-h/2, h/2)));
177     }
178   if (str == "scorepostbreak")
179     {
180       return simple_bar ("score", h);
181     }
182   else if (str == "|")
183     {
184       return thin;
185     }
186   else if (str == "|.")
187     {
188       m.add_at_edge (X_AXIS, LEFT, thick, 0);      
189       m.add_at_edge (X_AXIS, LEFT, thin, kern);
190     }
191   else if (str == ".|")
192     {
193       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
194       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
195     }
196   else if (str == ":|")
197     {
198       m.add_at_edge (X_AXIS, LEFT, thick, 0);
199       m.add_at_edge (X_AXIS, LEFT, thin, kern);
200       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
201     }
202   else if (str == "|:")
203     {
204       m.add_at_edge (X_AXIS, RIGHT, thick, 0);
205       m.add_at_edge (X_AXIS, RIGHT, thin, kern);
206       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
207     }
208   else if (str == ":|:")
209     {
210       m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
211       m.add_at_edge (X_AXIS, LEFT, colon, kern);      
212       m.add_at_edge (X_AXIS, RIGHT, thick, kern);
213       m.add_at_edge (X_AXIS, RIGHT, colon, kern);      
214     }
215   else if (str == ".|.")
216     {
217       m.add_at_edge (X_AXIS, LEFT, thick, thinkern);
218       m.add_at_edge (X_AXIS, RIGHT, thick, kern);      
219     }
220   else if (str == "||")
221     {
222       m.add_at_edge (X_AXIS, RIGHT, thin, 0);
223       m.add_at_edge (X_AXIS, RIGHT, thin, thinkern);      
224     }
225
226   return m;
227 }
228
229 Molecule 
230 Lookup::beam (Real slope, Real width, Real thick) const
231 {
232   Real height = slope * width; 
233   Real min_y = (0 <? height) - thick/2;
234   Real max_y = (0 >? height) + thick/2;
235
236   
237   Molecule m;
238   Atom at
239      (gh_list (beam_scm_sym,
240                                 gh_double2scm (width),
241                                 gh_double2scm (slope),
242                                 gh_double2scm (thick),
243                                 SCM_UNDEFINED));
244
245   m.dim_[X_AXIS] = Interval (0, width);
246   m.dim_[Y_AXIS] = Interval (min_y, max_y);
247   m.add_atom (&at);
248   return m;
249 }
250
251 Molecule
252 Lookup::clef (String st) const
253 {
254   return afm_find (String ("clefs-" + st));
255 }
256
257 SCM
258 offset2scm (Offset o)
259 {
260   return gh_list (gh_double2scm (o[X_AXIS]), gh_double2scm(o[Y_AXIS]),
261                   SCM_UNDEFINED);
262 }
263
264 Molecule
265 Lookup::dashed_slur (Array<Offset> controls, Real thick, Real dash) const
266 {
267   assert (controls.size () == 8);
268   Offset d = controls[3] - controls[0];
269   
270   Real dx = d[X_AXIS];
271   Real dy = d[Y_AXIS];
272
273   Molecule m;
274
275
276   m.dim_[X_AXIS] = Interval (0, dx);
277   m.dim_[Y_AXIS] = Interval (0 <? dy, 0 >? dy);
278
279   SCM sc[4];
280   for (int i=0; i<  4; i++)
281     {
282       sc[i] =  offset2scm (controls[i]);
283     }
284
285   Atom at
286     (gh_list (ly_symbol ("dashed-slur"),
287               gh_double2scm (thick), 
288               gh_double2scm (dash),
289               ly_quote_scm (array_to_list (sc, 4)),
290               SCM_UNDEFINED));
291   
292   
293   m.add_atom (&at);
294   return m;
295 }
296
297 Molecule
298 Lookup::dots () const
299 {
300   return afm_find (String ("dots-dot"));
301 }
302
303
304
305 Molecule
306 Lookup::fill (Box b) const
307 {
308   Molecule m;
309   m.dim_ = b;
310   return m;
311 }
312
313 Molecule
314 Lookup::flag (int j, Direction d) const
315 {
316   char c = (d == UP) ? 'u' : 'd';
317   return  afm_find (String ("flags-") + to_str (c) + to_str (j));
318 }
319
320 Molecule
321 Lookup::rest (int j, bool o, String style) const
322 {
323   return afm_find (String ("rests-") + to_str (j) + (o ? "o" : "") + style);
324 }
325
326
327 Molecule
328 Lookup::special_time_signature (String s, int n, int d) const
329 {
330   // First guess: s contains only the signature style
331   String symbolname = "timesig-" + s + to_str (n) + "/" + to_str (d);
332   
333   Molecule m = afm_find (symbolname, false);
334   if (!m.empty_b()) 
335     return m;
336
337   // Second guess: s contains the full signature name
338   m = afm_find ("timesig-"+s, false);
339   if (!m.empty_b ()) 
340     return m;
341
342   // Resort to default layout with numbers
343   return time_signature (n,d);
344 }
345
346 Molecule
347 Lookup::filledbox (Box b ) const
348 {
349   Molecule m;
350   
351   Atom at  (gh_list (filledbox_scm_sym,
352                      gh_double2scm (-b[X_AXIS][LEFT]),
353                      gh_double2scm (b[X_AXIS][RIGHT]),                 
354                      gh_double2scm (-b[Y_AXIS][DOWN]),
355                      gh_double2scm (b[Y_AXIS][UP]),                    
356                      SCM_UNDEFINED));
357
358   m.dim_ = b;
359   m.add_atom (&at);
360   return m;
361 }
362
363 Molecule
364 Lookup::stem (Real y1, Real y2) const
365 {
366   if (y1 > y2)
367     {
368       Real t = y1;
369       y1 = y2;
370       y2 = t;
371     }
372   Real stem_width = paper_l_->get_var ("stemthickness");
373   return filledbox (Box (Interval (-stem_width/2,stem_width/2),
374                          Interval (y1, y2)));
375 }
376
377
378
379 /**
380    Magnification steps.  These are powers of 1.2. The numbers are
381  taken from Knuth's plain.tex: */
382 static Real mag_steps[] = {1, 1, 1.200, 1.440, 1.7280,  2.074, 2.488};
383
384
385
386 Molecule
387 Lookup::text (String style, String text) const
388 {
389   Molecule m;
390   if (style.empty_b ())
391     style = "roman";
392   
393   int font_mag = 1;
394   Real font_h = paper_l_->get_var ("font_normal");
395   if (paper_l_->scope_p_->elem_b ("font_" + style))
396     {
397       font_h = paper_l_->get_var ("font_" + style);
398     }
399    
400   if (paper_l_->scope_p_->elem_b ("magnification_" + style))
401     {
402       font_mag = (int)paper_l_->get_var ("magnification_" + style);
403     }
404
405   /*
406     UGH.
407   */
408   SCM l = gh_eval_str (("(style-to-cmr \"" + style + "\")").ch_C());
409   if (l != SCM_BOOL_F)
410     {
411       style = ly_scm2string (SCM_CDR(l)) +to_str  ((int)font_h);
412     }
413
414   Real w = 0;
415   Interval ydims (0,0);
416
417   Font_metric* afm_l = all_fonts_global_p->find_font (style);
418   DOUT << "\nChars: ";
419   
420   for (int i = 0; i < text.length_i (); i++) 
421     {
422       if (text[i]=='\\')
423         for (i++; (i < text.length_i ()) && isalpha(text[i]); i++)
424           ;
425       else
426         {
427           Character_metric *c = afm_l->get_char ((unsigned char)text[i],false);
428
429           w += c->dimensions()[X_AXIS].length ();
430           ydims.unite (c->dimensions()[Y_AXIS]);
431         }
432     }
433
434   if (font_mag > 1 && font_mag < 7 )
435     {
436       /* UGH  */ 
437       style = style + String(" scaled \\magstep ") + to_str (font_mag);
438       w *= mag_steps[font_mag];
439       ydims *= mag_steps[font_mag];
440     }
441
442   DOUT << "\n" << to_str (w) << "\n";
443   m.dim_.x () = Interval (0, w);
444   m.dim_.y () = ydims;
445
446   
447   Atom at  (gh_list (text_scm_sym,
448                      gh_str02scm (text.ch_C()),
449                      SCM_UNDEFINED));
450   at.font_ = ly_symbol (style);
451   
452   m.add_atom (&at);
453   return m;
454 }
455   
456
457 Molecule
458 Lookup::time_signature (int num, int den) const
459 {
460   String sty = "number";
461   Molecule n (text (sty, to_str (num)));
462   Molecule d (text (sty, to_str (den)));
463   n.align_to (X_AXIS, CENTER);
464   d.align_to (X_AXIS, CENTER);
465   Molecule m;
466   if (den)
467     {
468       m.add_at_edge (Y_AXIS, UP, n, 0.0);
469       m.add_at_edge (Y_AXIS, DOWN, d, 0.0);
470     }
471   else
472     {
473       m = n;
474       m.align_to (Y_AXIS, CENTER);
475     }
476   return m;
477 }
478
479 Molecule
480 Lookup::staff_brace (Real y) const
481 {
482   Molecule m;
483   
484   Atom at  (gh_list (pianobrace_scm_sym,
485                      gh_double2scm (y),
486                      SCM_UNDEFINED
487                      ));
488   
489   m.dim_[Y_AXIS] = Interval (-y/2,y/2);
490   m.dim_[X_AXIS] = Interval (0,0);
491   m.add_atom (&at);
492   return m;
493 }
494
495 Molecule
496 Lookup::hairpin (Real width, bool decresc, bool continued) const
497 {
498   Molecule m;   
499   Real height = paper_l_->staffheight_f () / 6;
500
501   String hairpin = String (decresc ? "de" : "") + "crescendo";
502   Atom at  (gh_list (ly_symbol (hairpin),
503                      gh_double2scm (width),
504                      gh_double2scm (height),
505                      gh_double2scm (continued ? height/2 : 0.0),
506                      SCM_UNDEFINED));
507   m.dim_.x () = Interval (0, width);
508   m.dim_.y () = Interval (-2*height, 2*height);
509
510   m.add_atom (&at);
511   return m;
512 }
513
514 Molecule
515 Lookup::plet (Real dy , Real dx, Direction dir) const
516 {
517   Molecule m;
518   SCM thick = tuplet_thick_scm_sym;
519   Real t = 0.1 PT;
520   if (paper_l_->scope_p_->elem_b (thick))
521     {
522       t = paper_l_->get_realvar (thick);
523     }
524
525   Real interline_f = paper_l_->get_realvar (interline_scm_sym);
526   Atom at  (gh_list(tuplet_scm_sym,
527                     gh_double2scm (interline_f), 
528                     gh_double2scm (dx),
529                     gh_double2scm (dy),
530                     gh_double2scm (t),
531                     gh_int2scm (dir),
532                     SCM_UNDEFINED));
533   m.add_atom (&at);
534
535   return m;
536 }
537
538 /*
539   Make a smooth curve along the points 
540  */
541 Molecule
542 Lookup::slur (Array<Offset> controls) const
543 {
544   Offset  delta_off = controls[3]- controls[0];
545   Molecule m; 
546
547   SCM scontrols [8];
548   int indices[] = {5,6,7,4,1,2,3,0};
549
550   for (int i= 0; i < 8; i++)
551     scontrols[i] = offset2scm (controls[indices[i]]);
552
553
554   Atom at  (gh_list (ly_symbol ("bezier-sandwich"),
555                      ly_quote_scm (array_to_list (scontrols, 8)),
556                      SCM_UNDEFINED));
557
558   m.dim_[X_AXIS] = Interval (0, delta_off[X_AXIS]);
559   m.dim_[Y_AXIS] = Interval (0 <? delta_off[Y_AXIS], 0 >? delta_off[Y_AXIS]);
560   m.add_atom (&at);
561   return m;
562 }
563
564 Molecule
565 Lookup::staff_bracket (Real y) const
566 {
567   Molecule m; 
568   Atom at  ( gh_list (bracket_scm_sym,
569                       gh_double2scm (y),
570                       SCM_UNDEFINED));
571   m.add_atom (&at);                              
572   m.dim_[Y_AXIS] = Interval (-y/2,y/2);
573   m.dim_[X_AXIS] = Interval (0,4 PT);
574
575   m.translate_axis (- 4. / 3. * m.dim_[X_AXIS].length (), X_AXIS);
576   return m;
577 }
578
579 Molecule
580 Lookup::volta (Real w, bool last_b) const
581 {
582   Molecule m; 
583   SCM thick = volta_thick_scm_sym;
584   Real t = 0.1 PT;
585   if (paper_l_->scope_p_->elem_b (thick))
586     {
587       t = paper_l_->get_realvar (thick);
588     }
589   Atom at  (gh_list (volta_scm_sym,
590                      gh_double2scm (w),
591                      gh_double2scm (t),
592                      gh_int2scm (last_b),
593                      SCM_UNDEFINED));
594
595   Real interline_f = paper_l_->get_realvar (interline_scm_sym);
596
597   m.dim_[Y_AXIS] = Interval (-interline_f, interline_f);
598   m.dim_[X_AXIS] = Interval (0, w);
599
600   m.add_atom (&at);
601   return m;
602 }
603
604 Molecule
605 Lookup::accordion (SCM s) const
606 {
607   Molecule m;
608   String sym = ly_scm2string(SCM_CAR(s));
609   String reg = ly_scm2string(SCM_CAR(SCM_CDR(s)));
610   Real interline_f = paper_l_->get_realvar(interline_scm_sym);
611   if (sym == "Discant")
612     {
613       Molecule r = afm_find("scripts-accDiscant");
614       m.add_molecule(r);
615       if (reg.left_str(1) == "F")
616         {
617           Molecule d = afm_find("scripts-accDot");
618           d.translate_axis(interline_f * 2.5 PT, Y_AXIS);
619           m.add_molecule(d);
620           reg = reg.right_str(reg.length_i()-1);
621         }
622       int eflag = 0x00;
623       if (reg.left_str(3) == "EEE")
624         {
625           eflag = 0x07;
626           reg = reg.right_str(reg.length_i()-3);
627         }
628       else if (reg.left_str(2) == "EE")
629         {
630           eflag = 0x05;
631           reg = reg.right_str(reg.length_i()-2);
632         }
633       else if (reg.left_str(2) == "Eh")
634         {
635           eflag = 0x04;
636           reg = reg.right_str(reg.length_i()-2);
637         }
638       else if (reg.left_str(1) == "E")
639         {
640           eflag = 0x02;
641           reg = reg.right_str(reg.length_i()-1);
642         }
643       if (eflag & 0x02)
644         {
645           Molecule d = afm_find("scripts-accDot");
646           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
647           m.add_molecule(d);
648         }
649       if (eflag & 0x04)
650         {
651           Molecule d = afm_find("scripts-accDot");
652           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
653           d.translate_axis(0.8 * interline_f PT, X_AXIS);
654           m.add_molecule(d);
655         }
656       if (eflag & 0x01)
657         {
658           Molecule d = afm_find("scripts-accDot");
659           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
660           d.translate_axis(-0.8 * interline_f PT, X_AXIS);
661           m.add_molecule(d);
662         }
663       if (reg.left_str(2) == "SS")
664         {
665           Molecule d = afm_find("scripts-accDot");
666           d.translate_axis(0.5 * interline_f PT, Y_AXIS);
667           d.translate_axis(0.4 * interline_f PT, X_AXIS);
668           m.add_molecule(d);
669           d.translate_axis(-0.8 * interline_f PT, X_AXIS);
670           m.add_molecule(d);
671           reg = reg.right_str(reg.length_i()-2);
672         }
673       if (reg.left_str(1) == "S")
674         {
675           Molecule d = afm_find("scripts-accDot");
676           d.translate_axis(0.5 * interline_f PT, Y_AXIS);
677           m.add_molecule(d);
678           reg = reg.right_str(reg.length_i()-1);
679         }
680     }
681   else if (sym == "Freebase")
682     {
683       Molecule r = afm_find("scripts-accFreebase");
684       m.add_molecule(r);
685       if (reg.left_str(1) == "F")
686         {
687           Molecule d = afm_find("scripts-accDot");
688           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
689           m.add_molecule(d);
690           reg = reg.right_str(reg.length_i()-1);
691         }
692       if (reg == "E")
693         {
694           Molecule d = afm_find("scripts-accDot");
695           d.translate_axis(interline_f * 0.5 PT, Y_AXIS);
696           m.add_molecule(d);
697         }
698     }
699   else if (sym == "Bayanbase")
700     {
701       Molecule r = afm_find("scripts-accBayanbase");
702       m.add_molecule(r);
703       if (reg.left_str(1) == "T")
704         {
705           Molecule d = afm_find("scripts-accDot");
706           d.translate_axis(interline_f * 2.5 PT, Y_AXIS);
707           m.add_molecule(d);
708           reg = reg.right_str(reg.length_i()-1);
709         }
710       /* include 4' reed just for completeness. You don't want to use this. */
711       if (reg.left_str(1) == "F")
712         {
713           Molecule d = afm_find("scripts-accDot");
714           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
715           m.add_molecule(d);
716           reg = reg.right_str(reg.length_i()-1);
717         }
718       if (reg.left_str(2) == "EE")
719         {
720           Molecule d = afm_find("scripts-accDot");
721           d.translate_axis(interline_f * 0.5 PT, Y_AXIS);
722           d.translate_axis(0.4 * interline_f PT, X_AXIS);
723           m.add_molecule(d);
724           d.translate_axis(-0.8 * interline_f PT, X_AXIS);
725           m.add_molecule(d);
726           reg = reg.right_str(reg.length_i()-2);
727         }
728       if (reg.left_str(1) == "E")
729         {
730           Molecule d = afm_find("scripts-accDot");
731           d.translate_axis(interline_f * 0.5 PT, Y_AXIS);
732           m.add_molecule(d);
733           reg = reg.right_str(reg.length_i()-1);
734         }
735     }
736   else if (sym == "Stdbase")
737     {
738       Molecule r = afm_find("scripts-accStdbase");
739       m.add_molecule(r);
740       if (reg.left_str(1) == "T")
741         {
742           Molecule d = afm_find("scripts-accDot");
743           d.translate_axis(interline_f * 3.5 PT, Y_AXIS);
744           m.add_molecule(d);
745           reg = reg.right_str(reg.length_i()-1);
746         }
747       if (reg.left_str(1) == "F")
748         {
749           Molecule d = afm_find("scripts-accDot");
750           d.translate_axis(interline_f * 2.5 PT, Y_AXIS);
751           m.add_molecule(d);
752           reg = reg.right_str(reg.length_i()-1);
753         }
754       if (reg.left_str(1) == "M")
755         {
756           Molecule d = afm_find("scripts-accDot");
757           d.translate_axis(interline_f * 2 PT, Y_AXIS);
758           d.translate_axis(interline_f PT, X_AXIS);
759           m.add_molecule(d);
760           reg = reg.right_str(reg.length_i()-1);
761         }
762       if (reg.left_str(1) == "E")
763         {
764           Molecule d = afm_find("scripts-accDot");
765           d.translate_axis(interline_f * 1.5 PT, Y_AXIS);
766           m.add_molecule(d);
767           reg = reg.right_str(reg.length_i()-1);
768         }
769       if (reg.left_str(1) == "S")
770         {
771           Molecule d = afm_find("scripts-accDot");
772           d.translate_axis(interline_f * 0.5 PT, Y_AXIS);
773           m.add_molecule(d);
774           reg = reg.right_str(reg.length_i()-1);
775         }
776     }
777   /* ugh maybe try to use regular font for S.B. and B.B and only use one font
778      for the rectangle */
779   else if (sym == "SB")
780     {
781       Molecule r = afm_find("scripts-accSB");
782       m.add_molecule(r);
783     }
784   else if (sym == "BB")
785     {
786       Molecule r = afm_find("scripts-accBB");
787       m.add_molecule(r);
788     }
789   else if (sym == "OldEE")
790     {
791       Molecule r = afm_find("scripts-accOldEE");
792       m.add_molecule(r);
793     }
794   else if (sym == "OldEES")
795     {
796       Molecule r = afm_find("scripts-accOldEES");
797       m.add_molecule(r);
798     }
799   return m;  
800 }