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 "MathFactory.h"
21 #include "MathParser.h"
22 #include "MathStream.h"
24 #include "LaTeXFeatures.h"
25 #include "MetricsInfo.h"
27 #include "frontends/FontLoader.h"
28 #include "frontends/FontMetrics.h"
29 #include "frontends/Painter.h"
31 #include "support/debug.h"
32 #include "support/docstream.h"
33 #include "support/lassert.h"
34 #include "support/lyxlib.h"
43 using frontend::Painter;
50 Matrix(int, double, double);
52 void transform(double &, double &);
59 Matrix::Matrix(int code, double x, double y)
61 double const cs = (code & 1) ? 0 : (1 - code);
62 double const sn = (code & 1) ? (2 - code) : 0;
70 void Matrix::transform(double & x, double & y)
72 double xx = m_[0][0] * x + m_[0][1] * y;
73 double yy = m_[1][0] * x + m_[1][1] * y;
83 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
84 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
88 double const parenthHigh[] = {
90 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
91 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
92 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
93 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
99 double const parenth[] = {
101 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
102 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
103 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
104 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
110 double const brace[] = {
112 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
113 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
114 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
115 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
116 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
117 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
118 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
123 double const mapsto[] = {
125 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
126 1, 0.015, 0.475, 0.945, 0.475,
127 1, 0.015, 0.015, 0.015, 0.985,
132 double const lhook[] = {
134 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
135 1, 0.015, 0.475, 0.7, 0.475,
137 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
138 0.825, 0.35, 0.7, 0.475,
143 double const rhook[] = {
145 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
146 1, 0.3, 0.475, 0.985, 0.475,
148 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
149 0.175, 0.35, 0.3, 0.475,
154 double const LRArrow[] = {
156 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
158 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
159 1, 0.2, 0.8, 0.8, 0.8,
160 1, 0.2, 0.2, 0.8, 0.2,
165 double const LArrow[] = {
167 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
168 1, 0.2, 0.8, 0.985, 0.8,
169 1, 0.2, 0.2, 0.985, 0.2,
174 double const lharpoondown[] = {
176 0.015, 0.5, 0.25, 0.985,
177 1, 0.02, 0.475, 0.985, 0.475,
182 double const lharpoonup[] = {
184 0.25, 0.015, 0.015, 0.5,
185 1, 0.02, 0.525, 0.985, 0.525,
190 double const lrharpoons[] = {
192 0.25, 0.015, 0.015, 0.225,
193 1, 0.02, 0.23, 0.985, 0.23,
195 0.75, 0.985, 0.985, 0.775,
196 1, 0.02, 0.7, 0.980, 0.7,
201 double const rlharpoons[] = {
203 0.75, 0.015, 0.985, 0.225,
204 1, 0.02, 0.23, 0.985, 0.23,
206 0.25, 0.985, 0.015, 0.775,
207 1, 0.02, 0.7, 0.980, 0.7,
212 double const arrow[] = {
214 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
215 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
217 3, 0.5000, 0.1500, 0.5000, 0.9500,
222 double const Arrow[] = {
224 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
225 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
227 3, 0.3500, 0.5000, 0.3500, 0.9500,
228 3, 0.6500, 0.5000, 0.6500, 0.9500,
233 double const udarrow[] = {
235 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
237 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
238 1, 0.5, 0.1, 0.5, 0.9,
243 double const Udarrow[] = {
245 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
247 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
248 1, 0.35, 0.2, 0.35, 0.8,
249 1, 0.65, 0.2, 0.65, 0.8,
254 double const brack[] = {
256 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
261 double const dbrack[] = {
263 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
265 0.50, 0.05, 0.50, 0.95,
270 double const corner[] = {
272 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
277 double const angle[] = {
279 1, 0, 0.05, 0.5, 1, 1,
284 double const slash[] = {
285 1, 0.95, 0.05, 0.05, 0.95,
290 double const hline[] = {
291 1, 0.00, 0.5, 1.0, 0.5,
296 double const ddot[] = {
297 1, 0.2, 0.5, 0.3, 0.5,
298 1, 0.7, 0.5, 0.8, 0.5,
303 double const dddot[] = {
304 1, 0.1, 0.5, 0.2, 0.5,
305 1, 0.45, 0.5, 0.55, 0.5,
306 1, 0.8, 0.5, 0.9, 0.5,
311 double const ddddot[] = {
312 1, 0.1, 0.5, 0.2, 0.5,
313 1, 0.45, 0.5, 0.55, 0.5,
314 1, 0.8, 0.5, 0.9, 0.5,
315 1, 1.15, 0.5, 1.25, 0.5,
320 double const hline3[] = {
322 1, 0.475, 0, 0.525, 0,
328 double const dline3[] = {
329 1, 0.1, 0.1, 0.15, 0.15,
330 1, 0.475, 0.475, 0.525, 0.525,
331 1, 0.85, 0.85, 0.9, 0.9,
336 double const hlinesmall[] = {
337 1, 0.4, 0.5, 0.6, 0.5,
342 double const ring[] = {
344 0.5, 0.8, 0.8, 0.5, 0.5, 0.2, 0.2, 0.5, 0.5, 0.8,
349 double const vert[] = {
350 1, 0.5, 0.05, 0.5, 0.95,
355 double const Vert[] = {
356 1, 0.3, 0.05, 0.3, 0.95,
357 1, 0.7, 0.05, 0.7, 0.95,
362 double const tilde[] = {
364 0.00, 0.8, 0.25, 0.2, 0.75, 0.8, 1.00, 0.2,
374 struct named_deco_struct {
380 named_deco_struct deco_table[] = {
382 {"widehat", angle, 3 },
383 {"widetilde", tilde, 0 },
384 {"underbar", hline, 0 },
385 {"underline", hline, 0 },
386 {"overline", hline, 0 },
387 {"underbrace", brace, 1 },
388 {"overbrace", brace, 3 },
389 {"overleftarrow", arrow, 1 },
390 {"overrightarrow", arrow, 3 },
391 {"overleftrightarrow", udarrow, 1 },
392 {"xhookleftarrow", lhook, 0 },
393 {"xhookrightarrow", rhook, 0 },
394 {"xleftarrow", arrow, 1 },
395 {"xLeftarrow", LArrow, 0 },
396 {"xleftharpoondown", lharpoondown, 0 },
397 {"xleftharpoonup", lharpoonup, 0 },
398 {"xleftrightharpoons", lrharpoons, 0 },
399 {"xleftrightarrow", udarrow, 1 },
400 {"xLeftrightarrow", LRArrow, 0 },
401 {"xmapsto", mapsto, 0 },
402 {"xrightarrow", arrow, 3 },
403 {"xRightarrow", LArrow, 2 },
404 {"xrightharpoondown", lharpoonup, 2 },
405 {"xrightharpoonup", lharpoondown, 2 },
406 {"xrightleftharpoons", rlharpoons, 0 },
407 {"underleftarrow", arrow, 1 },
408 {"underrightarrow", arrow, 3 },
409 {"underleftrightarrow", udarrow, 1 },
410 {"undertilde", tilde, 0 },
411 {"utilde", tilde, 0 },
418 {"lbrace", brace, 0 },
419 {"rbrace", brace, 2 },
422 {"llbracket", dbrack, 0 },
423 {"rrbracket", dbrack, 2 },
426 {"slash", slash, 0 },
437 {"backslash", slash, 1 },
438 {"langle", angle, 0 },
439 {"lceil", corner, 0 },
440 {"lfloor", corner, 1 },
441 {"rangle", angle, 2 },
442 {"rceil", corner, 3 },
443 {"rfloor", corner, 2 },
444 {"downarrow", arrow, 2 },
445 {"Downarrow", Arrow, 2 },
446 {"uparrow", arrow, 0 },
447 {"Uparrow", Arrow, 0 },
448 {"updownarrow", udarrow, 0 },
449 {"Updownarrow", Udarrow, 0 },
453 {"dddot", dddot, 0 },
454 {"ddddot", ddddot, 0 },
456 {"grave", slash, 1 },
457 {"acute", slash, 0 },
458 {"tilde", tilde, 0 },
460 {"dot", hlinesmall, 0 },
461 {"check", angle, 1 },
462 {"breve", parenth, 1 },
464 {"mathring", ring, 0 },
467 {"dots", hline3, 0 },
468 {"ldots", hline3, 0 },
469 {"cdots", hline3, 0 },
470 {"vdots", hline3, 1 },
471 {"ddots", dline3, 0 },
472 {"adots", dline3, 1 },
473 {"iddots", dline3, 1 },
474 {"dotsb", hline3, 0 },
475 {"dotsc", hline3, 0 },
476 {"dotsi", hline3, 0 },
477 {"dotsm", hline3, 0 },
478 {"dotso", hline3, 0 }
482 map<docstring, deco_struct> deco_list;
484 // sort the table on startup
485 class init_deco_table {
488 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
489 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
493 deco_list[from_ascii(p->name)] = d;
498 static init_deco_table dummy;
501 deco_struct const * search_deco(docstring const & name)
503 map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
504 return p == deco_list.end() ? 0 : &(p->second);
511 int mathed_font_em(FontInfo const & font)
513 return theFontMetrics(font).em();
516 /* The math units. Quoting TeX by Topic, p.205:
518 * Spacing around mathematical objects is measured in mu units. A mu
519 * is 1/18th part of \fontdimen6 of the font in family 2 in the
520 * current style, the ‘quad’ value of the symbol font.
522 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
523 * inserted around (binary) relations, except where these are preceded
524 * or followed by other relations or punctuation, and except if they
525 * follow an open, or precede a close symbol.
527 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
528 * is put around binary operators.
530 * A \thinmuskip (default value in plain TeX: 3mu) follows after
531 * punctuation, and is put around inner objects, except where these
532 * are followed by a close or preceded by an open symbol, and except
533 * if the other object is a large operator or a binary relation.
535 * See the file MathClass.cpp for a formal implementation of the rules
539 int mathed_mu(FontInfo const & font, double mu)
541 MetricsBase mb(nullptr, font);
542 return Length(mu, Length::MU).inPixels(mb);
545 int mathed_thinmuskip(FontInfo const & font) { return mathed_mu(font, 3.0); }
546 int mathed_medmuskip(FontInfo const & font) { return mathed_mu(font, 4.0); }
547 int mathed_thickmuskip(FontInfo const & font) { return mathed_mu(font, 5.0); }
550 int mathed_char_width(FontInfo const & font, char_type c)
552 return theFontMetrics(font).width(c);
556 int mathed_char_kerning(FontInfo const & font, char_type c)
558 frontend::FontMetrics const & fm = theFontMetrics(font);
559 return max(0, fm.rbearing(c) - fm.width(c));
563 void mathed_string_dim(FontInfo const & font,
567 frontend::FontMetrics const & fm = theFontMetrics(font);
570 for (docstring::const_iterator it = s.begin();
573 dim.asc = max(dim.asc, fm.ascent(*it));
574 dim.des = max(dim.des, fm.descent(*it));
576 dim.wid = fm.width(s);
580 int mathed_string_width(FontInfo const & font, docstring const & s)
582 return theFontMetrics(font).width(s);
586 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
587 docstring const & name)
590 pi.pain.line(x + w/2, y, x + w/2, y + h,
591 Color_cursor, Painter::line_onoffdash);
595 deco_struct const * mds = search_deco(name);
597 lyxerr << "Deco was not found. Programming error?" << endl;
598 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
602 int const n = (w < h) ? w : h;
603 int const r = mds->angle;
604 double const * d = mds->data;
606 if (h > 70 && (name == "(" || name == ")"))
610 Matrix sqmt(r, n, n);
618 for (int i = 0; d[i]; ) {
619 int code = int(d[i++]);
620 if (code & 1) { // code == 1 || code == 3
626 sqmt.transform(xx, yy);
628 mt.transform(xx, yy);
629 mt.transform(x2, y2);
631 int(x + xx + 0.5), int(y + yy + 0.5),
632 int(x + x2 + 0.5), int(y + y2 + 0.5),
633 pi.base.font.color());
637 int const n = int(d[i++]);
638 for (int j = 0; j < n; ++j) {
641 // lyxerr << ' ' << xx << ' ' << yy << ' ';
643 sqmt.transform(xx, yy);
645 mt.transform(xx, yy);
646 xp[j] = int(x + xx + 0.5);
647 yp[j] = int(y + yy + 0.5);
648 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
650 pi.pain.lines(xp, yp, n, pi.base.font.color());
656 void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
658 LASSERT((bool)sym, return);
659 //lyxerr << "metrics: symbol: '" << sym->name
660 // << "' in font: '" << sym->inset
661 // << "' drawn as: '" << sym->draw
664 bool const italic_upcase_greek = sym->inset == "cmr" &&
665 sym->extra == "mathalpha" &&
666 mb.fontname == "mathit";
667 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
668 Changer dummy = mb.changeFontSet(font);
669 mathed_string_dim(mb.font, sym->draw, dim);
673 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
675 LASSERT((bool)sym, return);
676 //lyxerr << "drawing: symbol: '" << sym->name
677 // << "' in font: '" << sym->inset
678 // << "' drawn as: '" << sym->draw
681 bool const italic_upcase_greek = sym->inset == "cmr" &&
682 sym->extra == "mathalpha" &&
683 pi.base.fontname == "mathit";
684 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
686 Changer dummy = pi.base.changeFontSet(font);
687 pi.draw(x, y, sym->draw);
691 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
693 FontInfo font = mi.base.font;
694 augmentFont(font, "mathnormal");
695 mathed_string_dim(font, str, dim);
699 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
701 FontInfo f = pi.base.font;
702 augmentFont(f, "mathnormal");
703 f.setColor(Color_latex);
704 pi.pain.text(x, y, str, f);
708 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
710 FontInfo f = pi.base.font;
711 augmentFont(f, "mathnormal");
712 f.setColor(Color_foreground);
713 pi.pain.text(x, y, str, f);
717 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
719 frontend::FontMetrics const & fm = theFontMetrics(font);
720 asc = fm.maxAscent();
721 des = fm.maxDescent();
734 FontFamily const inh_family = INHERIT_FAMILY;
735 FontSeries const inh_series = INHERIT_SERIES;
736 FontShape const inh_shape = INHERIT_SHAPE;
739 // mathnormal should be the first, otherwise the fallback further down
741 fontinfo fontinfos[] = {
743 // Color_math determines which fonts are math (see isMathFont)
744 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
745 ITALIC_SHAPE, Color_math},
746 {"mathbf", inh_family, BOLD_SERIES,
747 inh_shape, Color_math},
748 {"mathcal", CMSY_FAMILY, inh_series,
749 inh_shape, Color_math},
750 {"mathfrak", EUFRAK_FAMILY, inh_series,
751 inh_shape, Color_math},
752 {"mathrm", ROMAN_FAMILY, inh_series,
753 UP_SHAPE, Color_math},
754 {"mathsf", SANS_FAMILY, inh_series,
755 inh_shape, Color_math},
756 {"mathbb", MSB_FAMILY, inh_series,
757 inh_shape, Color_math},
758 {"mathtt", TYPEWRITER_FAMILY, inh_series,
759 inh_shape, Color_math},
760 {"mathit", inh_family, inh_series,
761 ITALIC_SHAPE, Color_math},
762 {"mathscr", RSFS_FAMILY, inh_series,
763 inh_shape, Color_math},
764 {"cmex", CMEX_FAMILY, inh_series,
765 inh_shape, Color_math},
766 {"cmm", CMM_FAMILY, inh_series,
767 inh_shape, Color_math},
768 {"cmr", CMR_FAMILY, inh_series,
769 inh_shape, Color_math},
770 {"cmsy", CMSY_FAMILY, inh_series,
771 inh_shape, Color_math},
772 {"eufrak", EUFRAK_FAMILY, inh_series,
773 inh_shape, Color_math},
774 {"msa", MSA_FAMILY, inh_series,
775 inh_shape, Color_math},
776 {"msb", MSB_FAMILY, inh_series,
777 inh_shape, Color_math},
778 {"stmry", STMARY_FAMILY, inh_series,
779 inh_shape, Color_math},
780 {"wasy", WASY_FAMILY, inh_series,
781 inh_shape, Color_math},
782 {"esint", ESINT_FAMILY, inh_series,
783 inh_shape, Color_math},
786 {"text", inh_family, inh_series,
787 inh_shape, Color_foreground},
788 {"textbf", inh_family, BOLD_SERIES,
789 inh_shape, Color_foreground},
790 {"textit", inh_family, inh_series,
791 ITALIC_SHAPE, Color_foreground},
792 {"textmd", inh_family, MEDIUM_SERIES,
793 inh_shape, Color_foreground},
794 {"textnormal", inh_family, inh_series,
795 UP_SHAPE, Color_foreground},
796 {"textrm", ROMAN_FAMILY,
797 inh_series, UP_SHAPE,Color_foreground},
798 {"textsc", inh_family, inh_series,
799 SMALLCAPS_SHAPE, Color_foreground},
800 {"textsf", SANS_FAMILY, inh_series,
801 inh_shape, Color_foreground},
802 {"textsl", inh_family, inh_series,
803 SLANTED_SHAPE, Color_foreground},
804 {"texttt", TYPEWRITER_FAMILY, inh_series,
805 inh_shape, Color_foreground},
806 {"textup", inh_family, inh_series,
807 UP_SHAPE, Color_foreground},
810 {"textipa", inh_family, inh_series,
811 inh_shape, Color_foreground},
814 {"ce", inh_family, inh_series,
815 inh_shape, Color_foreground},
816 {"cf", inh_family, inh_series,
817 inh_shape, Color_foreground},
819 // LyX internal usage
820 {"lyxtex", inh_family, inh_series,
821 UP_SHAPE, Color_latex},
822 // FIXME: The following two don't work on OS X, since the Symbol font
823 // uses a different encoding, and is therefore disabled in
824 // FontLoader::available().
825 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
826 inh_shape, Color_math},
827 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
828 inh_shape, Color_math},
829 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
830 UP_SHAPE, Color_foreground},
831 {"lyxnochange", inh_family, inh_series,
832 inh_shape, Color_foreground},
833 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
834 UP_SHAPE, Color_math},
835 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
836 ITALIC_SHAPE, Color_math},
837 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
838 ITALIC_SHAPE, Color_math}
842 fontinfo * lookupFont(string const & name)
844 //lyxerr << "searching font '" << name << "'" << endl;
845 int const n = sizeof(fontinfos) / sizeof(fontinfo);
846 for (int i = 0; i < n; ++i)
847 if (fontinfos[i].cmd_ == name) {
848 //lyxerr << "found '" << i << "'" << endl;
849 return fontinfos + i;
855 fontinfo * searchFont(string const & name)
857 fontinfo * f = lookupFont(name);
858 return f ? f : fontinfos;
859 // this should be mathnormal
860 //return searchFont("mathnormal");
864 bool isFontName(string const & name)
866 return lookupFont(name);
870 bool isMathFont(string const & name)
872 fontinfo * f = lookupFont(name);
873 return f && f->color_ == Color_math;
877 bool isTextFont(string const & name)
879 fontinfo * f = lookupFont(name);
880 return f && f->color_ == Color_foreground;
884 FontInfo getFont(string const & name)
887 augmentFont(font, name);
892 void fakeFont(string const & orig, string const & fake)
894 fontinfo * forig = searchFont(orig);
895 fontinfo * ffake = searchFont(fake);
896 if (forig && ffake) {
897 forig->family_ = ffake->family_;
898 forig->series_ = ffake->series_;
899 forig->shape_ = ffake->shape_;
900 forig->color_ = ffake->color_;
902 lyxerr << "Can't fake font '" << orig << "' with '"
903 << fake << "'" << endl;
908 void augmentFont(FontInfo & font, string const & name)
910 static bool initialized = false;
913 // fake fonts if necessary
914 if (!theFontLoader().available(getFont("mathfrak")))
915 fakeFont("mathfrak", "lyxfakefrak");
916 if (!theFontLoader().available(getFont("mathcal")))
917 fakeFont("mathcal", "lyxfakecal");
919 fontinfo * info = searchFont(name);
920 if (info->family_ != inh_family)
921 font.setFamily(info->family_);
922 if (info->series_ != inh_series)
923 font.setSeries(info->series_);
924 if (info->shape_ != inh_shape)
925 font.setShape(info->shape_);
926 if (info->color_ != Color_none)
927 font.setColor(info->color_);
931 bool isAlphaSymbol(MathAtom const & at)
933 if (at->asCharInset() ||
934 (at->asSymbolInset() &&
935 at->asSymbolInset()->isOrdAlpha()))
938 if (at->asFontInset()) {
939 MathData const & ar = at->asFontInset()->cell(0);
940 for (size_t i = 0; i < ar.size(); ++i) {
941 if (!(ar[i]->asCharInset() ||
942 (ar[i]->asSymbolInset() &&
943 ar[i]->asSymbolInset()->isOrdAlpha())))
952 docstring asString(MathData const & ar)
955 otexrowstream ots(os);
962 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
964 // If the QUIET flag is set, we are going to parse for either
965 // a paste operation or a macro definition. We try to do the
966 // right thing in all cases.
968 bool quiet = pf & Parse::QUIET;
969 bool macro = pf & Parse::MACRODEF;
970 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet && !macro))
971 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
975 docstring asString(InsetMath const & inset)
978 otexrowstream ots(os);
985 docstring asString(MathAtom const & at)
988 otexrowstream ots(os);
995 int axis_height(MetricsBase & mb)
997 Changer dummy = mb.changeFontSet("mathnormal");
998 return theFontMetrics(mb.font).ascent('-') - 1;
1002 void validate_math_word(LaTeXFeatures & features, docstring const & word)
1004 MathWordList const & words = mathedWordList();
1005 MathWordList::const_iterator it = words.find(word);
1006 if (it != words.end()) {
1007 string const req = it->second.requires;
1009 features.require(req);