]> git.lyx.org Git - lyx.git/blob - src/mathed/math_support.C
whichFont down to 5.3%
[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 void whichFont(LyXFont & f, MathTextCodes type, MathMetricsInfo const & size)
223 {
224         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
262 } // namespace
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(MathTextCodes type, MathMetricsInfo const & size,
557         unsigned char c, int & asc, int & des, int & wid)
558 {
559         LyXFont font;
560         whichFont(font, type, size);
561         des = lyxfont::descent(c, font);
562         asc = lyxfont::ascent(c, font);
563         wid = mathed_char_width(type, size, c);
564 }
565
566
567 int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
568         unsigned char c, int & asc, int & des)
569 {
570         LyXFont font;
571         whichFont(font, type, size);
572         des = lyxfont::descent(c, font);
573         asc = lyxfont::ascent(c, font);
574         return asc + des;
575 }
576
577
578 int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
579         unsigned char c)
580 {
581         int asc;
582         int des;
583         return mathed_char_height(type, size, c, asc, des);
584 }
585
586
587 int mathed_char_ascent(MathTextCodes type, MathMetricsInfo const & size,
588         unsigned char c)
589 {
590         LyXFont font;
591         whichFont(font, type, size);
592         return lyxfont::ascent(c, font);
593 }
594
595
596 int mathed_char_descent(MathTextCodes type, MathMetricsInfo const & size,
597         unsigned char c)
598 {
599         LyXFont font;
600         whichFont(font, type, size);
601         return lyxfont::descent(c, font);
602 }
603
604
605 int mathed_char_width(MathTextCodes type, MathMetricsInfo const & size,
606         unsigned char c)
607 {
608         LyXFont font;
609         whichFont(font, type, size);
610         if (isBinaryOp(c, type))
611                 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
612         else
613                 return lyxfont::width(c, font);
614 }
615
616
617 void mathed_string_dim(MathTextCodes type, MathMetricsInfo const & size,
618         string const & s, int & asc, int & des, int & wid)
619 {
620         mathed_string_height(type, size, s, asc, des);
621         wid = mathed_string_width(type, size, s);
622 }
623
624
625 int mathed_string_height(MathTextCodes type, MathMetricsInfo const & size,
626         string const & s, int & asc, int & des)
627 {
628         LyXFont font;
629         whichFont(font, type, size);
630         asc = des = 0;
631         for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
632                 des = max(des, lyxfont::descent(*it, font));
633                 asc = max(asc, lyxfont::ascent(*it, font));
634         }
635         return asc + des;
636 }
637
638
639 int mathed_string_width(MathTextCodes type, MathMetricsInfo const & size,
640         string const & s)
641 {
642         LyXFont font;
643         whichFont(font, type, size);
644         return lyxfont::width(s, font);
645 }
646
647
648 int mathed_string_ascent(MathTextCodes type, MathMetricsInfo const & size,
649         string const & s)
650 {
651         LyXFont font;
652         whichFont(font, type, size);
653         int asc = 0;
654         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
655                 asc = max(asc, lyxfont::ascent(*it, font));
656         return asc;
657 }
658
659
660 int mathed_string_descent(MathTextCodes type, MathMetricsInfo const & size,
661         string const & s)
662 {
663         LyXFont font;
664         whichFont(font, type, size);
665         int des = 0;
666         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
667                 des = max(des, lyxfont::descent(*it, font));
668         return des;
669 }
670
671
672
673 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
674         const string & name)
675 {
676         if (name == ".") {
677                 pain.line(x + w/2, y, x + w/2, y + h,
678                           LColor::mathcursor, Painter::line_onoffdash);
679                 return;
680         }       
681         
682         deco_struct const * mds = search_deco(name);
683         if (!mds) {
684                 lyxerr << "Deco was not found. Programming error?\n";
685                 lyxerr << "name: '" << name << "'\n";
686                 return;
687         }
688         
689         int const n = (w < h) ? w : h;
690         int const r = mds->angle;
691         double const * d = mds->data;
692         
693         if (h > 70 && (name == "(" || name == ")"))
694                 d = parenthHigh;
695         
696         Matrix mt(r, w, h);
697         Matrix sqmt(r, n, n);
698
699         if (r > 0 && r < 3)
700                 y += h;
701
702         if (r >= 2)
703                 x += w;
704
705         for (int i = 0; d[i]; ) {
706                 int code = int(d[i++]);
707                 if (code & 1) {  // code == 1 || code == 3
708                         double xx = d[i++];
709                         double yy = d[i++];
710                         double x2 = d[i++];
711                         double y2 = d[i++];
712                         if (code == 3)
713                                 sqmt.transform(xx, yy);
714                         else
715                                 mt.transform(xx, yy);
716                         mt.transform(x2, y2);
717                         pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
718                                         LColor::math);
719                 }       else {
720                         int xp[32];
721                         int yp[32];
722                         int const n = int(d[i++]);
723                         for (int j = 0; j < n; ++j) {
724                                 double xx = d[i++];
725                                 double yy = d[i++];
726 //           lyxerr << " " << xx << " " << yy << " ";
727                                 if (code == 4)
728                                         sqmt.transform(xx, yy);
729                                 else
730                                         mt.transform(xx, yy);
731                                 xp[j] = x + int(xx);
732                                 yp[j] = y + int(yy);
733                                 //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
734                         }
735                         pain.lines(xp, yp, n, LColor::math);
736                 }
737         }
738 }
739
740
741 void mathed_draw_framebox(Painter & pain, int x, int y, MathInset const * p)
742 {
743         if (mathcursor && mathcursor->isInside(p))
744                 pain.rectangle(x, y - p->ascent(), p->width(), p->height(),
745                         LColor::mathframe);
746 }
747
748
749 // In the future maybe we use a better fonts renderer
750 void drawStr(Painter & pain, MathTextCodes type, MathMetricsInfo const & size,
751         int x, int y, string const & str)
752 {
753         LyXFont font;
754         whichFont(font, type, size);
755         pain.text(x, y, str, font);
756 }
757
758
759 void drawChar(Painter & pain, MathTextCodes type, MathMetricsInfo const & size,
760         int x, int y, char c)
761 {
762         string s;
763         if (isBinaryOp(c, type))
764                 s += ' ';
765         s += c;
766         if (isBinaryOp(c, type))
767                 s += ' ';
768         drawStr(pain, type, size, x, y, s);
769 }
770
771
772 // decrease math size for super- and subscripts
773 void smallerStyleScript(MathMetricsInfo & st)
774 {
775         switch (st.style) {
776                 case LM_ST_DISPLAY:
777                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
778                 default:            st.style = LM_ST_SCRIPTSCRIPT;
779         }
780 }
781
782
783 // decrease math size for fractions
784 void smallerStyleFrac(MathMetricsInfo & st)
785 {
786         switch (st.style) {
787                 case LM_ST_DISPLAY: st.style = LM_ST_TEXT; break;
788                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
789                 default:            st.style = LM_ST_SCRIPTSCRIPT;
790         }
791 }
792
793
794 void math_font_max_dim(MathTextCodes code, MathMetricsInfo const & size,
795         int & asc, int & des)
796 {
797         LyXFont font;
798         whichFont(font, code, size);
799         asc = lyxfont::maxAscent(font);
800         des = lyxfont::maxDescent(font);
801 }
802
803
804 char const * latex_mathspace[] = {
805         "!", ",", ":", ";", "quad", "qquad"
806 };
807
808
809
810 char const * math_font_name(MathTextCodes code)
811 {
812         static char const * theFontNames[] = {
813                 "mathrm",
814                 "mathcal",
815                 "mathfrak",
816                 "mathbf",
817                 "mathbb",
818                 "mathsf",
819                 "mathtt",
820                 "mathit",
821                 "textrm"
822         };
823
824         if (code >= LM_TC_RM && code <= LM_TC_TEXTRM) 
825                 return theFontNames[code - LM_TC_RM];
826         return 0;
827 }
828
829 string convertDelimToLatexName(string const & name)
830 {
831         if (name == "(")
832                 return name;
833         if (name == "[")
834                 return name;
835         if (name == ".")
836                 return name;
837         if (name == ")")
838                 return name;
839         if (name == "]")
840                 return name;
841         if (name == "/")
842                 return name;
843         if (name == "|")
844                 return name;
845         return "\\" + name + " ";
846 }
847
848