]> git.lyx.org Git - lyx.git/blob - src/mathed/MathSupport.cpp
Cmake build: Creating a define for a header file found
[lyx.git] / src / mathed / MathSupport.cpp
1 /**
2  * \file MathSupport.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "MathSupport.h"
15
16 #include "InsetMath.h"
17 #include "MathData.h"
18 #include "MathParser.h"
19 #include "MathStream.h"
20
21 #include "frontends/FontLoader.h"
22 #include "frontends/FontMetrics.h"
23 #include "frontends/Painter.h"
24
25 #include "support/debug.h"
26 #include "support/docstream.h"
27
28 #include <map>
29
30 using namespace std;
31
32 namespace lyx {
33
34 using frontend::Painter;
35
36
37 ///
38 class Matrix {
39 public:
40         ///
41         Matrix(int, double, double);
42         ///
43         void transform(double &, double &);
44 private:
45         ///
46         double m_[2][2];
47 };
48
49
50 Matrix::Matrix(int code, double x, double y)
51 {
52         double const cs = (code & 1) ? 0 : (1 - code);
53         double const sn = (code & 1) ? (2 - code) : 0;
54         m_[0][0] =  cs * x;
55         m_[0][1] =  sn * x;
56         m_[1][0] = -sn * y;
57         m_[1][1] =  cs * y;
58 }
59
60
61 void Matrix::transform(double & x, double & y)
62 {
63         double xx = m_[0][0] * x + m_[0][1] * y;
64         double yy = m_[1][0] * x + m_[1][1] * y;
65         x = xx;
66         y = yy;
67 }
68
69
70
71 namespace {
72
73 /*
74  * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
75  * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
76  */
77
78
79 double const parenthHigh[] = {
80         2, 13,
81         0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
82         0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
83         0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
84         0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
85         0.9840, 0.9986,
86         0
87 };
88
89
90 double const parenth[] = {
91         2, 13,
92         0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
93         0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
94         0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
95         0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
96         0.9930, 0.9919,
97         0
98 };
99
100
101 double const brace[] = {
102         2, 21,
103         0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
104         0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
105         0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
106         0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
107         0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
108         0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
109         0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
110         0
111 };
112
113
114 double const arrow[] = {
115         4, 7,
116         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
117         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
118         0.9500, 0.7500,
119         3, 0.5000, 0.1500, 0.5000, 0.9500,
120         0
121 };
122
123
124 double const Arrow[] = {
125         4, 7,
126         0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
127         0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
128         0.9500, 0.7500,
129         3, 0.3500, 0.5000, 0.3500, 0.9500,
130         3, 0.6500, 0.5000, 0.6500, 0.9500,
131         0
132 };
133
134
135 double const udarrow[] = {
136         2, 3,
137         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
138         2, 3,
139         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
140         1, 0.5, 0.2,  0.5, 0.8,
141         0
142 };
143
144
145 double const Udarrow[] = {
146         2, 3,
147         0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
148         2, 3,
149         0.015, 0.75,  0.5, 0.95, 0.95, 0.75,
150         1, 0.35, 0.2, 0.35, 0.8,
151         1, 0.65, 0.2, 0.65, 0.8,
152         0
153 };
154
155
156 double const brack[] = {
157         2, 4,
158         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
159         0
160 };
161
162
163 double const dbrack[] = {
164         2, 4,
165         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
166         2, 2,
167         0.50, 0.05,  0.50, 0.95,
168         0
169 };
170
171
172 double const corner[] = {
173         2, 3,
174         0.95, 0.05,  0.05, 0.05,  0.05, 0.95,
175         0
176 };
177
178
179 double const angle[] = {
180         2, 3,
181         1, 0,  0.05, 0.5,  1, 1,
182         0
183 };
184
185
186 double const slash[] = {
187         1, 0.95, 0.05, 0.05, 0.95,
188         0
189 };
190
191
192 double const hline[] = {
193         1, 0.00, 0.5, 1.0, 0.5,
194         0
195 };
196
197
198 double const ddot[] = {
199         1, 0.2, 0.5, 0.3, 0.5,
200         1, 0.7, 0.5, 0.8, 0.5,
201         0
202 };
203
204
205 double const dddot[] = {
206         1, 0.1,  0.5, 0.2,  0.5,
207         1, 0.45, 0.5, 0.55, 0.5,
208         1, 0.8,  0.5, 0.9,  0.5,
209         0
210 };
211
212
213 double const ddddot[] = {
214         1, 0.1,  0.5, 0.2,  0.5,
215         1, 0.45, 0.5, 0.55, 0.5,
216         1, 0.8,  0.5, 0.9,  0.5,
217         1, 1.15, 0.5, 1.25, 0.5,
218         0
219 };
220
221
222 double const hline3[] = {
223         1, 0.1,   0,  0.15,  0,
224         1, 0.475, 0,  0.525, 0,
225         1, 0.85,  0,  0.9,   0,
226         0
227 };
228
229
230 double const dline3[] = {
231         1, 0.1,   0.1,   0.15,  0.15,
232         1, 0.475, 0.475, 0.525, 0.525,
233         1, 0.85,  0.85,  0.9,   0.9,
234         0
235 };
236
237
238 double const hlinesmall[] = {
239         1, 0.4, 0.5, 0.6, 0.5,
240         0
241 };
242
243
244 double const ring[] = {
245         2, 5,
246         0.5, 0.8,  0.8, 0.5,  0.5, 0.2,  0.2, 0.5,  0.5, 0.8,
247         0
248 };
249
250
251 double const vert[] = {
252         1, 0.5, 0.05,  0.5, 0.95,
253         0
254 };
255
256
257 double const  Vert[] = {
258         1, 0.3, 0.05,  0.3, 0.95,
259         1, 0.7, 0.05,  0.7, 0.95,
260         0
261 };
262
263
264 double const tilde[] = {
265         2, 4,
266         0.00, 0.8,  0.25, 0.2,  0.75, 0.8,  1.00, 0.2,
267         0
268 };
269
270
271 struct deco_struct {
272         double const * data;
273         int angle;
274 };
275
276 struct named_deco_struct {
277         char const * name;
278         double const * data;
279         int angle;
280 };
281
282 named_deco_struct deco_table[] = {
283         // Decorations
284         {"widehat",             angle,    3 },
285         {"widetilde",           tilde,    0 },
286         {"underbar",            hline,    0 },
287         {"underline",           hline,    0 },
288         {"overline",            hline,    0 },
289         {"underbrace",          brace,    1 },
290         {"overbrace",           brace,    3 },
291         {"overleftarrow",       arrow,    1 },
292         {"overrightarrow",      arrow,    3 },
293         {"overleftrightarrow",  udarrow,  1 },
294         {"xleftarrow",          arrow,    1 },
295         {"xrightarrow",         arrow,    3 },
296         {"underleftarrow",      arrow,    1 },
297         {"underrightarrow",     arrow,    3 },
298         {"underleftrightarrow", udarrow,  1 },
299         {"undertilde",          tilde,    0 },
300         {"utilde",              tilde,    0 },
301
302         // Delimiters
303         {"(",              parenth,    0 },
304         {")",              parenth,    2 },
305         {"{",              brace,      0 },
306         {"}",              brace,      2 },
307         {"lbrace",         brace,      0 },
308         {"rbrace",         brace,      2 },
309         {"[",              brack,      0 },
310         {"]",              brack,      2 },
311         {"llbracket",      dbrack,     0 },
312         {"rrbracket",      dbrack,     2 },
313         {"|",              vert,       0 },
314         {"/",              slash,      0 },
315         {"slash",          slash,      0 },
316         {"vert",           vert,       0 },
317         {"Vert",           Vert,       0 },
318         {"'",              slash,      1 },
319         {"<",              angle,      0 },
320         {">",              angle,      2 },
321         {"\\",             slash,      1 },
322         {"backslash",      slash,      1 },
323         {"langle",         angle,      0 },
324         {"lceil",          corner,     0 },
325         {"lfloor",         corner,     1 },
326         {"rangle",         angle,      2 },
327         {"rceil",          corner,     3 },
328         {"rfloor",         corner,     2 },
329         {"downarrow",      arrow,      2 },
330         {"Downarrow",      Arrow,      2 },
331         {"uparrow",        arrow,      0 },
332         {"Uparrow",        Arrow,      0 },
333         {"updownarrow",    udarrow,    0 },
334         {"Updownarrow",    Udarrow,    0 },
335
336         // Accents
337         {"ddot",           ddot,       0 },
338         {"dddot",          dddot,      0 },
339         {"ddddot",         ddddot,     0 },
340         {"hat",            angle,      3 },
341         {"grave",          slash,      1 },
342         {"acute",          slash,      0 },
343         {"tilde",          tilde,      0 },
344         {"bar",            hline,      0 },
345         {"dot",            hlinesmall, 0 },
346         {"check",          angle,      1 },
347         {"breve",          parenth,    1 },
348         {"vec",            arrow,      3 },
349         {"mathring",       ring,       0 },
350
351         // Dots
352         {"dots",           hline3,     0 },
353         {"ldots",          hline3,     0 },
354         {"cdots",          hline3,     0 },
355         {"vdots",          hline3,     1 },
356         {"ddots",          dline3,     0 },
357         {"adots",          dline3,     1 },
358         {"iddots",         dline3,     1 },
359         {"dotsb",          hline3,     0 },
360         {"dotsc",          hline3,     0 },
361         {"dotsi",          hline3,     0 },
362         {"dotsm",          hline3,     0 },
363         {"dotso",          hline3,     0 }
364 };
365
366
367 map<docstring, deco_struct> deco_list;
368
369 // sort the table on startup
370 class init_deco_table {
371 public:
372         init_deco_table() {
373                 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
374                 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
375                         deco_struct d;
376                         d.data  = p->data;
377                         d.angle = p->angle;
378                         deco_list[from_ascii(p->name)] = d;
379                 }
380         }
381 };
382
383 static init_deco_table dummy;
384
385
386 deco_struct const * search_deco(docstring const & name)
387 {
388         map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
389         return p == deco_list.end() ? 0 : &(p->second);
390 }
391
392
393 } // namespace anon
394
395
396 int mathed_char_width(FontInfo const & font, char_type c)
397 {
398         return theFontMetrics(font).width(c);
399 }
400
401
402 int mathed_char_kerning(FontInfo const & font, char_type c)
403 {
404         frontend::FontMetrics const & fm = theFontMetrics(font);
405         return fm.rbearing(c) - fm.width(c);
406 }
407
408
409 void mathed_string_dim(FontInfo const & font,
410                        docstring const & s,
411                        Dimension & dim)
412 {
413         frontend::FontMetrics const & fm = theFontMetrics(font);
414         dim.asc = 0;
415         dim.des = 0;
416         for (docstring::const_iterator it = s.begin();
417              it != s.end();
418              ++it) {
419                 dim.asc = max(dim.asc, fm.ascent(*it));
420                 dim.des = max(dim.des, fm.descent(*it));
421         }
422         dim.wid = fm.width(s);
423 }
424
425
426 int mathed_string_width(FontInfo const & font, docstring const & s)
427 {
428         return theFontMetrics(font).width(s);
429 }
430
431
432 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
433         docstring const & name)
434 {
435         if (name == ".") {
436                 pi.pain.line(x + w/2, y, x + w/2, y + h,
437                           Color_cursor, Painter::line_onoffdash);
438                 return;
439         }
440
441         deco_struct const * mds = search_deco(name);
442         if (!mds) {
443                 lyxerr << "Deco was not found. Programming error?" << endl;
444                 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
445                 return;
446         }
447
448         int const n = (w < h) ? w : h;
449         int const r = mds->angle;
450         double const * d = mds->data;
451
452         if (h > 70 && (name == "(" || name == ")"))
453                 d = parenthHigh;
454
455         Matrix mt(r, w, h);
456         Matrix sqmt(r, n, n);
457
458         if (r > 0 && r < 3)
459                 y += h;
460
461         if (r >= 2)
462                 x += w;
463
464         for (int i = 0; d[i]; ) {
465                 int code = int(d[i++]);
466                 if (code & 1) {  // code == 1 || code == 3
467                         double xx = d[i++];
468                         double yy = d[i++];
469                         double x2 = d[i++];
470                         double y2 = d[i++];
471                         if (code == 3)
472                                 sqmt.transform(xx, yy);
473                         else
474                                 mt.transform(xx, yy);
475                         mt.transform(x2, y2);
476                         pi.pain.line(
477                                 int(x + xx + 0.5), int(y + yy + 0.5),
478                                 int(x + x2 + 0.5), int(y + y2 + 0.5),
479                                 pi.base.font.color());
480                 } else {
481                         int xp[32];
482                         int yp[32];
483                         int const n = int(d[i++]);
484                         for (int j = 0; j < n; ++j) {
485                                 double xx = d[i++];
486                                 double yy = d[i++];
487 //           lyxerr << ' ' << xx << ' ' << yy << ' ';
488                                 if (code == 4)
489                                         sqmt.transform(xx, yy);
490                                 else
491                                         mt.transform(xx, yy);
492                                 xp[j] = int(x + xx + 0.5);
493                                 yp[j] = int(y + yy + 0.5);
494                                 //  lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
495                         }
496                         pi.pain.lines(xp, yp, n, pi.base.font.color());
497                 }
498         }
499 }
500
501
502 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
503 {
504         FontInfo font = mi.base.font;
505         augmentFont(font, from_ascii("mathnormal"));
506         mathed_string_dim(font, str, dim);
507 }
508
509
510 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
511 {
512         FontInfo f = pi.base.font;
513         augmentFont(f, from_ascii("mathnormal"));
514         f.setColor(Color_latex);
515         pi.pain.text(x, y, str, f);
516 }
517
518
519 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
520 {
521         FontInfo f = pi.base.font;
522         augmentFont(f, from_ascii("mathnormal"));
523         f.setColor(Color_foreground);
524         pi.pain.text(x, y, str, f);
525 }
526
527
528 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
529 {
530         frontend::FontMetrics const & fm = theFontMetrics(font);
531         asc = fm.maxAscent();
532         des = fm.maxDescent();
533 }
534
535
536 struct fontinfo {
537         string cmd_;
538         FontFamily family_;
539         FontSeries series_;
540         FontShape  shape_;
541         ColorCode        color_;
542 };
543
544
545 FontFamily const inh_family = INHERIT_FAMILY;
546 FontSeries const inh_series = INHERIT_SERIES;
547 FontShape  const inh_shape  = INHERIT_SHAPE;
548
549
550 // mathnormal should be the first, otherwise the fallback further down
551 // does not work
552 fontinfo fontinfos[] = {
553         // math fonts
554         {"mathnormal",    ROMAN_FAMILY, MEDIUM_SERIES,
555                           ITALIC_SHAPE, Color_math},
556         {"mathbf",        inh_family, BOLD_SERIES,
557                           inh_shape, Color_math},
558         {"mathcal",       CMSY_FAMILY, inh_series,
559                           inh_shape, Color_math},
560         {"mathfrak",      EUFRAK_FAMILY, inh_series,
561                           inh_shape, Color_math},
562         {"mathrm",        ROMAN_FAMILY, inh_series,
563                           UP_SHAPE, Color_math},
564         {"mathsf",        SANS_FAMILY, inh_series,
565                           inh_shape, Color_math},
566         {"mathbb",        MSB_FAMILY, inh_series,
567                           inh_shape, Color_math},
568         {"mathtt",        TYPEWRITER_FAMILY, inh_series,
569                           inh_shape, Color_math},
570         {"mathit",        inh_family, inh_series,
571                           ITALIC_SHAPE, Color_math},
572         {"mathscr",       RSFS_FAMILY, inh_series,
573                   inh_shape, Color_math}, 
574         {"cmex",          CMEX_FAMILY, inh_series,
575                           inh_shape, Color_math},
576         {"cmm",           CMM_FAMILY, inh_series,
577                           inh_shape, Color_math},
578         {"cmr",           CMR_FAMILY, inh_series,
579                           inh_shape, Color_math},
580         {"cmsy",          CMSY_FAMILY, inh_series,
581                           inh_shape, Color_math},
582         {"eufrak",        EUFRAK_FAMILY, inh_series,
583                           inh_shape, Color_math},
584         {"msa",           MSA_FAMILY, inh_series,
585                           inh_shape, Color_math},
586         {"msb",           MSB_FAMILY, inh_series,
587                           inh_shape, Color_math},
588         {"stmry",         STMARY_FAMILY, inh_series,
589                           inh_shape, Color_math},
590         {"wasy",          WASY_FAMILY, inh_series,
591                           inh_shape, Color_math},
592         {"esint",         ESINT_FAMILY, inh_series,
593                           inh_shape, Color_math},
594
595         // Text fonts
596         {"text",          inh_family, inh_series,
597                           inh_shape, Color_foreground},
598         {"textbf",        inh_family, BOLD_SERIES,
599                           inh_shape, Color_foreground},
600         {"textit",        inh_family, inh_series,
601                           ITALIC_SHAPE, Color_foreground},
602         {"textmd",        inh_family, MEDIUM_SERIES,
603                           inh_shape, Color_foreground},
604         {"textnormal",    inh_family, inh_series,
605                           UP_SHAPE, Color_foreground},
606         {"textrm",        ROMAN_FAMILY,
607                           inh_series, UP_SHAPE,Color_foreground},
608         {"textsc",        inh_family, inh_series,
609                           SMALLCAPS_SHAPE, Color_foreground},
610         {"textsf",        SANS_FAMILY, inh_series,
611                           inh_shape, Color_foreground},
612         {"textsl",        inh_family, inh_series,
613                           SLANTED_SHAPE, Color_foreground},
614         {"texttt",        TYPEWRITER_FAMILY, inh_series,
615                           inh_shape, Color_foreground},
616         {"textup",        inh_family, inh_series,
617                           UP_SHAPE, Color_foreground},
618
619         // TIPA support
620         {"textipa",       inh_family, inh_series,
621                           inh_shape, Color_foreground},
622
623         // mhchem support
624         {"ce",            inh_family, inh_series,
625                           inh_shape, Color_foreground},
626         {"cf",            inh_family, inh_series,
627                           inh_shape, Color_foreground},
628
629         // LyX internal usage
630         {"lyxtex",        inh_family, inh_series,
631                           UP_SHAPE, Color_latex},
632         {"lyxsymbol",     SYMBOL_FAMILY, inh_series,
633                           inh_shape, Color_math},
634         {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
635                           inh_shape, Color_math},
636         {"lyxblacktext",  ROMAN_FAMILY, MEDIUM_SERIES,
637                           UP_SHAPE, Color_foreground},
638         {"lyxnochange",   inh_family, inh_series,
639                           inh_shape, Color_foreground},
640         {"lyxfakebb",     TYPEWRITER_FAMILY, BOLD_SERIES,
641                           UP_SHAPE, Color_math},
642         {"lyxfakecal",    SANS_FAMILY, MEDIUM_SERIES,
643                           ITALIC_SHAPE, Color_math},
644         {"lyxfakefrak",   ROMAN_FAMILY, BOLD_SERIES,
645                           ITALIC_SHAPE, Color_math}
646 };
647
648
649 fontinfo * lookupFont(docstring const & name0)
650 {
651         //lyxerr << "searching font '" << name << "'" << endl;
652         int const n = sizeof(fontinfos) / sizeof(fontinfo);
653         string name = to_utf8(name0);
654         for (int i = 0; i < n; ++i)
655                 if (fontinfos[i].cmd_ == name) {
656                         //lyxerr << "found '" << i << "'" << endl;
657                         return fontinfos + i;
658                 }
659         return 0;
660 }
661
662
663 fontinfo * searchFont(docstring const & name)
664 {
665         fontinfo * f = lookupFont(name);
666         return f ? f : fontinfos;
667         // this should be mathnormal
668         //return searchFont("mathnormal");
669 }
670
671
672 bool isFontName(docstring const & name)
673 {
674         return lookupFont(name);
675 }
676
677
678 bool isMathFont(docstring const & name)
679 {
680         fontinfo * f = lookupFont(name);
681         return f && f->color_ == Color_math;
682 }
683
684
685 bool isTextFont(docstring const & name)
686 {
687         fontinfo * f = lookupFont(name);
688         return f && f->color_ == Color_foreground;
689 }
690
691
692 FontInfo getFont(docstring const & name)
693 {
694         FontInfo font;
695         augmentFont(font, name);
696         return font;
697 }
698
699
700 void fakeFont(docstring const & orig, docstring const & fake)
701 {
702         fontinfo * forig = searchFont(orig);
703         fontinfo * ffake = searchFont(fake);
704         if (forig && ffake) {
705                 forig->family_ = ffake->family_;
706                 forig->series_ = ffake->series_;
707                 forig->shape_  = ffake->shape_;
708                 forig->color_  = ffake->color_;
709         } else {
710                 lyxerr << "Can't fake font '" << to_utf8(orig) << "' with '"
711                        << to_utf8(fake) << "'" << endl;
712         }
713 }
714
715
716 void augmentFont(FontInfo & font, docstring const & name)
717 {
718         static bool initialized = false;
719         if (!initialized) {
720                 initialized = true;
721                 // fake fonts if necessary
722                 if (!theFontLoader().available(getFont(from_ascii("mathfrak"))))
723                         fakeFont(from_ascii("mathfrak"), from_ascii("lyxfakefrak"));
724                 if (!theFontLoader().available(getFont(from_ascii("mathcal"))))
725                         fakeFont(from_ascii("mathcal"), from_ascii("lyxfakecal"));
726         }
727         fontinfo * info = searchFont(name);
728         if (info->family_ != inh_family)
729                 font.setFamily(info->family_);
730         if (info->series_ != inh_series)
731                 font.setSeries(info->series_);
732         if (info->shape_ != inh_shape)
733                 font.setShape(info->shape_);
734         if (info->color_ != Color_none)
735                 font.setColor(info->color_);
736 }
737
738
739 docstring asString(MathData const & ar)
740 {
741         odocstringstream os;
742         WriteStream ws(os);
743         ws << ar;
744         return os.str();
745 }
746
747
748 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
749 {
750         bool quiet = pf & Parse::QUIET;
751         if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
752                 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
753 }
754
755
756 docstring asString(InsetMath const & inset)
757 {
758         odocstringstream os;
759         WriteStream ws(os);
760         inset.write(ws);
761         return os.str();
762 }
763
764
765 docstring asString(MathAtom const & at)
766 {
767         odocstringstream os;
768         WriteStream ws(os);
769         at->write(ws);
770         return os.str();
771 }
772
773
774 } // namespace lyx