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"
20 #include "MathParser.h"
21 #include "MathStream.h"
23 #include "MetricsInfo.h"
25 #include "frontends/FontLoader.h"
26 #include "frontends/FontMetrics.h"
27 #include "frontends/Painter.h"
29 #include "support/debug.h"
30 #include "support/docstream.h"
31 #include "support/lassert.h"
32 #include "support/lyxlib.h"
41 using frontend::Painter;
48 Matrix(int, double, double);
50 void transform(double &, double &);
57 Matrix::Matrix(int code, double x, double y)
59 double const cs = (code & 1) ? 0 : (1 - code);
60 double const sn = (code & 1) ? (2 - code) : 0;
68 void Matrix::transform(double & x, double & y)
70 double xx = m_[0][0] * x + m_[0][1] * y;
71 double yy = m_[1][0] * x + m_[1][1] * y;
81 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
82 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
86 double const parenthHigh[] = {
88 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
89 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
90 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
91 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
97 double const parenth[] = {
99 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
100 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
101 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
102 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
108 double const brace[] = {
110 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
111 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
112 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
113 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
114 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
115 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
116 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
121 double const mapsto[] = {
123 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
124 1, 0.015, 0.475, 0.945, 0.475,
125 1, 0.015, 0.015, 0.015, 0.985,
130 double const lhook[] = {
132 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
133 1, 0.015, 0.475, 0.7, 0.475,
135 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
136 0.825, 0.35, 0.7, 0.475,
141 double const rhook[] = {
143 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
144 1, 0.3, 0.475, 0.985, 0.475,
146 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
147 0.175, 0.35, 0.3, 0.475,
152 double const LRArrow[] = {
154 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
156 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
157 1, 0.2, 0.8, 0.8, 0.8,
158 1, 0.2, 0.2, 0.8, 0.2,
163 double const LArrow[] = {
165 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
166 1, 0.2, 0.8, 0.985, 0.8,
167 1, 0.2, 0.2, 0.985, 0.2,
172 double const lharpoondown[] = {
174 0.015, 0.5, 0.25, 0.985,
175 1, 0.02, 0.475, 0.985, 0.475,
180 double const lharpoonup[] = {
182 0.25, 0.015, 0.015, 0.5,
183 1, 0.02, 0.525, 0.985, 0.525,
188 double const lrharpoons[] = {
190 0.25, 0.015, 0.015, 0.225,
191 1, 0.02, 0.23, 0.985, 0.23,
193 0.75, 0.985, 0.985, 0.775,
194 1, 0.02, 0.7, 0.980, 0.7,
199 double const rlharpoons[] = {
201 0.75, 0.015, 0.985, 0.225,
202 1, 0.02, 0.23, 0.985, 0.23,
204 0.25, 0.985, 0.015, 0.775,
205 1, 0.02, 0.7, 0.980, 0.7,
210 double const arrow[] = {
212 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
213 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
215 3, 0.5000, 0.1500, 0.5000, 0.9500,
220 double const Arrow[] = {
222 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
223 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
225 3, 0.3500, 0.5000, 0.3500, 0.9500,
226 3, 0.6500, 0.5000, 0.6500, 0.9500,
231 double const udarrow[] = {
233 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
235 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
236 1, 0.5, 0.1, 0.5, 0.9,
241 double const Udarrow[] = {
243 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
245 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
246 1, 0.35, 0.2, 0.35, 0.8,
247 1, 0.65, 0.2, 0.65, 0.8,
252 double const brack[] = {
254 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
259 double const dbrack[] = {
261 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
263 0.50, 0.05, 0.50, 0.95,
268 double const corner[] = {
270 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
275 double const angle[] = {
277 1, 0, 0.05, 0.5, 1, 1,
282 double const slash[] = {
283 1, 0.95, 0.05, 0.05, 0.95,
288 double const hline[] = {
289 1, 0.00, 0.5, 1.0, 0.5,
294 double const ddot[] = {
295 1, 0.2, 0.5, 0.3, 0.5,
296 1, 0.7, 0.5, 0.8, 0.5,
301 double const dddot[] = {
302 1, 0.1, 0.5, 0.2, 0.5,
303 1, 0.45, 0.5, 0.55, 0.5,
304 1, 0.8, 0.5, 0.9, 0.5,
309 double const ddddot[] = {
310 1, 0.1, 0.5, 0.2, 0.5,
311 1, 0.45, 0.5, 0.55, 0.5,
312 1, 0.8, 0.5, 0.9, 0.5,
313 1, 1.15, 0.5, 1.25, 0.5,
318 double const hline3[] = {
320 1, 0.475, 0, 0.525, 0,
326 double const dline3[] = {
327 1, 0.1, 0.1, 0.15, 0.15,
328 1, 0.475, 0.475, 0.525, 0.525,
329 1, 0.85, 0.85, 0.9, 0.9,
334 double const hlinesmall[] = {
335 1, 0.4, 0.5, 0.6, 0.5,
340 double const ring[] = {
342 0.5, 0.8, 0.8, 0.5, 0.5, 0.2, 0.2, 0.5, 0.5, 0.8,
347 double const vert[] = {
348 1, 0.5, 0.05, 0.5, 0.95,
353 double const Vert[] = {
354 1, 0.3, 0.05, 0.3, 0.95,
355 1, 0.7, 0.05, 0.7, 0.95,
360 double const tilde[] = {
362 0.00, 0.8, 0.25, 0.2, 0.75, 0.8, 1.00, 0.2,
372 struct named_deco_struct {
378 named_deco_struct deco_table[] = {
380 {"widehat", angle, 3 },
381 {"widetilde", tilde, 0 },
382 {"underbar", hline, 0 },
383 {"underline", hline, 0 },
384 {"overline", hline, 0 },
385 {"underbrace", brace, 1 },
386 {"overbrace", brace, 3 },
387 {"overleftarrow", arrow, 1 },
388 {"overrightarrow", arrow, 3 },
389 {"overleftrightarrow", udarrow, 1 },
390 {"xhookleftarrow", lhook, 0 },
391 {"xhookrightarrow", rhook, 0 },
392 {"xleftarrow", arrow, 1 },
393 {"xLeftarrow", LArrow, 0 },
394 {"xleftharpoondown", lharpoondown, 0 },
395 {"xleftharpoonup", lharpoonup, 0 },
396 {"xleftrightharpoons", lrharpoons, 0 },
397 {"xleftrightarrow", udarrow, 1 },
398 {"xLeftrightarrow", LRArrow, 0 },
399 {"xmapsto", mapsto, 0 },
400 {"xrightarrow", arrow, 3 },
401 {"xRightarrow", LArrow, 2 },
402 {"xrightharpoondown", lharpoonup, 2 },
403 {"xrightharpoonup", lharpoondown, 2 },
404 {"xrightleftharpoons", rlharpoons, 0 },
405 {"underleftarrow", arrow, 1 },
406 {"underrightarrow", arrow, 3 },
407 {"underleftrightarrow", udarrow, 1 },
408 {"undertilde", tilde, 0 },
409 {"utilde", tilde, 0 },
416 {"lbrace", brace, 0 },
417 {"rbrace", brace, 2 },
420 {"llbracket", dbrack, 0 },
421 {"rrbracket", dbrack, 2 },
424 {"slash", slash, 0 },
435 {"backslash", slash, 1 },
436 {"langle", angle, 0 },
437 {"lceil", corner, 0 },
438 {"lfloor", corner, 1 },
439 {"rangle", angle, 2 },
440 {"rceil", corner, 3 },
441 {"rfloor", corner, 2 },
442 {"downarrow", arrow, 2 },
443 {"Downarrow", Arrow, 2 },
444 {"uparrow", arrow, 0 },
445 {"Uparrow", Arrow, 0 },
446 {"updownarrow", udarrow, 0 },
447 {"Updownarrow", Udarrow, 0 },
451 {"dddot", dddot, 0 },
452 {"ddddot", ddddot, 0 },
454 {"grave", slash, 1 },
455 {"acute", slash, 0 },
456 {"tilde", tilde, 0 },
458 {"dot", hlinesmall, 0 },
459 {"check", angle, 1 },
460 {"breve", parenth, 1 },
462 {"mathring", ring, 0 },
465 {"dots", hline3, 0 },
466 {"ldots", hline3, 0 },
467 {"cdots", hline3, 0 },
468 {"vdots", hline3, 1 },
469 {"ddots", dline3, 0 },
470 {"adots", dline3, 1 },
471 {"iddots", dline3, 1 },
472 {"dotsb", hline3, 0 },
473 {"dotsc", hline3, 0 },
474 {"dotsi", hline3, 0 },
475 {"dotsm", hline3, 0 },
476 {"dotso", hline3, 0 }
480 map<docstring, deco_struct> deco_list;
482 // sort the table on startup
483 class init_deco_table {
486 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
487 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
491 deco_list[from_ascii(p->name)] = d;
496 static init_deco_table dummy;
499 deco_struct const * search_deco(docstring const & name)
501 map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
502 return p == deco_list.end() ? 0 : &(p->second);
509 int mathed_font_em(FontInfo const & font)
511 return theFontMetrics(font).em();
514 /* The math units. Quoting TeX by Topic, p.205:
516 * Spacing around mathematical objects is measured in mu units. A mu
517 * is 1/18th part of \fontdimen6 of the font in family 2 in the
518 * current style, the ‘quad’ value of the symbol font.
520 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
521 * inserted around (binary) relations, except where these are preceded
522 * or followed by other relations or punctuation, and except if they
523 * follow an open, or precede a close symbol.
525 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
526 * is put around binary operators.
528 * A \thinmuskip (default value in plain TeX: 3mu) follows after
529 * punctuation, and is put around inner objects, except where these
530 * are followed by a close or preceded by an open symbol, and except
531 * if the other object is a large operator or a binary relation.
533 * See the file MathClass.cpp for a formal implementation of the rules
537 int mathed_mu(FontInfo const & font, double mu)
539 MetricsBase mb(nullptr, font);
540 return Length(mu, Length::MU).inPixels(mb);
543 int mathed_thinmuskip(FontInfo const & font) { return mathed_mu(font, 3.0); }
544 int mathed_medmuskip(FontInfo const & font) { return mathed_mu(font, 4.0); }
545 int mathed_thickmuskip(FontInfo const & font) { return mathed_mu(font, 5.0); }
548 int mathed_char_width(FontInfo const & font, char_type c)
550 return theFontMetrics(font).width(c);
554 int mathed_char_kerning(FontInfo const & font, char_type c)
556 frontend::FontMetrics const & fm = theFontMetrics(font);
557 return fm.rbearing(c) - fm.width(c);
561 void mathed_string_dim(FontInfo const & font,
565 frontend::FontMetrics const & fm = theFontMetrics(font);
568 for (docstring::const_iterator it = s.begin();
571 dim.asc = max(dim.asc, fm.ascent(*it));
572 dim.des = max(dim.des, fm.descent(*it));
574 dim.wid = fm.width(s);
578 int mathed_string_width(FontInfo const & font, docstring const & s)
580 return theFontMetrics(font).width(s);
584 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
585 docstring const & name)
588 pi.pain.line(x + w/2, y, x + w/2, y + h,
589 Color_cursor, Painter::line_onoffdash);
593 deco_struct const * mds = search_deco(name);
595 lyxerr << "Deco was not found. Programming error?" << endl;
596 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
600 int const n = (w < h) ? w : h;
601 int const r = mds->angle;
602 double const * d = mds->data;
604 if (h > 70 && (name == "(" || name == ")"))
608 Matrix sqmt(r, n, n);
616 for (int i = 0; d[i]; ) {
617 int code = int(d[i++]);
618 if (code & 1) { // code == 1 || code == 3
624 sqmt.transform(xx, yy);
626 mt.transform(xx, yy);
627 mt.transform(x2, y2);
629 int(x + xx + 0.5), int(y + yy + 0.5),
630 int(x + x2 + 0.5), int(y + y2 + 0.5),
631 pi.base.font.color());
635 int const n = int(d[i++]);
636 for (int j = 0; j < n; ++j) {
639 // lyxerr << ' ' << xx << ' ' << yy << ' ';
641 sqmt.transform(xx, yy);
643 mt.transform(xx, yy);
644 xp[j] = int(x + xx + 0.5);
645 yp[j] = int(y + yy + 0.5);
646 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
648 pi.pain.lines(xp, yp, n, pi.base.font.color());
654 void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
656 LASSERT((bool)sym, return);
657 //lyxerr << "metrics: symbol: '" << sym->name
658 // << "' in font: '" << sym->inset
659 // << "' drawn as: '" << sym->draw
662 bool const italic_upcase_greek = sym->inset == "cmr" &&
663 sym->extra == "mathalpha" &&
664 mb.fontname == "mathit";
665 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
666 Changer dummy = mb.changeFontSet(font);
667 mathed_string_dim(mb.font, sym->draw, dim);
671 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
673 LASSERT((bool)sym, return);
674 //lyxerr << "drawing: symbol: '" << sym->name
675 // << "' in font: '" << sym->inset
676 // << "' drawn as: '" << sym->draw
679 bool const italic_upcase_greek = sym->inset == "cmr" &&
680 sym->extra == "mathalpha" &&
681 pi.base.fontname == "mathit";
682 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
684 Changer dummy = pi.base.changeFontSet(font);
685 pi.draw(x, y, sym->draw);
689 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
691 FontInfo font = mi.base.font;
692 augmentFont(font, "mathnormal");
693 mathed_string_dim(font, str, dim);
697 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
699 FontInfo f = pi.base.font;
700 augmentFont(f, "mathnormal");
701 f.setColor(Color_latex);
702 pi.pain.text(x, y, str, f);
706 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
708 FontInfo f = pi.base.font;
709 augmentFont(f, "mathnormal");
710 f.setColor(Color_foreground);
711 pi.pain.text(x, y, str, f);
715 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
717 frontend::FontMetrics const & fm = theFontMetrics(font);
718 asc = fm.maxAscent();
719 des = fm.maxDescent();
732 FontFamily const inh_family = INHERIT_FAMILY;
733 FontSeries const inh_series = INHERIT_SERIES;
734 FontShape const inh_shape = INHERIT_SHAPE;
737 // mathnormal should be the first, otherwise the fallback further down
739 fontinfo fontinfos[] = {
741 // Color_math determines which fonts are math (see isMathFont)
742 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
743 ITALIC_SHAPE, Color_math},
744 {"mathbf", inh_family, BOLD_SERIES,
745 inh_shape, Color_math},
746 {"mathcal", CMSY_FAMILY, inh_series,
747 inh_shape, Color_math},
748 {"mathfrak", EUFRAK_FAMILY, inh_series,
749 inh_shape, Color_math},
750 {"mathrm", ROMAN_FAMILY, inh_series,
751 UP_SHAPE, Color_math},
752 {"mathsf", SANS_FAMILY, inh_series,
753 inh_shape, Color_math},
754 {"mathbb", MSB_FAMILY, inh_series,
755 inh_shape, Color_math},
756 {"mathtt", TYPEWRITER_FAMILY, inh_series,
757 inh_shape, Color_math},
758 {"mathit", inh_family, inh_series,
759 ITALIC_SHAPE, Color_math},
760 {"mathscr", RSFS_FAMILY, inh_series,
761 inh_shape, Color_math},
762 {"cmex", CMEX_FAMILY, inh_series,
763 inh_shape, Color_math},
764 {"cmm", CMM_FAMILY, inh_series,
765 inh_shape, Color_math},
766 {"cmr", CMR_FAMILY, inh_series,
767 inh_shape, Color_math},
768 {"cmsy", CMSY_FAMILY, inh_series,
769 inh_shape, Color_math},
770 {"eufrak", EUFRAK_FAMILY, inh_series,
771 inh_shape, Color_math},
772 {"msa", MSA_FAMILY, inh_series,
773 inh_shape, Color_math},
774 {"msb", MSB_FAMILY, inh_series,
775 inh_shape, Color_math},
776 {"stmry", STMARY_FAMILY, inh_series,
777 inh_shape, Color_math},
778 {"wasy", WASY_FAMILY, inh_series,
779 inh_shape, Color_math},
780 {"esint", ESINT_FAMILY, inh_series,
781 inh_shape, Color_math},
784 {"text", inh_family, inh_series,
785 inh_shape, Color_foreground},
786 {"textbf", inh_family, BOLD_SERIES,
787 inh_shape, Color_foreground},
788 {"textit", inh_family, inh_series,
789 ITALIC_SHAPE, Color_foreground},
790 {"textmd", inh_family, MEDIUM_SERIES,
791 inh_shape, Color_foreground},
792 {"textnormal", inh_family, inh_series,
793 UP_SHAPE, Color_foreground},
794 {"textrm", ROMAN_FAMILY,
795 inh_series, UP_SHAPE,Color_foreground},
796 {"textsc", inh_family, inh_series,
797 SMALLCAPS_SHAPE, Color_foreground},
798 {"textsf", SANS_FAMILY, inh_series,
799 inh_shape, Color_foreground},
800 {"textsl", inh_family, inh_series,
801 SLANTED_SHAPE, Color_foreground},
802 {"texttt", TYPEWRITER_FAMILY, inh_series,
803 inh_shape, Color_foreground},
804 {"textup", inh_family, inh_series,
805 UP_SHAPE, Color_foreground},
808 {"textipa", inh_family, inh_series,
809 inh_shape, Color_foreground},
812 {"ce", inh_family, inh_series,
813 inh_shape, Color_foreground},
814 {"cf", inh_family, inh_series,
815 inh_shape, Color_foreground},
817 // LyX internal usage
818 {"lyxtex", inh_family, inh_series,
819 UP_SHAPE, Color_latex},
820 // FIXME: The following two don't work on OS X, since the Symbol font
821 // uses a different encoding, and is therefore disabled in
822 // FontLoader::available().
823 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
824 inh_shape, Color_math},
825 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
826 inh_shape, Color_math},
827 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
828 UP_SHAPE, Color_foreground},
829 {"lyxnochange", inh_family, inh_series,
830 inh_shape, Color_foreground},
831 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
832 UP_SHAPE, Color_math},
833 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
834 ITALIC_SHAPE, Color_math},
835 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
836 ITALIC_SHAPE, Color_math}
840 fontinfo * lookupFont(string const & name)
842 //lyxerr << "searching font '" << name << "'" << endl;
843 int const n = sizeof(fontinfos) / sizeof(fontinfo);
844 for (int i = 0; i < n; ++i)
845 if (fontinfos[i].cmd_ == name) {
846 //lyxerr << "found '" << i << "'" << endl;
847 return fontinfos + i;
853 fontinfo * searchFont(string const & name)
855 fontinfo * f = lookupFont(name);
856 return f ? f : fontinfos;
857 // this should be mathnormal
858 //return searchFont("mathnormal");
862 bool isFontName(string const & name)
864 return lookupFont(name);
868 bool isMathFont(string const & name)
870 fontinfo * f = lookupFont(name);
871 return f && f->color_ == Color_math;
875 bool isTextFont(string const & name)
877 fontinfo * f = lookupFont(name);
878 return f && f->color_ == Color_foreground;
882 FontInfo getFont(string const & name)
885 augmentFont(font, name);
890 void fakeFont(string const & orig, string const & fake)
892 fontinfo * forig = searchFont(orig);
893 fontinfo * ffake = searchFont(fake);
894 if (forig && ffake) {
895 forig->family_ = ffake->family_;
896 forig->series_ = ffake->series_;
897 forig->shape_ = ffake->shape_;
898 forig->color_ = ffake->color_;
900 lyxerr << "Can't fake font '" << orig << "' with '"
901 << fake << "'" << endl;
906 void augmentFont(FontInfo & font, string const & name)
908 static bool initialized = false;
911 // fake fonts if necessary
912 if (!theFontLoader().available(getFont("mathfrak")))
913 fakeFont("mathfrak", "lyxfakefrak");
914 if (!theFontLoader().available(getFont("mathcal")))
915 fakeFont("mathcal", "lyxfakecal");
917 fontinfo * info = searchFont(name);
918 if (info->family_ != inh_family)
919 font.setFamily(info->family_);
920 if (info->series_ != inh_series)
921 font.setSeries(info->series_);
922 if (info->shape_ != inh_shape)
923 font.setShape(info->shape_);
924 if (info->color_ != Color_none)
925 font.setColor(info->color_);
929 bool isAlphaSymbol(MathAtom const & at)
931 if (at->asCharInset() ||
932 (at->asSymbolInset() &&
933 at->asSymbolInset()->isOrdAlpha()))
936 if (at->asFontInset()) {
937 MathData const & ar = at->asFontInset()->cell(0);
938 for (size_t i = 0; i < ar.size(); ++i) {
939 if (!(ar[i]->asCharInset() ||
940 (ar[i]->asSymbolInset() &&
941 ar[i]->asSymbolInset()->isOrdAlpha())))
950 docstring asString(MathData const & ar)
953 otexrowstream ots(os);
960 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
962 bool quiet = pf & Parse::QUIET;
963 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
964 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
968 docstring asString(InsetMath const & inset)
971 otexrowstream ots(os);
978 docstring asString(MathAtom const & at)
981 otexrowstream ots(os);