2 * \file MathSupport.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
9 * Full author contact details are available in file CREDITS.
14 #include "MathSupport.h"
16 #include "InsetMathFont.h"
17 #include "InsetMathSymbol.h"
19 #include "MathParser.h"
20 #include "MathStream.h"
22 #include "MetricsInfo.h"
24 #include "frontends/FontLoader.h"
25 #include "frontends/FontMetrics.h"
26 #include "frontends/Painter.h"
28 #include "support/debug.h"
29 #include "support/docstream.h"
30 #include "support/lassert.h"
31 #include "support/lyxlib.h"
40 using frontend::Painter;
47 Matrix(int, double, double);
49 void transform(double &, double &);
56 Matrix::Matrix(int code, double x, double y)
58 double const cs = (code & 1) ? 0 : (1 - code);
59 double const sn = (code & 1) ? (2 - code) : 0;
67 void Matrix::transform(double & x, double & y)
69 double xx = m_[0][0] * x + m_[0][1] * y;
70 double yy = m_[1][0] * x + m_[1][1] * y;
80 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
81 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
85 double const parenthHigh[] = {
87 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
88 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
89 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
90 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
96 double const parenth[] = {
98 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
99 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
100 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
101 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
107 double const brace[] = {
109 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
110 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
111 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
112 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
113 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
114 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
115 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
120 double const mapsto[] = {
122 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
123 1, 0.015, 0.475, 0.945, 0.475,
124 1, 0.015, 0.015, 0.015, 0.985,
129 double const lhook[] = {
131 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
132 1, 0.015, 0.475, 0.7, 0.475,
134 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
135 0.825, 0.35, 0.7, 0.475,
140 double const rhook[] = {
142 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
143 1, 0.3, 0.475, 0.985, 0.475,
145 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
146 0.175, 0.35, 0.3, 0.475,
151 double const LRArrow[] = {
153 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
155 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
156 1, 0.2, 0.8, 0.8, 0.8,
157 1, 0.2, 0.2, 0.8, 0.2,
162 double const LArrow[] = {
164 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
165 1, 0.2, 0.8, 0.985, 0.8,
166 1, 0.2, 0.2, 0.985, 0.2,
171 double const lharpoondown[] = {
173 0.015, 0.5, 0.25, 0.985,
174 1, 0.02, 0.475, 0.985, 0.475,
179 double const lharpoonup[] = {
181 0.25, 0.015, 0.015, 0.5,
182 1, 0.02, 0.525, 0.985, 0.525,
187 double const lrharpoons[] = {
189 0.25, 0.015, 0.015, 0.225,
190 1, 0.02, 0.23, 0.985, 0.23,
192 0.75, 0.985, 0.985, 0.775,
193 1, 0.02, 0.7, 0.980, 0.7,
198 double const rlharpoons[] = {
200 0.75, 0.015, 0.985, 0.225,
201 1, 0.02, 0.23, 0.985, 0.23,
203 0.25, 0.985, 0.015, 0.775,
204 1, 0.02, 0.7, 0.980, 0.7,
209 double const arrow[] = {
211 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
212 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
214 3, 0.5000, 0.1500, 0.5000, 0.9500,
219 double const Arrow[] = {
221 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
222 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
224 3, 0.3500, 0.5000, 0.3500, 0.9500,
225 3, 0.6500, 0.5000, 0.6500, 0.9500,
230 double const udarrow[] = {
232 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
234 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
235 1, 0.5, 0.1, 0.5, 0.9,
240 double const Udarrow[] = {
242 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
244 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
245 1, 0.35, 0.2, 0.35, 0.8,
246 1, 0.65, 0.2, 0.65, 0.8,
251 double const brack[] = {
253 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
258 double const dbrack[] = {
260 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
262 0.50, 0.05, 0.50, 0.95,
267 double const corner[] = {
269 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
274 double const angle[] = {
276 1, 0, 0.05, 0.5, 1, 1,
281 double const slash[] = {
282 1, 0.95, 0.05, 0.05, 0.95,
287 double const hline[] = {
288 1, 0.00, 0.5, 1.0, 0.5,
293 double const ddot[] = {
294 1, 0.2, 0.5, 0.3, 0.5,
295 1, 0.7, 0.5, 0.8, 0.5,
300 double const dddot[] = {
301 1, 0.1, 0.5, 0.2, 0.5,
302 1, 0.45, 0.5, 0.55, 0.5,
303 1, 0.8, 0.5, 0.9, 0.5,
308 double const ddddot[] = {
309 1, 0.1, 0.5, 0.2, 0.5,
310 1, 0.45, 0.5, 0.55, 0.5,
311 1, 0.8, 0.5, 0.9, 0.5,
312 1, 1.15, 0.5, 1.25, 0.5,
317 double const hline3[] = {
319 1, 0.475, 0, 0.525, 0,
325 double const dline3[] = {
326 1, 0.1, 0.1, 0.15, 0.15,
327 1, 0.475, 0.475, 0.525, 0.525,
328 1, 0.85, 0.85, 0.9, 0.9,
333 double const hlinesmall[] = {
334 1, 0.4, 0.5, 0.6, 0.5,
339 double const ring[] = {
341 0.5, 0.8, 0.8, 0.5, 0.5, 0.2, 0.2, 0.5, 0.5, 0.8,
346 double const vert[] = {
347 1, 0.5, 0.05, 0.5, 0.95,
352 double const Vert[] = {
353 1, 0.3, 0.05, 0.3, 0.95,
354 1, 0.7, 0.05, 0.7, 0.95,
359 double const tilde[] = {
361 0.00, 0.8, 0.25, 0.2, 0.75, 0.8, 1.00, 0.2,
371 struct named_deco_struct {
377 named_deco_struct deco_table[] = {
379 {"widehat", angle, 3 },
380 {"widetilde", tilde, 0 },
381 {"underbar", hline, 0 },
382 {"underline", hline, 0 },
383 {"overline", hline, 0 },
384 {"underbrace", brace, 1 },
385 {"overbrace", brace, 3 },
386 {"overleftarrow", arrow, 1 },
387 {"overrightarrow", arrow, 3 },
388 {"overleftrightarrow", udarrow, 1 },
389 {"xhookleftarrow", lhook, 0 },
390 {"xhookrightarrow", rhook, 0 },
391 {"xleftarrow", arrow, 1 },
392 {"xLeftarrow", LArrow, 0 },
393 {"xleftharpoondown", lharpoondown, 0 },
394 {"xleftharpoonup", lharpoonup, 0 },
395 {"xleftrightharpoons", lrharpoons, 0 },
396 {"xleftrightarrow", udarrow, 1 },
397 {"xLeftrightarrow", LRArrow, 0 },
398 {"xmapsto", mapsto, 0 },
399 {"xrightarrow", arrow, 3 },
400 {"xRightarrow", LArrow, 2 },
401 {"xrightharpoondown", lharpoonup, 2 },
402 {"xrightharpoonup", lharpoondown, 2 },
403 {"xrightleftharpoons", rlharpoons, 0 },
404 {"underleftarrow", arrow, 1 },
405 {"underrightarrow", arrow, 3 },
406 {"underleftrightarrow", udarrow, 1 },
407 {"undertilde", tilde, 0 },
408 {"utilde", tilde, 0 },
415 {"lbrace", brace, 0 },
416 {"rbrace", brace, 2 },
419 {"llbracket", dbrack, 0 },
420 {"rrbracket", dbrack, 2 },
423 {"slash", slash, 0 },
434 {"backslash", slash, 1 },
435 {"langle", angle, 0 },
436 {"lceil", corner, 0 },
437 {"lfloor", corner, 1 },
438 {"rangle", angle, 2 },
439 {"rceil", corner, 3 },
440 {"rfloor", corner, 2 },
441 {"downarrow", arrow, 2 },
442 {"Downarrow", Arrow, 2 },
443 {"uparrow", arrow, 0 },
444 {"Uparrow", Arrow, 0 },
445 {"updownarrow", udarrow, 0 },
446 {"Updownarrow", Udarrow, 0 },
450 {"dddot", dddot, 0 },
451 {"ddddot", ddddot, 0 },
453 {"grave", slash, 1 },
454 {"acute", slash, 0 },
455 {"tilde", tilde, 0 },
457 {"dot", hlinesmall, 0 },
458 {"check", angle, 1 },
459 {"breve", parenth, 1 },
461 {"mathring", ring, 0 },
464 {"dots", hline3, 0 },
465 {"ldots", hline3, 0 },
466 {"cdots", hline3, 0 },
467 {"vdots", hline3, 1 },
468 {"ddots", dline3, 0 },
469 {"adots", dline3, 1 },
470 {"iddots", dline3, 1 },
471 {"dotsb", hline3, 0 },
472 {"dotsc", hline3, 0 },
473 {"dotsi", hline3, 0 },
474 {"dotsm", hline3, 0 },
475 {"dotso", hline3, 0 }
479 map<docstring, deco_struct> deco_list;
481 // sort the table on startup
482 class init_deco_table {
485 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
486 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
490 deco_list[from_ascii(p->name)] = d;
495 static init_deco_table dummy;
498 deco_struct const * search_deco(docstring const & name)
500 map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
501 return p == deco_list.end() ? 0 : &(p->second);
508 int mathed_font_em(FontInfo const & font)
510 return theFontMetrics(font).em();
513 /* The math units. Quoting TeX by Topic, p.205:
515 * Spacing around mathematical objects is measured in mu units. A mu
516 * is 1/18th part of \fontdimen6 of the font in family 2 in the
517 * current style, the ‘quad’ value of the symbol font.
519 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
520 * inserted around (binary) relations, except where these are preceded
521 * or followed by other relations or punctuation, and except if they
522 * follow an open, or precede a close symbol.
524 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
525 * is put around binary operators.
527 * A \thinmuskip (default value in plain TeX: 3mu) follows after
528 * punctuation, and is put around inner objects, except where these
529 * are followed by a close or preceded by an open symbol, and except
530 * if the other object is a large operator or a binary relation.
533 int mathed_thinmuskip(FontInfo font)
535 font.setFamily(SYMBOL_FAMILY);
536 return support::iround(3.0 / 18 * theFontMetrics(font).em());
540 int mathed_medmuskip(FontInfo font)
542 font.setFamily(SYMBOL_FAMILY);
543 return support::iround(4.0 / 18 * theFontMetrics(font).em());
547 int mathed_thickmuskip(FontInfo font)
549 font.setFamily(SYMBOL_FAMILY);
550 return support::iround(5.0 / 18 * theFontMetrics(font).em());
554 int mathed_char_width(FontInfo const & font, char_type c)
556 return theFontMetrics(font).width(c);
560 int mathed_char_kerning(FontInfo const & font, char_type c)
562 frontend::FontMetrics const & fm = theFontMetrics(font);
563 return fm.rbearing(c) - fm.width(c);
567 void mathed_string_dim(FontInfo const & font,
571 frontend::FontMetrics const & fm = theFontMetrics(font);
574 for (docstring::const_iterator it = s.begin();
577 dim.asc = max(dim.asc, fm.ascent(*it));
578 dim.des = max(dim.des, fm.descent(*it));
580 dim.wid = fm.width(s);
584 int mathed_string_width(FontInfo const & font, docstring const & s)
586 return theFontMetrics(font).width(s);
590 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
591 docstring const & name)
594 pi.pain.line(x + w/2, y, x + w/2, y + h,
595 Color_cursor, Painter::line_onoffdash);
599 deco_struct const * mds = search_deco(name);
601 lyxerr << "Deco was not found. Programming error?" << endl;
602 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
606 int const n = (w < h) ? w : h;
607 int const r = mds->angle;
608 double const * d = mds->data;
610 if (h > 70 && (name == "(" || name == ")"))
614 Matrix sqmt(r, n, n);
622 for (int i = 0; d[i]; ) {
623 int code = int(d[i++]);
624 if (code & 1) { // code == 1 || code == 3
630 sqmt.transform(xx, yy);
632 mt.transform(xx, yy);
633 mt.transform(x2, y2);
635 int(x + xx + 0.5), int(y + yy + 0.5),
636 int(x + x2 + 0.5), int(y + y2 + 0.5),
637 pi.base.font.color());
641 int const n = int(d[i++]);
642 for (int j = 0; j < n; ++j) {
645 // lyxerr << ' ' << xx << ' ' << yy << ' ';
647 sqmt.transform(xx, yy);
649 mt.transform(xx, yy);
650 xp[j] = int(x + xx + 0.5);
651 yp[j] = int(y + yy + 0.5);
652 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
654 pi.pain.lines(xp, yp, n, pi.base.font.color());
660 void mathedSymbolDim(MetricsInfo & mi, Dimension & dim, latexkeys const * sym)
662 LASSERT((bool)sym, return);
663 //lyxerr << "metrics: symbol: '" << sym->name
664 // << "' in font: '" << sym->inset
665 // << "' drawn as: '" << sym->draw
668 bool const italic_upcase_greek = sym->inset == "cmr" &&
669 sym->extra == "mathalpha" &&
670 mi.base.fontname == "mathit";
671 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
672 Changer dummy = mi.base.changeFontSet(font);
673 mathed_string_dim(mi.base.font, sym->draw, dim);
677 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
679 LASSERT((bool)sym, return);
680 //lyxerr << "drawing: symbol: '" << sym->name
681 // << "' in font: '" << sym->inset
682 // << "' drawn as: '" << sym->draw
685 bool const italic_upcase_greek = sym->inset == "cmr" &&
686 sym->extra == "mathalpha" &&
687 pi.base.fontname == "mathit";
688 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
690 Changer dummy = pi.base.changeFontSet(font);
691 pi.draw(x, y, sym->draw);
695 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
697 FontInfo font = mi.base.font;
698 augmentFont(font, "mathnormal");
699 mathed_string_dim(font, str, dim);
703 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
705 FontInfo f = pi.base.font;
706 augmentFont(f, "mathnormal");
707 f.setColor(Color_latex);
708 pi.pain.text(x, y, str, f);
712 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
714 FontInfo f = pi.base.font;
715 augmentFont(f, "mathnormal");
716 f.setColor(Color_foreground);
717 pi.pain.text(x, y, str, f);
721 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
723 frontend::FontMetrics const & fm = theFontMetrics(font);
724 asc = fm.maxAscent();
725 des = fm.maxDescent();
738 FontFamily const inh_family = INHERIT_FAMILY;
739 FontSeries const inh_series = INHERIT_SERIES;
740 FontShape const inh_shape = INHERIT_SHAPE;
743 // mathnormal should be the first, otherwise the fallback further down
745 fontinfo fontinfos[] = {
747 // Color_math determines which fonts are math (see isMathFont)
748 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
749 ITALIC_SHAPE, Color_math},
750 {"mathbf", inh_family, BOLD_SERIES,
751 inh_shape, Color_math},
752 {"mathcal", CMSY_FAMILY, inh_series,
753 inh_shape, Color_math},
754 {"mathfrak", EUFRAK_FAMILY, inh_series,
755 inh_shape, Color_math},
756 {"mathrm", ROMAN_FAMILY, inh_series,
757 UP_SHAPE, Color_math},
758 {"mathsf", SANS_FAMILY, inh_series,
759 inh_shape, Color_math},
760 {"mathbb", MSB_FAMILY, inh_series,
761 inh_shape, Color_math},
762 {"mathtt", TYPEWRITER_FAMILY, inh_series,
763 inh_shape, Color_math},
764 {"mathit", inh_family, inh_series,
765 ITALIC_SHAPE, Color_math},
766 {"mathscr", RSFS_FAMILY, inh_series,
767 inh_shape, Color_math},
768 {"cmex", CMEX_FAMILY, inh_series,
769 inh_shape, Color_math},
770 {"cmm", CMM_FAMILY, inh_series,
771 inh_shape, Color_math},
772 {"cmr", CMR_FAMILY, inh_series,
773 inh_shape, Color_math},
774 {"cmsy", CMSY_FAMILY, inh_series,
775 inh_shape, Color_math},
776 {"eufrak", EUFRAK_FAMILY, inh_series,
777 inh_shape, Color_math},
778 {"msa", MSA_FAMILY, inh_series,
779 inh_shape, Color_math},
780 {"msb", MSB_FAMILY, inh_series,
781 inh_shape, Color_math},
782 {"stmry", STMARY_FAMILY, inh_series,
783 inh_shape, Color_math},
784 {"wasy", WASY_FAMILY, inh_series,
785 inh_shape, Color_math},
786 {"esint", ESINT_FAMILY, inh_series,
787 inh_shape, Color_math},
790 {"text", inh_family, inh_series,
791 inh_shape, Color_foreground},
792 {"textbf", inh_family, BOLD_SERIES,
793 inh_shape, Color_foreground},
794 {"textit", inh_family, inh_series,
795 ITALIC_SHAPE, Color_foreground},
796 {"textmd", inh_family, MEDIUM_SERIES,
797 inh_shape, Color_foreground},
798 {"textnormal", inh_family, inh_series,
799 UP_SHAPE, Color_foreground},
800 {"textrm", ROMAN_FAMILY,
801 inh_series, UP_SHAPE,Color_foreground},
802 {"textsc", inh_family, inh_series,
803 SMALLCAPS_SHAPE, Color_foreground},
804 {"textsf", SANS_FAMILY, inh_series,
805 inh_shape, Color_foreground},
806 {"textsl", inh_family, inh_series,
807 SLANTED_SHAPE, Color_foreground},
808 {"texttt", TYPEWRITER_FAMILY, inh_series,
809 inh_shape, Color_foreground},
810 {"textup", inh_family, inh_series,
811 UP_SHAPE, Color_foreground},
814 {"textipa", inh_family, inh_series,
815 inh_shape, Color_foreground},
818 {"ce", inh_family, inh_series,
819 inh_shape, Color_foreground},
820 {"cf", inh_family, inh_series,
821 inh_shape, Color_foreground},
823 // LyX internal usage
824 {"lyxtex", inh_family, inh_series,
825 UP_SHAPE, Color_latex},
826 // FIXME: The following two don't work on OS X, since the Symbol font
827 // uses a different encoding, and is therefore disabled in
828 // FontLoader::available().
829 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
830 inh_shape, Color_math},
831 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
832 inh_shape, Color_math},
833 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
834 UP_SHAPE, Color_foreground},
835 {"lyxnochange", inh_family, inh_series,
836 inh_shape, Color_foreground},
837 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
838 UP_SHAPE, Color_math},
839 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
840 ITALIC_SHAPE, Color_math},
841 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
842 ITALIC_SHAPE, Color_math}
846 fontinfo * lookupFont(string const & name)
848 //lyxerr << "searching font '" << name << "'" << endl;
849 int const n = sizeof(fontinfos) / sizeof(fontinfo);
850 for (int i = 0; i < n; ++i)
851 if (fontinfos[i].cmd_ == name) {
852 //lyxerr << "found '" << i << "'" << endl;
853 return fontinfos + i;
859 fontinfo * searchFont(string const & name)
861 fontinfo * f = lookupFont(name);
862 return f ? f : fontinfos;
863 // this should be mathnormal
864 //return searchFont("mathnormal");
868 bool isFontName(string const & name)
870 return lookupFont(name);
874 bool isMathFont(string const & name)
876 fontinfo * f = lookupFont(name);
877 return f && f->color_ == Color_math;
881 bool isTextFont(string const & name)
883 fontinfo * f = lookupFont(name);
884 return f && f->color_ == Color_foreground;
888 FontInfo getFont(string const & name)
891 augmentFont(font, name);
896 void fakeFont(string const & orig, string const & fake)
898 fontinfo * forig = searchFont(orig);
899 fontinfo * ffake = searchFont(fake);
900 if (forig && ffake) {
901 forig->family_ = ffake->family_;
902 forig->series_ = ffake->series_;
903 forig->shape_ = ffake->shape_;
904 forig->color_ = ffake->color_;
906 lyxerr << "Can't fake font '" << orig << "' with '"
907 << fake << "'" << endl;
912 void augmentFont(FontInfo & font, string const & name)
914 static bool initialized = false;
917 // fake fonts if necessary
918 if (!theFontLoader().available(getFont("mathfrak")))
919 fakeFont("mathfrak", "lyxfakefrak");
920 if (!theFontLoader().available(getFont("mathcal")))
921 fakeFont("mathcal", "lyxfakecal");
923 fontinfo * info = searchFont(name);
924 if (info->family_ != inh_family)
925 font.setFamily(info->family_);
926 if (info->series_ != inh_series)
927 font.setSeries(info->series_);
928 if (info->shape_ != inh_shape)
929 font.setShape(info->shape_);
930 if (info->color_ != Color_none)
931 font.setColor(info->color_);
935 bool isAlphaSymbol(MathAtom const & at)
937 if (at->asCharInset() ||
938 (at->asSymbolInset() &&
939 at->asSymbolInset()->isOrdAlpha()))
942 if (at->asFontInset()) {
943 MathData const & ar = at->asFontInset()->cell(0);
944 for (size_t i = 0; i < ar.size(); ++i) {
945 if (!(ar[i]->asCharInset() ||
946 (ar[i]->asSymbolInset() &&
947 ar[i]->asSymbolInset()->isOrdAlpha())))
956 docstring asString(MathData const & ar)
959 otexrowstream ots(os);
966 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
968 bool quiet = pf & Parse::QUIET;
969 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
970 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
974 docstring asString(InsetMath const & inset)
977 otexrowstream ots(os);
984 docstring asString(MathAtom const & at)
987 otexrowstream ots(os);