]> git.lyx.org Git - lyx.git/blob - src/mathed/math_support.C
suppress debug messages
[lyx.git] / src / mathed / math_support.C
1 #include <config.h>
2
3 #include <map>
4
5 #include "math_support.h"
6 #include "lyxfont.h"
7 #include "FontLoader.h"
8 #include "font.h"
9 #include "math_cursor.h"
10 #include "math_defs.h"
11 #include "math_inset.h"
12 #include "math_parser.h"
13 #include "Painter.h"
14 #include "debug.h"
15 #include "commandtags.h"
16
17 using std::map;
18 using std::endl;
19 using std::max;
20
21
22 bool isBinaryOp(char c, MathTextCodes type)
23 {
24         return type < LM_TC_SYMB && strchr("+-<>=/*", c);
25 }
26
27
28 ///
29 class Matrix {
30 public:
31         ///
32         Matrix(int, double, double);
33         ///
34         void transform(double &, double &);
35 private:
36         ///
37         double m_[2][2];
38 };
39
40
41 Matrix::Matrix(int code, double x, double y)
42 {
43         double const cs = (code & 1) ? 0 : (1 - code);
44         double const sn = (code & 1) ? (2 - code) : 0;
45         m_[0][0] =  cs * x;
46         m_[0][1] =  sn * x;
47         m_[1][0] = -sn * y;
48         m_[1][1] =  cs * y;
49 }
50
51
52 void Matrix::transform(double & x, double & y)
53 {
54         double xx = m_[0][0] * x + m_[0][1] * y;
55         double yy = m_[1][0] * x + m_[1][1] * y;
56         x = xx;
57         y = yy;
58 }
59
60
61 namespace {
62
63 LyXFont * MathFonts = 0;
64 bool font_available[LM_FONT_END];
65 bool font_available_initialized[LM_FONT_END];
66
67 enum MathFont {
68         FONT_IT,
69         FONT_SYMBOL,
70         FONT_SYMBOLI,
71         FONT_BF,
72         FONT_TT,
73         FONT_RM,
74         FONT_SF,
75         FONT_CMR,
76         FONT_CMSY,
77         FONT_CMM,
78         FONT_CMEX,
79         FONT_MSA,
80         FONT_MSB,
81         FONT_EUFRAK,
82         FONT_FAKEBB,
83         FONT_FAKECAL,
84         FONT_FAKEFRAK,
85         FONT_NUM
86 };
87
88 void mathed_init_fonts()
89 {
90         MathFonts = new LyXFont[FONT_NUM];
91
92         MathFonts[FONT_IT].setShape(LyXFont::ITALIC_SHAPE);
93
94         MathFonts[FONT_SYMBOL].setFamily(LyXFont::SYMBOL_FAMILY);
95
96         MathFonts[FONT_SYMBOLI].setFamily(LyXFont::SYMBOL_FAMILY);
97         MathFonts[FONT_SYMBOLI].setShape(LyXFont::ITALIC_SHAPE);
98
99         MathFonts[FONT_BF].setSeries(LyXFont::BOLD_SERIES);
100
101         MathFonts[FONT_TT].setFamily(LyXFont::TYPEWRITER_FAMILY);
102         MathFonts[FONT_RM].setFamily(LyXFont::ROMAN_FAMILY);
103         MathFonts[FONT_SF].setFamily(LyXFont::SANS_FAMILY);
104
105         MathFonts[FONT_CMR].setFamily(LyXFont::CMR_FAMILY);
106         MathFonts[FONT_CMSY].setFamily(LyXFont::CMSY_FAMILY);
107         MathFonts[FONT_CMM].setFamily(LyXFont::CMM_FAMILY);
108         MathFonts[FONT_CMEX].setFamily(LyXFont::CMEX_FAMILY);
109         MathFonts[FONT_MSA].setFamily(LyXFont::MSA_FAMILY);
110         MathFonts[FONT_MSB].setFamily(LyXFont::MSB_FAMILY);
111         MathFonts[FONT_EUFRAK].setFamily(LyXFont::EUFRAK_FAMILY);
112
113         MathFonts[FONT_FAKEBB].setFamily(LyXFont::TYPEWRITER_FAMILY);
114         MathFonts[FONT_FAKEBB].setSeries(LyXFont::BOLD_SERIES);
115
116         MathFonts[FONT_FAKECAL].setFamily(LyXFont::SANS_FAMILY);
117         MathFonts[FONT_FAKECAL].setShape(LyXFont::ITALIC_SHAPE);
118
119         MathFonts[FONT_FAKEFRAK].setFamily(LyXFont::SANS_FAMILY);
120         MathFonts[FONT_FAKEFRAK].setSeries(LyXFont::BOLD_SERIES);
121
122         for (int i = 0; i < LM_FONT_END; ++i)
123                 font_available_initialized[i] = false;
124 }
125
126
127 LyXFont const & whichFontBaseIntern(MathTextCodes type)
128 {
129         if (!MathFonts)
130                 mathed_init_fonts();
131
132         switch (type) {
133         case LM_TC_SYMB:        
134         case LM_TC_BOLDSYMB:    
135                 return MathFonts[FONT_SYMBOLI];
136
137         case LM_TC_VAR:
138         case LM_TC_IT:
139                 return MathFonts[FONT_IT];
140
141         case LM_TC_BF:
142                 return MathFonts[FONT_BF];
143
144         case LM_TC_BB:
145                 return MathFonts[FONT_MSB];
146
147         case LM_TC_CAL:
148                 return MathFonts[FONT_CMSY];
149
150         case LM_TC_TT:
151                 return MathFonts[FONT_TT];
152
153         case LM_TC_BOX:
154         case LM_TC_TEXTRM:
155         case LM_TC_CONST:
156         case LM_TC_TEX:
157         case LM_TC_RM:
158                 return MathFonts[FONT_RM];
159
160         case LM_TC_SF:
161                 return MathFonts[FONT_SF];
162
163         case LM_TC_CMR:
164                 return MathFonts[FONT_CMR];
165
166         case LM_TC_CMSY:
167                 return MathFonts[FONT_CMSY];
168
169         case LM_TC_CMM:
170                 return MathFonts[FONT_CMM];
171
172         case LM_TC_CMEX:
173                 return MathFonts[FONT_CMEX];
174
175         case LM_TC_MSA:
176                 return MathFonts[FONT_MSA];
177
178         case LM_TC_MSB:
179                 return MathFonts[FONT_MSB];
180
181         case LM_TC_EUFRAK:
182                 return MathFonts[FONT_EUFRAK];
183
184         default:
185                 break;
186         }
187         return MathFonts[1];
188 }
189
190
191 LyXFont const & whichFontBase(MathTextCodes type)
192 {
193         if (!MathFonts)
194                 mathed_init_fonts();
195
196         switch (type) {
197         case LM_TC_BB:
198                 if (math_font_available(LM_TC_MSB))
199                         return MathFonts[FONT_MSB];
200                 else
201                         return MathFonts[FONT_FAKEBB];
202
203         case LM_TC_CAL:
204                 if (math_font_available(LM_TC_CMSY))
205                         return MathFonts[FONT_CMSY];
206                 else
207                         return MathFonts[FONT_FAKECAL];
208
209         case LM_TC_EUFRAK:
210                 if (math_font_available(LM_TC_EUFRAK))
211                         return MathFonts[FONT_EUFRAK];
212                 else
213                         return MathFonts[FONT_FAKEFRAK];
214
215         default:
216                 break;
217         }
218         return whichFontBaseIntern(type);
219 }
220
221 } // namespace
222
223
224 void whichFont(LyXFont & f, MathTextCodes type, MathMetricsInfo const & size)
225 {
226         f = whichFontBase(type);
227         // use actual size
228         f.setSize(size.font.size());
229
230         switch (size.style) {
231         case LM_ST_DISPLAY:
232                 if (type == LM_TC_BOLDSYMB || type == LM_TC_CMEX) {
233                         f.incSize();
234                         f.incSize();
235                 }
236                 break;
237
238         case LM_ST_TEXT:
239                 break;
240
241         case LM_ST_SCRIPT:
242                 f.decSize();
243                 f.decSize();
244                 break;
245
246         case LM_ST_SCRIPTSCRIPT:
247                 f.decSize();
248                 f.decSize();
249                 f.decSize();
250                 break;
251
252         default:
253                 lyxerr << "Math Error: wrong font size: " << size.style << endl;
254                 break;
255         }
256
257         if (type != LM_TC_TEXTRM && type != LM_TC_BOX)
258                 f.setColor(LColor::math);
259
260         if (type == LM_TC_TEX)
261                 f.setColor(LColor::latex);
262 }
263
264
265 bool math_font_available(MathTextCodes type)
266 {
267         if (!font_available_initialized[type]) {
268                 font_available_initialized[type] = true;
269                 font_available[type] = fontloader.available(whichFontBaseIntern(type));
270                 if (!font_available[type])
271                         lyxerr[Debug::FONT] << "Math font " << type << " not available.\n";
272         }
273         return font_available[type];
274 }
275
276
277 namespace {
278
279 /*
280  * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
281  * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
282  */
283
284
285 double const parenthHigh[] = {
286         2, 13,
287         0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
288         0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
289         0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
290         0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
291         0.9840, 0.9986,
292         0
293 };
294
295
296 double const parenth[] = {
297         2, 13,
298         0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
299         0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
300         0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
301         0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
302         0.9930, 0.9919,
303         0
304 };
305
306
307 double const brace[] = {
308         2, 21,
309         0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
310         0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
311         0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
312         0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
313         0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
314         0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
315         0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
316         0
317 };
318
319
320 double const arrow[] = {
321         4, 7,
322         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
323         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
324         0.9500, 0.7500,
325         3, 0.5000, 0.1500, 0.5000, 0.9500,
326         0
327 };
328
329
330 double const Arrow[] = {
331         4, 7,
332         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
333         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
334         0.9500, 0.7500,
335         3, 0.3500, 0.5000, 0.3500, 0.9500,
336         3, 0.6500, 0.5000, 0.6500, 0.9500,
337         0
338 };
339
340
341 double const udarrow[] = {
342         2, 3,
343         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
344         2, 3,
345         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
346         1, 0.5, 0.2,  0.5, 0.8,
347         0
348 };
349
350
351 double const Udarrow[] = {
352         2, 3,
353         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
354         2, 3,
355         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
356         1, 0.35, 0.2, 0.35, 0.8,
357         1, 0.65, 0.2, 0.65, 0.8,
358         0
359 };
360
361
362 double const brack[] = {
363         2, 4,
364         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
365         0
366 };
367
368
369 double const corner[] = {
370         2, 3,
371         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,
372         0
373 };
374
375
376 double const angle[] = {
377         2, 3,
378         1, 0,  0.05, 0.5,  1, 1,
379         0
380 };
381
382
383 double const slash[] = {
384         1, 0.95, 0.05, 0.05, 0.95,
385         0
386 };
387
388
389 double const hline[] = {
390         1, 0.00, 0.5, 1.0, 0.5,
391         0
392 };
393
394
395 double const ddot[] = {
396         1, 0.2, 0.5,  0.3, 0.5,
397         1, 0.7, 0.5,  0.8, 0.5,
398         0
399 };
400
401
402 double const dddot[] = {
403         1, 0.1, 0.5,  0.2, 0.5,
404         1, 0.45, 0.5, 0.55, 0.5,
405         1, 0.8, 0.5,  0.9, 0.5,
406         0
407 };
408
409
410 double const hline3[] = {
411         1, 0.1,   0,  0.15,  0,
412         1, 0.475, 0,  0.525, 0,
413         1, 0.85,  0,  0.9,   0,
414         0
415 };
416
417
418 double const dline3[] = {
419         1, 0.1,   0.1,   0.15,  0.15,
420         1, 0.475, 0.475, 0.525, 0.525,
421         1, 0.85,  0.85,  0.9,   0.9,
422         0
423 };
424
425
426 double const hlinesmall[] = {
427         1, 0.4, 0.5, 0.6, 0.5,
428         0
429 };
430
431
432 double const vert[] = {
433         1, 0.5, 0.05,  0.5, 0.95,
434         0
435 };
436
437
438 double const  Vert[] = {
439         1, 0.3, 0.05,  0.3, 0.95,
440         1, 0.7, 0.05,  0.7, 0.95,
441         0
442 };
443
444
445 double const tilde[] = {
446         2, 4,
447         0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
448         0
449 };
450
451
452 struct deco_struct {
453         double const * data;
454         int angle;
455 };
456
457 struct named_deco_struct {
458         char const * name;
459         double const * data;
460         int angle;
461 };
462
463 named_deco_struct deco_table[] = {
464         // Decorations
465         {"widehat",        angle,      3 },
466         {"widetilde",      tilde,      0 },
467         {"underbar",       hline,      0 },
468         {"underline",      hline,      0 },
469         {"overline",       hline,      0 },
470         {"underbrace",     brace,      1 },
471         {"overbrace",      brace,      3 },
472         {"overleftarrow",  arrow,      1 },
473         {"overrightarrow", arrow,      3 },
474         {"overleftrightarrow", udarrow, 1 },
475         {"xleftarrow",     arrow,      1 },
476         {"xrightarrow",    arrow,      3 },
477         {"underleftarrow", arrow,      1 },
478         {"underrightarrow", arrow,     3 },
479         {"underleftrightarrow",udarrow, 1 },
480
481         // Delimiters
482         {"(",              parenth,    0 },
483         {")",              parenth,    2 },
484         {"{",              brace,      0 },
485         {"}",              brace,      2 },
486         {"[",              brack,      0 },
487         {"]",              brack,      2 },
488         {"|",              vert,       0 },
489         {"/",              slash,      0 },
490         {"Vert",           Vert,       0 },
491         {"'",              slash,      1 },
492         {"backslash",      slash,      1 },
493         {"langle",         angle,      0 },
494         {"lceil",          corner,     0 },
495         {"lfloor",         corner,     1 },
496         {"rangle",         angle,      2 },
497         {"rceil",          corner,     3 },
498         {"rfloor",         corner,     2 },
499         {"downarrow",      arrow,      2 },
500         {"Downarrow",      Arrow,      2 },
501         {"uparrow",        arrow,      0 },
502         {"Uparrow",        Arrow,      0 },
503         {"updownarrow",    udarrow,    0 },
504         {"Updownarrow",    Udarrow,    0 },     
505         
506         // Accents
507         {"ddot",           ddot,       0 },
508         {"dddot",          dddot,      0 },
509         {"hat",            angle,      3 },
510         {"grave",          slash,      1 },
511         {"acute",          slash,      0 },
512         {"tilde",          tilde,      0 },
513         {"bar",            hline,      0 },
514         {"dot",            hlinesmall, 0 },
515         {"check",          angle,      1 },
516         {"breve",          parenth,    1 },
517         {"vec",            arrow,      3 },
518         {"not",            slash,      0 },
519         
520         // Dots
521         {"ldots",          hline3,     0 },
522         {"cdots",          hline3,     0 },
523         {"vdots",          hline3,     1 },
524         {"ddots",          dline3,     0 }
525 };
526
527
528 map<string, deco_struct> deco_list;
529
530 // sort the table on startup
531 struct init_deco_table {
532         init_deco_table() {
533                 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
534                 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
535                         deco_struct d;
536                         d.data  = p->data;
537                         d.angle = p->angle;
538                         deco_list[p->name]= d;
539                 }
540         }
541 };
542
543 static init_deco_table dummy;
544
545
546 deco_struct const * search_deco(string const & name)
547 {
548         map<string, deco_struct>::const_iterator p = deco_list.find(name);
549         return (p == deco_list.end()) ? 0 : &(p->second);
550 }
551
552
553 } // namespace anon
554
555
556 void mathed_char_dim(LyXFont const & font,
557         unsigned char c, int & asc, int & des, int & wid)
558 {
559         des = lyxfont::descent(c, font);
560         asc = lyxfont::ascent(c, font);
561         wid = mathed_char_width(font, c);
562 }
563
564
565 int mathed_char_height(LyXFont const & font,
566         unsigned char c, int & asc, int & des)
567 {
568         des = lyxfont::descent(c, font);
569         asc = lyxfont::ascent(c, font);
570         return asc + des;
571 }
572
573
574 int mathed_char_height(LyXFont const & font, unsigned char c)
575 {
576         int asc;
577         int des;
578         return mathed_char_height(font, c, asc, des);
579 }
580
581
582 int mathed_char_ascent(LyXFont const & font, unsigned char c)
583 {
584         return lyxfont::ascent(c, font);
585 }
586
587
588 int mathed_char_descent(LyXFont const & font, unsigned char c)
589 {
590         return lyxfont::descent(c, font);
591 }
592
593
594 int mathed_char_width(LyXFont const & font,
595         unsigned char c)
596 {
597         //if (isBinaryOp(c, type))
598         //      return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
599         return lyxfont::width(c, font);
600 }
601
602
603 void mathed_string_dim(LyXFont const & font,
604         string const & s, int & asc, int & des, int & wid)
605 {
606         mathed_string_height(font, s, asc, des);
607         wid = mathed_string_width(font, s);
608 }
609
610
611 int mathed_string_height(LyXFont const & font,
612         string const & s, int & asc, int & des)
613 {
614         asc = des = 0;
615         for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
616                 des = max(des, lyxfont::descent(*it, font));
617                 asc = max(asc, lyxfont::ascent(*it, font));
618         }
619         return asc + des;
620 }
621
622
623 int mathed_string_width(LyXFont const & font, string const & s)
624 {
625         return lyxfont::width(s, font);
626 }
627
628
629 int mathed_string_ascent(LyXFont const & font, string const & s)
630 {
631         int asc = 0;
632         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
633                 asc = max(asc, lyxfont::ascent(*it, font));
634         return asc;
635 }
636
637
638 int mathed_string_descent(LyXFont const & font, string const & s)
639 {
640         int des = 0;
641         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
642                 des = max(des, lyxfont::descent(*it, font));
643         return des;
644 }
645
646
647
648 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
649         const string & name)
650 {
651         if (name == ".") {
652                 pain.line(x + w/2, y, x + w/2, y + h,
653                           LColor::mathcursor, Painter::line_onoffdash);
654                 return;
655         }       
656         
657         deco_struct const * mds = search_deco(name);
658         if (!mds) {
659                 lyxerr << "Deco was not found. Programming error?\n";
660                 lyxerr << "name: '" << name << "'\n";
661                 return;
662         }
663         
664         int const n = (w < h) ? w : h;
665         int const r = mds->angle;
666         double const * d = mds->data;
667         
668         if (h > 70 && (name == "(" || name == ")"))
669                 d = parenthHigh;
670         
671         Matrix mt(r, w, h);
672         Matrix sqmt(r, n, n);
673
674         if (r > 0 && r < 3)
675                 y += h;
676
677         if (r >= 2)
678                 x += w;
679
680         for (int i = 0; d[i];) {
681                 int code = int(d[i++]);
682                 if (code & 1) {  // code == 1 || code == 3
683                         double xx = d[i++];
684                         double yy = d[i++];
685                         double x2 = d[i++];
686                         double y2 = d[i++];
687                         if (code == 3)
688                                 sqmt.transform(xx, yy);
689                         else
690                                 mt.transform(xx, yy);
691                         mt.transform(x2, y2);
692                         pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
693                                         LColor::math);
694                 }       else {
695                         int xp[32];
696                         int yp[32];
697                         int const n = int(d[i++]);
698                         for (int j = 0; j < n; ++j) {
699                                 double xx = d[i++];
700                                 double yy = d[i++];
701 //           lyxerr << " " << xx << " " << yy << " ";
702                                 if (code == 4)
703                                         sqmt.transform(xx, yy);
704                                 else
705                                         mt.transform(xx, yy);
706                                 xp[j] = x + int(xx);
707                                 yp[j] = y + int(yy);
708                                 //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
709                         }
710                         pain.lines(xp, yp, n, LColor::math);
711                 }
712         }
713 }
714
715
716 void mathed_draw_framebox(Painter & pain, int x, int y, MathInset const * p)
717 {
718         if (mathcursor && mathcursor->isInside(p))
719                 pain.rectangle(x, y - p->ascent(), p->width(), p->height(),
720                         LColor::mathframe);
721 }
722
723
724 // In the future maybe we use a better fonts renderer
725 void drawStr(Painter & pain, LyXFont const & font,
726         int x, int y, string const & str)
727 {
728         pain.text(x, y, str, font);
729 }
730
731
732 void drawChar(Painter & pain, LyXFont const & font, int x, int y, char c)
733 {
734         //if (isBinaryOp(c, type)) 
735         //      x += lyxfont::width(' ', font);
736         pain.text(x, y, c, font);
737 }
738
739
740 // decrease math size for super- and subscripts
741 void smallerStyleScript(MathMetricsInfo & st)
742 {
743         switch (st.style) {
744                 case LM_ST_DISPLAY:
745                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
746                 default:            st.style = LM_ST_SCRIPTSCRIPT;
747         }
748 }
749
750
751 // decrease math size for fractions
752 void smallerStyleFrac(MathMetricsInfo & st)
753 {
754         switch (st.style) {
755                 case LM_ST_DISPLAY: st.style = LM_ST_TEXT; break;
756                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
757                 default:            st.style = LM_ST_SCRIPTSCRIPT;
758         }
759 }
760
761
762 void math_font_max_dim(LyXFont const & font, int & asc, int & des)
763 {
764         asc = lyxfont::maxAscent(font);
765         des = lyxfont::maxDescent(font);
766 }
767
768
769 char const * latex_mathspace[] = {
770         "!", ",", ":", ";", "quad", "qquad"
771 };
772
773
774
775 char const * math_font_name(MathTextCodes code)
776 {
777         static char const * theFontNames[] = {
778                 "mathrm",
779                 "mathcal",
780                 "mathfrak",
781                 "mathbf",
782                 "mathbb",
783                 "mathsf",
784                 "mathtt",
785                 "mathit",
786                 "textrm"
787         };
788
789         if (code >= LM_TC_RM && code <= LM_TC_TEXTRM) 
790                 return theFontNames[code - LM_TC_RM];
791         return 0;
792 }
793
794 string convertDelimToLatexName(string const & name)
795 {
796         if (name == "(")
797                 return name;
798         if (name == "[")
799                 return name;
800         if (name == ".")
801                 return name;
802         if (name == ")")
803                 return name;
804         if (name == "]")
805                 return name;
806         if (name == "/")
807                 return name;
808         if (name == "|")
809                 return name;
810         return "\\" + name + " ";
811 }
812
813