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