]> git.lyx.org Git - lyx.git/blob - src/mathed/math_support.C
small internal stuff
[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
222 LyXFont whichFont(MathTextCodes type, MathMetricsInfo const & size)
223 {
224         LyXFont f = whichFontBase(type);
225         // use actual size
226         f.setSize(size.font.size());
227
228         switch (size.style) {
229         case LM_ST_DISPLAY:
230                 if (type == LM_TC_BOLDSYMB || type == LM_TC_CMEX) {
231                         f.incSize();
232                         f.incSize();
233                 }
234                 break;
235
236         case LM_ST_TEXT:
237                 break;
238
239         case LM_ST_SCRIPT:
240                 f.decSize();
241                 f.decSize();
242                 break;
243
244         case LM_ST_SCRIPTSCRIPT:
245                 f.decSize();
246                 f.decSize();
247                 f.decSize();
248                 break;
249
250         default:
251                 lyxerr << "Math Error: wrong font size: " << size.style << endl;
252                 break;
253         }
254
255         if (type != LM_TC_TEXTRM && type != LM_TC_BOX)
256                 f.setColor(LColor::math);
257
258         if (type == LM_TC_TEX)
259                 f.setColor(LColor::latex);
260
261         return f;
262 }
263
264 } // namespace
265
266
267 bool math_font_available(MathTextCodes type)
268 {
269         if (!font_available_initialized[type]) {
270                 font_available_initialized[type] = true;
271                 font_available[type] = fontloader.available(whichFontBaseIntern(type));
272                 if (!font_available[type])
273                         lyxerr[Debug::FONT] << "Math font " << type << " not available.\n";
274         }
275         return font_available[type];
276 }
277
278
279 namespace {
280
281 /*
282  * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
283  * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
284  */
285
286
287 double const parenthHigh[] = {
288         2, 13,
289         0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
290         0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
291         0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
292         0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
293         0.9840, 0.9986,
294         0
295 };
296
297
298 double const parenth[] = {
299         2, 13,
300         0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
301         0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
302         0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
303         0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
304         0.9930, 0.9919,
305         0
306 };
307
308
309 double const brace[] = {
310         2, 21,
311         0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
312         0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
313         0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
314         0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
315         0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
316         0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
317         0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
318         0
319 };
320
321
322 double const arrow[] = {
323         4, 7,
324         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
325         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
326         0.9500, 0.7500,
327         3, 0.5000, 0.1500, 0.5000, 0.9500,
328         0
329 };
330
331
332 double const Arrow[] = {
333         4, 7,
334         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
335         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
336         0.9500, 0.7500,
337         3, 0.3500, 0.5000, 0.3500, 0.9500,
338         3, 0.6500, 0.5000, 0.6500, 0.9500,
339         0
340 };
341
342
343 double const udarrow[] = {
344         2, 3,
345         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
346         2, 3,
347         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
348         1, 0.5, 0.2,  0.5, 0.8,
349         0
350 };
351
352
353 double const Udarrow[] = {
354         2, 3,
355         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
356         2, 3,
357         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
358         1, 0.35, 0.2, 0.35, 0.8,
359         1, 0.65, 0.2, 0.65, 0.8,
360         0
361 };
362
363
364 double const brack[] = {
365         2, 4,
366         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
367         0
368 };
369
370
371 double const corner[] = {
372         2, 3,
373         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,
374         0
375 };
376
377
378 double const angle[] = {
379         2, 3,
380         1, 0,  0.05, 0.5,  1, 1,
381         0
382 };
383
384
385 double const slash[] = {
386         1, 0.95, 0.05, 0.05, 0.95,
387         0
388 };
389
390
391 double const hline[] = {
392         1, 0.00, 0.5, 1.0, 0.5,
393         0
394 };
395
396
397 double const hline2[] = {
398         1, 0.2, 0.5,  0.3, 0.5,
399         1, 0.7, 0.5,  0.8, 0.5,
400         0
401 };
402
403
404 double const hline3[] = {
405         1, 0.1,   0,  0.15,  0,
406         1, 0.475, 0,  0.525, 0,
407         1, 0.85,  0,  0.9,   0,
408         0
409 };
410
411
412 double const dline3[] = {
413         1, 0.1,   0.1,   0.15,  0.15,
414         1, 0.475, 0.475, 0.525, 0.525,
415         1, 0.85,  0.85,  0.9,   0.9,
416         0
417 };
418
419
420 double const hlinesmall[] = {
421         1, 0.4, 0.5, 0.6, 0.5,
422         0
423 };
424
425
426 double const vert[] = {
427         1, 0.5, 0.05,  0.5, 0.95,
428         0
429 };
430
431
432 double const  Vert[] = {
433         1, 0.3, 0.05,  0.3, 0.95,
434         1, 0.7, 0.05,  0.7, 0.95,
435         0
436 };
437
438
439 double const tilde[] = {
440         2, 4,
441         0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
442         0
443 };
444
445
446 struct deco_struct {
447         double const * data;
448         int angle;
449 };
450
451 struct named_deco_struct {
452         char const * name;
453         double const * data;
454         int angle;
455 };
456
457 named_deco_struct deco_table[] = {
458         // Decorations
459         {"widehat",        angle,      3 },
460         {"widetilde",      tilde,      0 },
461         {"underbar",       hline,      0 },
462         {"underline",      hline,      0 },
463         {"overline",       hline,      0 },
464         {"underbrace",     brace,      1 },
465         {"overbrace",      brace,      3 },
466         {"overleftarrow",  arrow,      1 },
467         {"overrightarrow", arrow,      3 },
468         {"xleftarrow",     arrow,      1 },
469         {"xrightarrow",    arrow,      3 },
470         
471         // Delimiters
472         {"(",              parenth,    0 },
473         {")",              parenth,    2 },
474         {"{",              brace,      0 },
475         {"}",              brace,      2 },
476         {"[",              brack,      0 },
477         {"]",              brack,      2 },
478         {"|",              vert,       0 },
479         {"/",              slash,      0 },
480         {"Vert",           Vert,       0 },
481         {"'",              slash,      1 },
482         {"backslash",      slash,      1 },
483         {"langle",         angle,      0 },
484         {"lceil",          corner,     0 },
485         {"lfloor",         corner,     1 },
486         {"rangle",         angle,      2 },
487         {"rceil",          corner,     3 },
488         {"rfloor",         corner,     2 },
489         {"downarrow",      arrow,      2 },
490         {"Downarrow",      Arrow,      2 },
491         {"uparrow",        arrow,      0 },
492         {"Uparrow",        Arrow,      0 },
493         {"updownarrow",    udarrow,    0 },
494         {"Updownarrow",    Udarrow,    0 },     
495         
496         // Accents
497         {"ddot",           hline2,     0 },
498         {"hat",            angle,      3 },
499         {"grave",          slash,      1 },
500         {"acute",          slash,      0 },
501         {"tilde",          tilde,      0 },
502         {"bar",            hline,      0 },
503         {"dot",            hlinesmall, 0 },
504         {"check",          angle,      1 },
505         {"breve",          parenth,    1 },
506         {"vec",            arrow,      3 },
507         {"not",            slash,      0 },
508         
509         // Dots
510         {"ldots",          hline3,     0 },
511         {"cdots",          hline3,     0 },
512         {"vdots",          hline3,     1 },
513         {"ddots",          dline3,     0 }
514 };
515
516
517 map<string, deco_struct> deco_list;
518
519 // sort the table on startup
520 struct init_deco_table {
521         init_deco_table() {
522                 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
523                 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
524                         deco_struct d;
525                         d.data  = p->data;
526                         d.angle = p->angle;
527                         deco_list[p->name]= d;
528                 }
529         }
530 };
531
532 static init_deco_table dummy;
533
534
535 deco_struct const * search_deco(string const & name)
536 {
537         map<string, deco_struct>::const_iterator p = deco_list.find(name);
538         return (p == deco_list.end()) ? 0 : &(p->second);
539 }
540
541
542 } // namespace anon
543
544
545 void mathed_char_dim(MathTextCodes type, MathMetricsInfo const & size,
546         unsigned char c, int & asc, int & des, int & wid)
547 {
548         LyXFont const font = whichFont(type, size);
549         des = lyxfont::descent(c, font);
550         asc = lyxfont::ascent(c, font);
551         wid = mathed_char_width(type, size, c);
552 }
553
554
555 int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
556         unsigned char c, int & asc, int & des)
557 {
558         LyXFont const font = whichFont(type, size);
559         des = lyxfont::descent(c, font);
560         asc = lyxfont::ascent(c, font);
561         return asc + des;
562 }
563
564
565 int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
566         unsigned char c)
567 {
568         int asc;
569         int des;
570         return mathed_char_height(type, size, c, asc, des);
571 }
572
573
574 int mathed_char_ascent(MathTextCodes type, MathMetricsInfo const & size,
575         unsigned char c)
576 {
577         LyXFont const font = whichFont(type, size);
578         return lyxfont::ascent(c, font);
579 }
580
581
582 int mathed_char_descent(MathTextCodes type, MathMetricsInfo const & size,
583         unsigned char c)
584 {
585         LyXFont const font = whichFont(type, size);
586         return lyxfont::descent(c, font);
587 }
588
589
590 int mathed_char_width(MathTextCodes type, MathMetricsInfo const & size,
591         unsigned char c)
592 {
593         LyXFont const font = whichFont(type, size);
594         if (isBinaryOp(c, type))
595                 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
596         else
597                 return lyxfont::width(c, font);
598 }
599
600
601 void mathed_string_dim(MathTextCodes type, MathMetricsInfo const & size,
602         string const & s, int & asc, int & des, int & wid)
603 {
604         mathed_string_height(type, size, s, asc, des);
605         wid = mathed_string_width(type, size, s);
606 }
607
608
609 int mathed_string_height(MathTextCodes type, MathMetricsInfo const & size,
610         string const & s, int & asc, int & des)
611 {
612         LyXFont const font = whichFont(type, size);
613         asc = des = 0;
614         for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
615                 des = max(des, lyxfont::descent(*it, font));
616                 asc = max(asc, lyxfont::ascent(*it, font));
617         }
618         return asc + des;
619 }
620
621
622 int mathed_string_width(MathTextCodes type, MathMetricsInfo const & size,
623         string const & s)
624 {
625         return lyxfont::width(s, whichFont(type, size));
626 }
627
628
629 int mathed_string_ascent(MathTextCodes type, MathMetricsInfo const & size,
630         string const & s)
631 {
632         LyXFont const font = whichFont(type, size);
633         int asc = 0;
634         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
635                 asc = max(asc, lyxfont::ascent(*it, font));
636         return asc;
637 }
638
639
640 int mathed_string_descent(MathTextCodes type, MathMetricsInfo const & size,
641         string const & s)
642 {
643         LyXFont const font = whichFont(type, size);
644         int des = 0;
645         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
646                 des = max(des, lyxfont::descent(*it, font));
647         return des;
648 }
649
650
651
652 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
653         const string & name)
654 {
655         if (name == ".") {
656                 pain.line(x + w/2, y, x + w/2, y + h,
657                           LColor::mathcursor, Painter::line_onoffdash);
658                 return;
659         }       
660         
661         deco_struct const * mds = search_deco(name);
662         if (!mds) {
663                 lyxerr << "Deco was not found. Programming error?\n";
664                 lyxerr << "name: '" << name << "'\n";
665                 return;
666         }
667         
668         int const n = (w < h) ? w : h;
669         int const r = mds->angle;
670         double const * d = mds->data;
671         
672         if (h > 70 && (name == "(" || name == ")"))
673                 d = parenthHigh;
674         
675         Matrix mt(r, w, h);
676         Matrix sqmt(r, n, n);
677
678         if (r > 0 && r < 3)
679                 y += h;
680
681         if (r >= 2)
682                 x += w;
683
684         for (int i = 0; d[i]; ) {
685                 int code = int(d[i++]);
686                 if (code & 1) {  // code == 1 || code == 3
687                         double xx = d[i++];
688                         double yy = d[i++];
689                         double x2 = d[i++];
690                         double y2 = d[i++];
691                         if (code == 3)
692                                 sqmt.transform(xx, yy);
693                         else
694                                 mt.transform(xx, yy);
695                         mt.transform(x2, y2);
696                         pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
697                                         LColor::math);
698                 }       else {
699                         int xp[32];
700                         int yp[32];
701                         int const n = int(d[i++]);
702                         for (int j = 0; j < n; ++j) {
703                                 double xx = d[i++];
704                                 double yy = d[i++];
705 //           lyxerr << " " << xx << " " << yy << " ";
706                                 if (code == 4)
707                                         sqmt.transform(xx, yy);
708                                 else
709                                         mt.transform(xx, yy);
710                                 xp[j] = x + int(xx);
711                                 yp[j] = y + int(yy);
712                                 //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
713                         }
714                         pain.lines(xp, yp, n, LColor::math);
715                 }
716         }
717 }
718
719
720 void mathed_draw_framebox(Painter & pain, int x, int y, MathInset const * p)
721 {
722         if (mathcursor && mathcursor->isInside(p))
723                 pain.rectangle(x, y - p->ascent(), p->width(), p->height(),
724                         LColor::mathframe);
725 }
726
727
728 // In the future maybe we use a better fonts renderer
729 void drawStr(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
730         int x, int y, string const & s)
731 {
732         pain.text(x, y, s, whichFont(type, siz));
733 }
734
735
736 void drawChar(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
737         int x, int y, char c)
738 {
739         string s;
740         if (isBinaryOp(c, type))
741                 s += ' ';
742         s += c;
743         if (isBinaryOp(c, type))
744                 s += ' ';
745         drawStr(pain, type, siz, x, y, s);
746 }
747
748
749 // decrease math size for super- and subscripts
750 void smallerStyleScript(MathMetricsInfo & st)
751 {
752         switch (st.style) {
753                 case LM_ST_DISPLAY:
754                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
755                 default:            st.style = LM_ST_SCRIPTSCRIPT;
756         }
757 }
758
759
760 // decrease math size for fractions
761 void smallerStyleFrac(MathMetricsInfo & st)
762 {
763         switch (st.style) {
764                 case LM_ST_DISPLAY: st.style = LM_ST_TEXT; break;
765                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
766                 default:            st.style = LM_ST_SCRIPTSCRIPT;
767         }
768 }
769
770
771 void math_font_max_dim(MathTextCodes code, MathMetricsInfo const & siz,
772         int & asc, int & des)
773 {
774         LyXFont font = whichFont(code, siz);
775         asc = lyxfont::maxAscent(font);
776         des = lyxfont::maxDescent(font);
777 }
778
779
780 char const * latex_mathspace[] = {
781         "!", ",", ":", ";", "quad", "qquad"
782 };
783
784
785
786 char const * math_font_name(MathTextCodes code)
787 {
788         static char const * theFontNames[] = {
789                 "mathrm",
790                 "mathcal",
791                 "mathfrak",
792                 "mathbf",
793                 "mathbb",
794                 "mathsf",
795                 "mathtt",
796                 "mathit",
797                 "textrm"
798         };
799
800         if (code >= LM_TC_RM && code <= LM_TC_TEXTRM) 
801                 return theFontNames[code - LM_TC_RM];
802         return 0;
803 }