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_deco_table;
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();
517 int mathed_font_x_height(FontInfo const & font)
519 return theFontMetrics(font).ascent('x');
522 /* The math units. Quoting TeX by Topic, p.205:
524 * Spacing around mathematical objects is measured in mu units. A mu
525 * is 1/18th part of \fontdimen6 of the font in family 2 in the
526 * current style, the ‘quad’ value of the symbol font.
528 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
529 * inserted around (binary) relations, except where these are preceded
530 * or followed by other relations or punctuation, and except if they
531 * follow an open, or precede a close symbol.
533 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
534 * is put around binary operators.
536 * A \thinmuskip (default value in plain TeX: 3mu) follows after
537 * punctuation, and is put around inner objects, except where these
538 * are followed by a close or preceded by an open symbol, and except
539 * if the other object is a large operator or a binary relation.
541 * See the file MathClass.cpp for a formal implementation of the rules
545 int mathed_mu(FontInfo const & font, double mu)
547 MetricsBase mb(nullptr, font);
548 return Length(mu, Length::MU).inPixels(mb);
551 int mathed_thinmuskip(FontInfo const & font) { return mathed_mu(font, 3.0); }
552 int mathed_medmuskip(FontInfo const & font) { return mathed_mu(font, 4.0); }
553 int mathed_thickmuskip(FontInfo const & font) { return mathed_mu(font, 5.0); }
556 int mathed_char_width(FontInfo const & font, char_type c)
558 return theFontMetrics(font).width(c);
562 int mathed_char_kerning(FontInfo const & font, char_type c)
564 frontend::FontMetrics const & fm = theFontMetrics(font);
565 return max(0, fm.rbearing(c) - fm.width(c));
569 void mathed_string_dim(FontInfo const & font,
573 frontend::FontMetrics const & fm = theFontMetrics(font);
576 for (docstring::const_iterator it = s.begin();
579 dim.asc = max(dim.asc, fm.ascent(*it));
580 dim.des = max(dim.des, fm.descent(*it));
582 dim.wid = fm.width(s);
586 int mathed_string_width(FontInfo const & font, docstring const & s)
588 return theFontMetrics(font).width(s);
592 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
593 docstring const & name)
596 pi.pain.line(x + w/2, y, x + w/2, y + h,
597 Color_cursor, Painter::line_onoffdash);
601 deco_struct const * mds = search_deco(name);
603 lyxerr << "Deco was not found. Programming error?" << endl;
604 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
608 int const n = (w < h) ? w : h;
609 int const r = mds->angle;
610 double const * d = mds->data;
612 if (h > 70 && (name == "(" || name == ")"))
616 Matrix sqmt(r, n, n);
624 for (int i = 0; d[i]; ) {
625 int code = int(d[i++]);
626 if (code & 1) { // code == 1 || code == 3
632 sqmt.transform(xx, yy);
634 mt.transform(xx, yy);
635 mt.transform(x2, y2);
637 int(x + xx + 0.5), int(y + yy + 0.5),
638 int(x + x2 + 0.5), int(y + y2 + 0.5),
639 pi.base.font.color());
643 int const n2 = int(d[i++]);
644 for (int j = 0; j < n2; ++j) {
647 // lyxerr << ' ' << xx << ' ' << yy << ' ';
649 sqmt.transform(xx, yy);
651 mt.transform(xx, yy);
652 xp[j] = int(x + xx + 0.5);
653 yp[j] = int(y + yy + 0.5);
654 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
656 pi.pain.lines(xp, yp, n2, pi.base.font.color());
662 void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
664 LASSERT((bool)sym, return);
665 //lyxerr << "metrics: symbol: '" << sym->name
666 // << "' in font: '" << sym->inset
667 // << "' drawn as: '" << sym->draw
670 bool const italic_upcase_greek = sym->inset == "cmr" &&
671 sym->extra == "mathalpha" &&
672 mb.fontname == "mathit";
673 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
674 Changer dummy = mb.changeFontSet(font);
675 mathed_string_dim(mb.font, sym->draw, dim);
679 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
681 LASSERT((bool)sym, return);
682 //lyxerr << "drawing: symbol: '" << sym->name
683 // << "' in font: '" << sym->inset
684 // << "' drawn as: '" << sym->draw
687 bool const italic_upcase_greek = sym->inset == "cmr" &&
688 sym->extra == "mathalpha" &&
689 pi.base.fontname == "mathit";
690 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
692 Changer dummy = pi.base.changeFontSet(font);
693 pi.draw(x, y, sym->draw);
697 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
699 FontInfo font = mi.base.font;
700 augmentFont(font, "mathnormal");
701 mathed_string_dim(font, str, dim);
705 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
707 FontInfo f = pi.base.font;
708 augmentFont(f, "mathnormal");
709 f.setColor(Color_latex);
710 pi.pain.text(x, y, str, f);
714 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
716 FontInfo f = pi.base.font;
717 augmentFont(f, "mathnormal");
718 f.setColor(Color_foreground);
719 pi.pain.text(x, y, str, f);
723 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
725 frontend::FontMetrics const & fm = theFontMetrics(font);
726 asc = fm.maxAscent();
727 des = fm.maxDescent();
740 FontFamily const inh_family = INHERIT_FAMILY;
741 FontSeries const inh_series = INHERIT_SERIES;
742 FontShape const inh_shape = INHERIT_SHAPE;
745 // mathnormal should be the first, otherwise the fallback further down
747 fontinfo fontinfos[] = {
749 // Color_math determines which fonts are math (see isMathFont)
750 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
751 ITALIC_SHAPE, Color_math},
752 {"mathbf", inh_family, BOLD_SERIES,
753 inh_shape, Color_math},
754 {"mathcal", CMSY_FAMILY, inh_series,
755 inh_shape, Color_math},
756 {"mathfrak", EUFRAK_FAMILY, inh_series,
757 inh_shape, Color_math},
758 {"mathrm", ROMAN_FAMILY, inh_series,
759 UP_SHAPE, Color_math},
760 {"mathsf", SANS_FAMILY, inh_series,
761 inh_shape, Color_math},
762 {"mathbb", MSB_FAMILY, inh_series,
763 inh_shape, Color_math},
764 {"mathtt", TYPEWRITER_FAMILY, inh_series,
765 inh_shape, Color_math},
766 {"mathit", inh_family, inh_series,
767 ITALIC_SHAPE, Color_math},
768 {"mathscr", RSFS_FAMILY, inh_series,
769 inh_shape, Color_math},
770 {"cmex", CMEX_FAMILY, inh_series,
771 inh_shape, Color_math},
772 {"cmm", CMM_FAMILY, inh_series,
773 inh_shape, Color_math},
774 {"cmr", CMR_FAMILY, inh_series,
775 inh_shape, Color_math},
776 {"cmsy", CMSY_FAMILY, inh_series,
777 inh_shape, Color_math},
778 {"eufrak", EUFRAK_FAMILY, inh_series,
779 inh_shape, Color_math},
780 {"msa", MSA_FAMILY, inh_series,
781 inh_shape, Color_math},
782 {"msb", MSB_FAMILY, inh_series,
783 inh_shape, Color_math},
784 {"stmry", STMARY_FAMILY, inh_series,
785 inh_shape, Color_math},
786 {"wasy", WASY_FAMILY, inh_series,
787 inh_shape, Color_math},
788 {"esint", ESINT_FAMILY, inh_series,
789 inh_shape, Color_math},
792 {"text", inh_family, inh_series,
793 inh_shape, Color_foreground},
794 {"textbf", inh_family, BOLD_SERIES,
795 inh_shape, Color_foreground},
796 {"textit", inh_family, inh_series,
797 ITALIC_SHAPE, Color_foreground},
798 {"textmd", inh_family, MEDIUM_SERIES,
799 inh_shape, Color_foreground},
800 {"textnormal", inh_family, inh_series,
801 UP_SHAPE, Color_foreground},
802 {"textrm", ROMAN_FAMILY,
803 inh_series, UP_SHAPE,Color_foreground},
804 {"textsc", inh_family, inh_series,
805 SMALLCAPS_SHAPE, Color_foreground},
806 {"textsf", SANS_FAMILY, inh_series,
807 inh_shape, Color_foreground},
808 {"textsl", inh_family, inh_series,
809 SLANTED_SHAPE, Color_foreground},
810 {"texttt", TYPEWRITER_FAMILY, inh_series,
811 inh_shape, Color_foreground},
812 {"textup", inh_family, inh_series,
813 UP_SHAPE, Color_foreground},
816 {"textipa", inh_family, inh_series,
817 inh_shape, Color_foreground},
820 {"ce", inh_family, inh_series,
821 inh_shape, Color_foreground},
822 {"cf", inh_family, inh_series,
823 inh_shape, Color_foreground},
825 // LyX internal usage
826 {"lyxtex", inh_family, inh_series,
827 UP_SHAPE, Color_latex},
828 // FIXME: The following two don't work on OS X, since the Symbol font
829 // uses a different encoding, and is therefore disabled in
830 // FontLoader::available().
831 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
832 inh_shape, Color_math},
833 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
834 inh_shape, Color_math},
835 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
836 UP_SHAPE, Color_foreground},
837 {"lyxnochange", inh_family, inh_series,
838 inh_shape, Color_foreground},
839 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
840 UP_SHAPE, Color_math},
841 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
842 ITALIC_SHAPE, Color_math},
843 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
844 ITALIC_SHAPE, Color_math}
848 fontinfo * lookupFont(string const & name)
850 //lyxerr << "searching font '" << name << "'" << endl;
851 int const n = sizeof(fontinfos) / sizeof(fontinfo);
852 for (int i = 0; i < n; ++i)
853 if (fontinfos[i].cmd_ == name) {
854 //lyxerr << "found '" << i << "'" << endl;
855 return fontinfos + i;
861 fontinfo * searchFont(string const & name)
863 fontinfo * f = lookupFont(name);
864 return f ? f : fontinfos;
865 // this should be mathnormal
866 //return searchFont("mathnormal");
870 bool isFontName(string const & name)
872 return lookupFont(name);
876 bool isMathFont(string const & name)
878 fontinfo * f = lookupFont(name);
879 return f && f->color_ == Color_math;
883 bool isTextFont(string const & name)
885 fontinfo * f = lookupFont(name);
886 return f && f->color_ == Color_foreground;
890 FontInfo getFont(string const & name)
893 augmentFont(font, name);
898 void fakeFont(string const & orig, string const & fake)
900 fontinfo * forig = searchFont(orig);
901 fontinfo * ffake = searchFont(fake);
902 if (forig && ffake) {
903 forig->family_ = ffake->family_;
904 forig->series_ = ffake->series_;
905 forig->shape_ = ffake->shape_;
906 forig->color_ = ffake->color_;
908 lyxerr << "Can't fake font '" << orig << "' with '"
909 << fake << "'" << endl;
914 void augmentFont(FontInfo & font, string const & name)
916 static bool initialized = false;
919 // fake fonts if necessary
920 if (!theFontLoader().available(getFont("mathfrak")))
921 fakeFont("mathfrak", "lyxfakefrak");
922 if (!theFontLoader().available(getFont("mathcal")))
923 fakeFont("mathcal", "lyxfakecal");
925 fontinfo * info = searchFont(name);
926 if (info->family_ != inh_family)
927 font.setFamily(info->family_);
928 if (info->series_ != inh_series)
929 font.setSeries(info->series_);
930 if (info->shape_ != inh_shape)
931 font.setShape(info->shape_);
932 if (info->color_ != Color_none)
933 font.setColor(info->color_);
937 bool isAlphaSymbol(MathAtom const & at)
939 if (at->asCharInset() ||
940 (at->asSymbolInset() &&
941 at->asSymbolInset()->isOrdAlpha()))
944 if (at->asFontInset()) {
945 MathData const & ar = at->asFontInset()->cell(0);
946 for (size_t i = 0; i < ar.size(); ++i) {
947 if (!(ar[i]->asCharInset() ||
948 (ar[i]->asSymbolInset() &&
949 ar[i]->asSymbolInset()->isOrdAlpha())))
958 docstring asString(MathData const & ar)
961 otexrowstream ots(os);
968 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
970 // If the QUIET flag is set, we are going to parse for either
971 // a paste operation or a macro definition. We try to do the
972 // right thing in all cases.
974 bool quiet = pf & Parse::QUIET;
975 bool macro = pf & Parse::MACRODEF;
976 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet && !macro))
977 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
981 docstring asString(InsetMath const & inset)
984 otexrowstream ots(os);
991 docstring asString(MathAtom const & at)
994 otexrowstream ots(os);
1001 int axis_height(MetricsBase & mb)
1003 Changer dummy = mb.changeFontSet("mathnormal");
1004 return theFontMetrics(mb.font).ascent('-') - 1;
1008 void validate_math_word(LaTeXFeatures & features, docstring const & word)
1010 MathWordList const & words = mathedWordList();
1011 MathWordList::const_iterator it = words.find(word);
1012 if (it != words.end()) {
1013 string const req = it->second.requires;
1015 features.require(req);