]> git.lyx.org Git - lyx.git/blob - src/mathed/math_support.C
some support for \xleftarrow
[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 ddot[] = {
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 dddot[] = {
405         1, 0.1, 0.5,  0.2, 0.5,
406         1, 0.45, 0.5, 0.55, 0.5,
407         1, 0.8, 0.5,  0.9, 0.5,
408         0
409 };
410
411
412 double const hline3[] = {
413         1, 0.1,   0,  0.15,  0,
414         1, 0.475, 0,  0.525, 0,
415         1, 0.85,  0,  0.9,   0,
416         0
417 };
418
419
420 double const dline3[] = {
421         1, 0.1,   0.1,   0.15,  0.15,
422         1, 0.475, 0.475, 0.525, 0.525,
423         1, 0.85,  0.85,  0.9,   0.9,
424         0
425 };
426
427
428 double const hlinesmall[] = {
429         1, 0.4, 0.5, 0.6, 0.5,
430         0
431 };
432
433
434 double const vert[] = {
435         1, 0.5, 0.05,  0.5, 0.95,
436         0
437 };
438
439
440 double const  Vert[] = {
441         1, 0.3, 0.05,  0.3, 0.95,
442         1, 0.7, 0.05,  0.7, 0.95,
443         0
444 };
445
446
447 double const tilde[] = {
448         2, 4,
449         0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
450         0
451 };
452
453
454 struct deco_struct {
455         double const * data;
456         int angle;
457 };
458
459 struct named_deco_struct {
460         char const * name;
461         double const * data;
462         int angle;
463 };
464
465 named_deco_struct deco_table[] = {
466         // Decorations
467         {"widehat",        angle,      3 },
468         {"widetilde",      tilde,      0 },
469         {"underbar",       hline,      0 },
470         {"underline",      hline,      0 },
471         {"overline",       hline,      0 },
472         {"underbrace",     brace,      1 },
473         {"overbrace",      brace,      3 },
474         {"overleftarrow",  arrow,      1 },
475         {"overrightarrow", arrow,      3 },
476         {"overleftrightarrow", udarrow, 1 },
477         {"xleftarrow",     arrow,      1 },
478         {"xrightarrow",    arrow,      3 },
479         {"underleftarrow", arrow,      1 },
480         {"underrightarrow", arrow,     3 },
481         {"underleftrightarrow",udarrow, 1 },
482
483         // Delimiters
484         {"(",              parenth,    0 },
485         {")",              parenth,    2 },
486         {"{",              brace,      0 },
487         {"}",              brace,      2 },
488         {"[",              brack,      0 },
489         {"]",              brack,      2 },
490         {"|",              vert,       0 },
491         {"/",              slash,      0 },
492         {"Vert",           Vert,       0 },
493         {"'",              slash,      1 },
494         {"backslash",      slash,      1 },
495         {"langle",         angle,      0 },
496         {"lceil",          corner,     0 },
497         {"lfloor",         corner,     1 },
498         {"rangle",         angle,      2 },
499         {"rceil",          corner,     3 },
500         {"rfloor",         corner,     2 },
501         {"downarrow",      arrow,      2 },
502         {"Downarrow",      Arrow,      2 },
503         {"uparrow",        arrow,      0 },
504         {"Uparrow",        Arrow,      0 },
505         {"updownarrow",    udarrow,    0 },
506         {"Updownarrow",    Udarrow,    0 },     
507         
508         // Accents
509         {"ddot",           ddot,       0 },
510         {"dddot",          dddot,      0 },
511         {"hat",            angle,      3 },
512         {"grave",          slash,      1 },
513         {"acute",          slash,      0 },
514         {"tilde",          tilde,      0 },
515         {"bar",            hline,      0 },
516         {"dot",            hlinesmall, 0 },
517         {"check",          angle,      1 },
518         {"breve",          parenth,    1 },
519         {"vec",            arrow,      3 },
520         {"not",            slash,      0 },
521         
522         // Dots
523         {"ldots",          hline3,     0 },
524         {"cdots",          hline3,     0 },
525         {"vdots",          hline3,     1 },
526         {"ddots",          dline3,     0 }
527 };
528
529
530 map<string, deco_struct> deco_list;
531
532 // sort the table on startup
533 struct init_deco_table {
534         init_deco_table() {
535                 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
536                 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
537                         deco_struct d;
538                         d.data  = p->data;
539                         d.angle = p->angle;
540                         deco_list[p->name]= d;
541                 }
542         }
543 };
544
545 static init_deco_table dummy;
546
547
548 deco_struct const * search_deco(string const & name)
549 {
550         map<string, deco_struct>::const_iterator p = deco_list.find(name);
551         return (p == deco_list.end()) ? 0 : &(p->second);
552 }
553
554
555 } // namespace anon
556
557
558 void mathed_char_dim(MathTextCodes type, MathMetricsInfo const & size,
559         unsigned char c, int & asc, int & des, int & wid)
560 {
561         LyXFont const font = whichFont(type, size);
562         des = lyxfont::descent(c, font);
563         asc = lyxfont::ascent(c, font);
564         wid = mathed_char_width(type, size, c);
565 }
566
567
568 int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
569         unsigned char c, int & asc, int & des)
570 {
571         LyXFont const font = whichFont(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 const font = whichFont(type, size);
591         return lyxfont::ascent(c, font);
592 }
593
594
595 int mathed_char_descent(MathTextCodes type, MathMetricsInfo const & size,
596         unsigned char c)
597 {
598         LyXFont const font = whichFont(type, size);
599         return lyxfont::descent(c, font);
600 }
601
602
603 int mathed_char_width(MathTextCodes type, MathMetricsInfo const & size,
604         unsigned char c)
605 {
606         LyXFont const font = whichFont(type, size);
607         if (isBinaryOp(c, type))
608                 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
609         else
610                 return lyxfont::width(c, font);
611 }
612
613
614 void mathed_string_dim(MathTextCodes type, MathMetricsInfo const & size,
615         string const & s, int & asc, int & des, int & wid)
616 {
617         mathed_string_height(type, size, s, asc, des);
618         wid = mathed_string_width(type, size, s);
619 }
620
621
622 int mathed_string_height(MathTextCodes type, MathMetricsInfo const & size,
623         string const & s, int & asc, int & des)
624 {
625         LyXFont const font = whichFont(type, size);
626         asc = des = 0;
627         for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
628                 des = max(des, lyxfont::descent(*it, font));
629                 asc = max(asc, lyxfont::ascent(*it, font));
630         }
631         return asc + des;
632 }
633
634
635 int mathed_string_width(MathTextCodes type, MathMetricsInfo const & size,
636         string const & s)
637 {
638         return lyxfont::width(s, whichFont(type, size));
639 }
640
641
642 int mathed_string_ascent(MathTextCodes type, MathMetricsInfo const & size,
643         string const & s)
644 {
645         LyXFont const font = whichFont(type, size);
646         int asc = 0;
647         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
648                 asc = max(asc, lyxfont::ascent(*it, font));
649         return asc;
650 }
651
652
653 int mathed_string_descent(MathTextCodes type, MathMetricsInfo const & size,
654         string const & s)
655 {
656         LyXFont const font = whichFont(type, size);
657         int des = 0;
658         for (string::const_iterator it = s.begin(); it != s.end(); ++it)
659                 des = max(des, lyxfont::descent(*it, font));
660         return des;
661 }
662
663
664
665 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
666         const string & name)
667 {
668         if (name == ".") {
669                 pain.line(x + w/2, y, x + w/2, y + h,
670                           LColor::mathcursor, Painter::line_onoffdash);
671                 return;
672         }       
673         
674         deco_struct const * mds = search_deco(name);
675         if (!mds) {
676                 lyxerr << "Deco was not found. Programming error?\n";
677                 lyxerr << "name: '" << name << "'\n";
678                 return;
679         }
680         
681         int const n = (w < h) ? w : h;
682         int const r = mds->angle;
683         double const * d = mds->data;
684         
685         if (h > 70 && (name == "(" || name == ")"))
686                 d = parenthHigh;
687         
688         Matrix mt(r, w, h);
689         Matrix sqmt(r, n, n);
690
691         if (r > 0 && r < 3)
692                 y += h;
693
694         if (r >= 2)
695                 x += w;
696
697         for (int i = 0; d[i]; ) {
698                 int code = int(d[i++]);
699                 if (code & 1) {  // code == 1 || code == 3
700                         double xx = d[i++];
701                         double yy = d[i++];
702                         double x2 = d[i++];
703                         double y2 = d[i++];
704                         if (code == 3)
705                                 sqmt.transform(xx, yy);
706                         else
707                                 mt.transform(xx, yy);
708                         mt.transform(x2, y2);
709                         pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
710                                         LColor::math);
711                 }       else {
712                         int xp[32];
713                         int yp[32];
714                         int const n = int(d[i++]);
715                         for (int j = 0; j < n; ++j) {
716                                 double xx = d[i++];
717                                 double yy = d[i++];
718 //           lyxerr << " " << xx << " " << yy << " ";
719                                 if (code == 4)
720                                         sqmt.transform(xx, yy);
721                                 else
722                                         mt.transform(xx, yy);
723                                 xp[j] = x + int(xx);
724                                 yp[j] = y + int(yy);
725                                 //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
726                         }
727                         pain.lines(xp, yp, n, LColor::math);
728                 }
729         }
730 }
731
732
733 void mathed_draw_framebox(Painter & pain, int x, int y, MathInset const * p)
734 {
735         if (mathcursor && mathcursor->isInside(p))
736                 pain.rectangle(x, y - p->ascent(), p->width(), p->height(),
737                         LColor::mathframe);
738 }
739
740
741 // In the future maybe we use a better fonts renderer
742 void drawStr(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
743         int x, int y, string const & s)
744 {
745         pain.text(x, y, s, whichFont(type, siz));
746 }
747
748
749 void drawChar(Painter & pain, MathTextCodes type, MathMetricsInfo const & siz,
750         int x, int y, char c)
751 {
752         string s;
753         if (isBinaryOp(c, type))
754                 s += ' ';
755         s += c;
756         if (isBinaryOp(c, type))
757                 s += ' ';
758         drawStr(pain, type, siz, x, y, s);
759 }
760
761
762 // decrease math size for super- and subscripts
763 void smallerStyleScript(MathMetricsInfo & st)
764 {
765         switch (st.style) {
766                 case LM_ST_DISPLAY:
767                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
768                 default:            st.style = LM_ST_SCRIPTSCRIPT;
769         }
770 }
771
772
773 // decrease math size for fractions
774 void smallerStyleFrac(MathMetricsInfo & st)
775 {
776         switch (st.style) {
777                 case LM_ST_DISPLAY: st.style = LM_ST_TEXT; break;
778                 case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
779                 default:            st.style = LM_ST_SCRIPTSCRIPT;
780         }
781 }
782
783
784 void math_font_max_dim(MathTextCodes code, MathMetricsInfo const & siz,
785         int & asc, int & des)
786 {
787         LyXFont font = whichFont(code, siz);
788         asc = lyxfont::maxAscent(font);
789         des = lyxfont::maxDescent(font);
790 }
791
792
793 char const * latex_mathspace[] = {
794         "!", ",", ":", ";", "quad", "qquad"
795 };
796
797
798
799 char const * math_font_name(MathTextCodes code)
800 {
801         static char const * theFontNames[] = {
802                 "mathrm",
803                 "mathcal",
804                 "mathfrak",
805                 "mathbf",
806                 "mathbb",
807                 "mathsf",
808                 "mathtt",
809                 "mathit",
810                 "textrm"
811         };
812
813         if (code >= LM_TC_RM && code <= LM_TC_TEXTRM) 
814                 return theFontNames[code - LM_TC_RM];
815         return 0;
816 }
817
818 string convertDelimToLatexName(string const & name)
819 {
820         if (name == "(")
821                 return name;
822         if (name == "[")
823                 return name;
824         if (name == ".")
825                 return name;
826         if (name == ")")
827                 return name;
828         if (name == "]")
829                 return name;
830         if (name == "/")
831                 return name;
832         if (name == "|")
833                 return name;
834         return "\\" + name + " ";
835 }
836
837