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.
532 * See the file MathClass.cpp for a formal implementation of the rules
536 int mathed_thinmuskip(FontInfo font)
538 font.setFamily(SYMBOL_FAMILY);
539 return support::iround(3.0 / 18 * theFontMetrics(font).em());
543 int mathed_medmuskip(FontInfo font)
545 font.setFamily(SYMBOL_FAMILY);
546 return support::iround(4.0 / 18 * theFontMetrics(font).em());
550 int mathed_thickmuskip(FontInfo font)
552 font.setFamily(SYMBOL_FAMILY);
553 return support::iround(5.0 / 18 * theFontMetrics(font).em());
557 int mathed_char_width(FontInfo const & font, char_type c)
559 return theFontMetrics(font).width(c);
563 int mathed_char_kerning(FontInfo const & font, char_type c)
565 frontend::FontMetrics const & fm = theFontMetrics(font);
566 return fm.rbearing(c) - fm.width(c);
570 void mathed_string_dim(FontInfo const & font,
574 frontend::FontMetrics const & fm = theFontMetrics(font);
577 for (docstring::const_iterator it = s.begin();
580 dim.asc = max(dim.asc, fm.ascent(*it));
581 dim.des = max(dim.des, fm.descent(*it));
583 dim.wid = fm.width(s);
587 int mathed_string_width(FontInfo const & font, docstring const & s)
589 return theFontMetrics(font).width(s);
593 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
594 docstring const & name)
597 pi.pain.line(x + w/2, y, x + w/2, y + h,
598 Color_cursor, Painter::line_onoffdash);
602 deco_struct const * mds = search_deco(name);
604 lyxerr << "Deco was not found. Programming error?" << endl;
605 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
609 int const n = (w < h) ? w : h;
610 int const r = mds->angle;
611 double const * d = mds->data;
613 if (h > 70 && (name == "(" || name == ")"))
617 Matrix sqmt(r, n, n);
625 for (int i = 0; d[i]; ) {
626 int code = int(d[i++]);
627 if (code & 1) { // code == 1 || code == 3
633 sqmt.transform(xx, yy);
635 mt.transform(xx, yy);
636 mt.transform(x2, y2);
638 int(x + xx + 0.5), int(y + yy + 0.5),
639 int(x + x2 + 0.5), int(y + y2 + 0.5),
640 pi.base.font.color());
644 int const n = int(d[i++]);
645 for (int j = 0; j < n; ++j) {
648 // lyxerr << ' ' << xx << ' ' << yy << ' ';
650 sqmt.transform(xx, yy);
652 mt.transform(xx, yy);
653 xp[j] = int(x + xx + 0.5);
654 yp[j] = int(y + yy + 0.5);
655 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
657 pi.pain.lines(xp, yp, n, pi.base.font.color());
663 void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
665 LASSERT((bool)sym, return);
666 //lyxerr << "metrics: symbol: '" << sym->name
667 // << "' in font: '" << sym->inset
668 // << "' drawn as: '" << sym->draw
671 bool const italic_upcase_greek = sym->inset == "cmr" &&
672 sym->extra == "mathalpha" &&
673 mb.fontname == "mathit";
674 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
675 Changer dummy = mb.changeFontSet(font);
676 mathed_string_dim(mb.font, sym->draw, dim);
680 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
682 LASSERT((bool)sym, return);
683 //lyxerr << "drawing: symbol: '" << sym->name
684 // << "' in font: '" << sym->inset
685 // << "' drawn as: '" << sym->draw
688 bool const italic_upcase_greek = sym->inset == "cmr" &&
689 sym->extra == "mathalpha" &&
690 pi.base.fontname == "mathit";
691 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
693 Changer dummy = pi.base.changeFontSet(font);
694 pi.draw(x, y, sym->draw);
698 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
700 FontInfo font = mi.base.font;
701 augmentFont(font, "mathnormal");
702 mathed_string_dim(font, str, dim);
706 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
708 FontInfo f = pi.base.font;
709 augmentFont(f, "mathnormal");
710 f.setColor(Color_latex);
711 pi.pain.text(x, y, str, f);
715 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
717 FontInfo f = pi.base.font;
718 augmentFont(f, "mathnormal");
719 f.setColor(Color_foreground);
720 pi.pain.text(x, y, str, f);
724 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
726 frontend::FontMetrics const & fm = theFontMetrics(font);
727 asc = fm.maxAscent();
728 des = fm.maxDescent();
741 FontFamily const inh_family = INHERIT_FAMILY;
742 FontSeries const inh_series = INHERIT_SERIES;
743 FontShape const inh_shape = INHERIT_SHAPE;
746 // mathnormal should be the first, otherwise the fallback further down
748 fontinfo fontinfos[] = {
750 // Color_math determines which fonts are math (see isMathFont)
751 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
752 ITALIC_SHAPE, Color_math},
753 {"mathbf", inh_family, BOLD_SERIES,
754 inh_shape, Color_math},
755 {"mathcal", CMSY_FAMILY, inh_series,
756 inh_shape, Color_math},
757 {"mathfrak", EUFRAK_FAMILY, inh_series,
758 inh_shape, Color_math},
759 {"mathrm", ROMAN_FAMILY, inh_series,
760 UP_SHAPE, Color_math},
761 {"mathsf", SANS_FAMILY, inh_series,
762 inh_shape, Color_math},
763 {"mathbb", MSB_FAMILY, inh_series,
764 inh_shape, Color_math},
765 {"mathtt", TYPEWRITER_FAMILY, inh_series,
766 inh_shape, Color_math},
767 {"mathit", inh_family, inh_series,
768 ITALIC_SHAPE, Color_math},
769 {"mathscr", RSFS_FAMILY, inh_series,
770 inh_shape, Color_math},
771 {"cmex", CMEX_FAMILY, inh_series,
772 inh_shape, Color_math},
773 {"cmm", CMM_FAMILY, inh_series,
774 inh_shape, Color_math},
775 {"cmr", CMR_FAMILY, inh_series,
776 inh_shape, Color_math},
777 {"cmsy", CMSY_FAMILY, inh_series,
778 inh_shape, Color_math},
779 {"eufrak", EUFRAK_FAMILY, inh_series,
780 inh_shape, Color_math},
781 {"msa", MSA_FAMILY, inh_series,
782 inh_shape, Color_math},
783 {"msb", MSB_FAMILY, inh_series,
784 inh_shape, Color_math},
785 {"stmry", STMARY_FAMILY, inh_series,
786 inh_shape, Color_math},
787 {"wasy", WASY_FAMILY, inh_series,
788 inh_shape, Color_math},
789 {"esint", ESINT_FAMILY, inh_series,
790 inh_shape, Color_math},
793 {"text", inh_family, inh_series,
794 inh_shape, Color_foreground},
795 {"textbf", inh_family, BOLD_SERIES,
796 inh_shape, Color_foreground},
797 {"textit", inh_family, inh_series,
798 ITALIC_SHAPE, Color_foreground},
799 {"textmd", inh_family, MEDIUM_SERIES,
800 inh_shape, Color_foreground},
801 {"textnormal", inh_family, inh_series,
802 UP_SHAPE, Color_foreground},
803 {"textrm", ROMAN_FAMILY,
804 inh_series, UP_SHAPE,Color_foreground},
805 {"textsc", inh_family, inh_series,
806 SMALLCAPS_SHAPE, Color_foreground},
807 {"textsf", SANS_FAMILY, inh_series,
808 inh_shape, Color_foreground},
809 {"textsl", inh_family, inh_series,
810 SLANTED_SHAPE, Color_foreground},
811 {"texttt", TYPEWRITER_FAMILY, inh_series,
812 inh_shape, Color_foreground},
813 {"textup", inh_family, inh_series,
814 UP_SHAPE, Color_foreground},
817 {"textipa", inh_family, inh_series,
818 inh_shape, Color_foreground},
821 {"ce", inh_family, inh_series,
822 inh_shape, Color_foreground},
823 {"cf", inh_family, inh_series,
824 inh_shape, Color_foreground},
826 // LyX internal usage
827 {"lyxtex", inh_family, inh_series,
828 UP_SHAPE, Color_latex},
829 // FIXME: The following two don't work on OS X, since the Symbol font
830 // uses a different encoding, and is therefore disabled in
831 // FontLoader::available().
832 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
833 inh_shape, Color_math},
834 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
835 inh_shape, Color_math},
836 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
837 UP_SHAPE, Color_foreground},
838 {"lyxnochange", inh_family, inh_series,
839 inh_shape, Color_foreground},
840 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
841 UP_SHAPE, Color_math},
842 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
843 ITALIC_SHAPE, Color_math},
844 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
845 ITALIC_SHAPE, Color_math}
849 fontinfo * lookupFont(string const & name)
851 //lyxerr << "searching font '" << name << "'" << endl;
852 int const n = sizeof(fontinfos) / sizeof(fontinfo);
853 for (int i = 0; i < n; ++i)
854 if (fontinfos[i].cmd_ == name) {
855 //lyxerr << "found '" << i << "'" << endl;
856 return fontinfos + i;
862 fontinfo * searchFont(string const & name)
864 fontinfo * f = lookupFont(name);
865 return f ? f : fontinfos;
866 // this should be mathnormal
867 //return searchFont("mathnormal");
871 bool isFontName(string const & name)
873 return lookupFont(name);
877 bool isMathFont(string const & name)
879 fontinfo * f = lookupFont(name);
880 return f && f->color_ == Color_math;
884 bool isTextFont(string const & name)
886 fontinfo * f = lookupFont(name);
887 return f && f->color_ == Color_foreground;
891 FontInfo getFont(string const & name)
894 augmentFont(font, name);
899 void fakeFont(string const & orig, string const & fake)
901 fontinfo * forig = searchFont(orig);
902 fontinfo * ffake = searchFont(fake);
903 if (forig && ffake) {
904 forig->family_ = ffake->family_;
905 forig->series_ = ffake->series_;
906 forig->shape_ = ffake->shape_;
907 forig->color_ = ffake->color_;
909 lyxerr << "Can't fake font '" << orig << "' with '"
910 << fake << "'" << endl;
915 void augmentFont(FontInfo & font, string const & name)
917 static bool initialized = false;
920 // fake fonts if necessary
921 if (!theFontLoader().available(getFont("mathfrak")))
922 fakeFont("mathfrak", "lyxfakefrak");
923 if (!theFontLoader().available(getFont("mathcal")))
924 fakeFont("mathcal", "lyxfakecal");
926 fontinfo * info = searchFont(name);
927 if (info->family_ != inh_family)
928 font.setFamily(info->family_);
929 if (info->series_ != inh_series)
930 font.setSeries(info->series_);
931 if (info->shape_ != inh_shape)
932 font.setShape(info->shape_);
933 if (info->color_ != Color_none)
934 font.setColor(info->color_);
938 bool isAlphaSymbol(MathAtom const & at)
940 if (at->asCharInset() ||
941 (at->asSymbolInset() &&
942 at->asSymbolInset()->isOrdAlpha()))
945 if (at->asFontInset()) {
946 MathData const & ar = at->asFontInset()->cell(0);
947 for (size_t i = 0; i < ar.size(); ++i) {
948 if (!(ar[i]->asCharInset() ||
949 (ar[i]->asSymbolInset() &&
950 ar[i]->asSymbolInset()->isOrdAlpha())))
959 docstring asString(MathData const & ar)
962 otexrowstream ots(os);
969 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
971 bool quiet = pf & Parse::QUIET;
972 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
973 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
977 docstring asString(InsetMath const & inset)
980 otexrowstream ots(os);
987 docstring asString(MathAtom const & at)
990 otexrowstream ots(os);