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);
674 // seperate things a bit
675 if (sym->extra == "mathbin")
676 dim.wid += 2 * mathed_medmuskip(mi.base.font);
677 else if (sym->extra == "mathrel")
678 dim.wid += 2 * mathed_thickmuskip(mi.base.font);
679 else if (sym->extra == "mathpunct")
680 dim.wid += mathed_thinmuskip(mi.base.font);
684 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
686 LASSERT((bool)sym, return);
687 //lyxerr << "drawing: symbol: '" << sym->name
688 // << "' in font: '" << sym->inset
689 // << "' drawn as: '" << sym->draw
692 bool const italic_upcase_greek = sym->inset == "cmr" &&
693 sym->extra == "mathalpha" &&
694 pi.base.fontname == "mathit";
695 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
696 if (sym->extra == "mathbin")
697 x += mathed_medmuskip(pi.base.font);
698 else if (sym->extra == "mathrel")
699 x += mathed_thickmuskip(pi.base.font);
701 Changer dummy = pi.base.changeFontSet(font);
702 pi.draw(x, y, sym->draw);
706 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
708 FontInfo font = mi.base.font;
709 augmentFont(font, "mathnormal");
710 mathed_string_dim(font, str, dim);
714 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
716 FontInfo f = pi.base.font;
717 augmentFont(f, "mathnormal");
718 f.setColor(Color_latex);
719 pi.pain.text(x, y, str, f);
723 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
725 FontInfo f = pi.base.font;
726 augmentFont(f, "mathnormal");
727 f.setColor(Color_foreground);
728 pi.pain.text(x, y, str, f);
732 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
734 frontend::FontMetrics const & fm = theFontMetrics(font);
735 asc = fm.maxAscent();
736 des = fm.maxDescent();
749 FontFamily const inh_family = INHERIT_FAMILY;
750 FontSeries const inh_series = INHERIT_SERIES;
751 FontShape const inh_shape = INHERIT_SHAPE;
754 // mathnormal should be the first, otherwise the fallback further down
756 fontinfo fontinfos[] = {
758 // Color_math determines which fonts are math (see isMathFont)
759 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
760 ITALIC_SHAPE, Color_math},
761 {"mathbf", inh_family, BOLD_SERIES,
762 inh_shape, Color_math},
763 {"mathcal", CMSY_FAMILY, inh_series,
764 inh_shape, Color_math},
765 {"mathfrak", EUFRAK_FAMILY, inh_series,
766 inh_shape, Color_math},
767 {"mathrm", ROMAN_FAMILY, inh_series,
768 UP_SHAPE, Color_math},
769 {"mathsf", SANS_FAMILY, inh_series,
770 inh_shape, Color_math},
771 {"mathbb", MSB_FAMILY, inh_series,
772 inh_shape, Color_math},
773 {"mathtt", TYPEWRITER_FAMILY, inh_series,
774 inh_shape, Color_math},
775 {"mathit", inh_family, inh_series,
776 ITALIC_SHAPE, Color_math},
777 {"mathscr", RSFS_FAMILY, inh_series,
778 inh_shape, Color_math},
779 {"cmex", CMEX_FAMILY, inh_series,
780 inh_shape, Color_math},
781 {"cmm", CMM_FAMILY, inh_series,
782 inh_shape, Color_math},
783 {"cmr", CMR_FAMILY, inh_series,
784 inh_shape, Color_math},
785 {"cmsy", CMSY_FAMILY, inh_series,
786 inh_shape, Color_math},
787 {"eufrak", EUFRAK_FAMILY, inh_series,
788 inh_shape, Color_math},
789 {"msa", MSA_FAMILY, inh_series,
790 inh_shape, Color_math},
791 {"msb", MSB_FAMILY, inh_series,
792 inh_shape, Color_math},
793 {"stmry", STMARY_FAMILY, inh_series,
794 inh_shape, Color_math},
795 {"wasy", WASY_FAMILY, inh_series,
796 inh_shape, Color_math},
797 {"esint", ESINT_FAMILY, inh_series,
798 inh_shape, Color_math},
801 {"text", inh_family, inh_series,
802 inh_shape, Color_foreground},
803 {"textbf", inh_family, BOLD_SERIES,
804 inh_shape, Color_foreground},
805 {"textit", inh_family, inh_series,
806 ITALIC_SHAPE, Color_foreground},
807 {"textmd", inh_family, MEDIUM_SERIES,
808 inh_shape, Color_foreground},
809 {"textnormal", inh_family, inh_series,
810 UP_SHAPE, Color_foreground},
811 {"textrm", ROMAN_FAMILY,
812 inh_series, UP_SHAPE,Color_foreground},
813 {"textsc", inh_family, inh_series,
814 SMALLCAPS_SHAPE, Color_foreground},
815 {"textsf", SANS_FAMILY, inh_series,
816 inh_shape, Color_foreground},
817 {"textsl", inh_family, inh_series,
818 SLANTED_SHAPE, Color_foreground},
819 {"texttt", TYPEWRITER_FAMILY, inh_series,
820 inh_shape, Color_foreground},
821 {"textup", inh_family, inh_series,
822 UP_SHAPE, Color_foreground},
825 {"textipa", inh_family, inh_series,
826 inh_shape, Color_foreground},
829 {"ce", inh_family, inh_series,
830 inh_shape, Color_foreground},
831 {"cf", inh_family, inh_series,
832 inh_shape, Color_foreground},
834 // LyX internal usage
835 {"lyxtex", inh_family, inh_series,
836 UP_SHAPE, Color_latex},
837 // FIXME: The following two don't work on OS X, since the Symbol font
838 // uses a different encoding, and is therefore disabled in
839 // FontLoader::available().
840 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
841 inh_shape, Color_math},
842 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
843 inh_shape, Color_math},
844 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
845 UP_SHAPE, Color_foreground},
846 {"lyxnochange", inh_family, inh_series,
847 inh_shape, Color_foreground},
848 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
849 UP_SHAPE, Color_math},
850 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
851 ITALIC_SHAPE, Color_math},
852 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
853 ITALIC_SHAPE, Color_math}
857 fontinfo * lookupFont(string const & name)
859 //lyxerr << "searching font '" << name << "'" << endl;
860 int const n = sizeof(fontinfos) / sizeof(fontinfo);
861 for (int i = 0; i < n; ++i)
862 if (fontinfos[i].cmd_ == name) {
863 //lyxerr << "found '" << i << "'" << endl;
864 return fontinfos + i;
870 fontinfo * searchFont(string const & name)
872 fontinfo * f = lookupFont(name);
873 return f ? f : fontinfos;
874 // this should be mathnormal
875 //return searchFont("mathnormal");
879 bool isFontName(string const & name)
881 return lookupFont(name);
885 bool isMathFont(string const & name)
887 fontinfo * f = lookupFont(name);
888 return f && f->color_ == Color_math;
892 bool isTextFont(string const & name)
894 fontinfo * f = lookupFont(name);
895 return f && f->color_ == Color_foreground;
899 FontInfo getFont(string const & name)
902 augmentFont(font, name);
907 void fakeFont(string const & orig, string const & fake)
909 fontinfo * forig = searchFont(orig);
910 fontinfo * ffake = searchFont(fake);
911 if (forig && ffake) {
912 forig->family_ = ffake->family_;
913 forig->series_ = ffake->series_;
914 forig->shape_ = ffake->shape_;
915 forig->color_ = ffake->color_;
917 lyxerr << "Can't fake font '" << orig << "' with '"
918 << fake << "'" << endl;
923 void augmentFont(FontInfo & font, string const & name)
925 static bool initialized = false;
928 // fake fonts if necessary
929 if (!theFontLoader().available(getFont("mathfrak")))
930 fakeFont("mathfrak", "lyxfakefrak");
931 if (!theFontLoader().available(getFont("mathcal")))
932 fakeFont("mathcal", "lyxfakecal");
934 fontinfo * info = searchFont(name);
935 if (info->family_ != inh_family)
936 font.setFamily(info->family_);
937 if (info->series_ != inh_series)
938 font.setSeries(info->series_);
939 if (info->shape_ != inh_shape)
940 font.setShape(info->shape_);
941 if (info->color_ != Color_none)
942 font.setColor(info->color_);
946 bool isAlphaSymbol(MathAtom const & at)
948 if (at->asCharInset() ||
949 (at->asSymbolInset() &&
950 at->asSymbolInset()->isOrdAlpha()))
953 if (at->asFontInset()) {
954 MathData const & ar = at->asFontInset()->cell(0);
955 for (size_t i = 0; i < ar.size(); ++i) {
956 if (!(ar[i]->asCharInset() ||
957 (ar[i]->asSymbolInset() &&
958 ar[i]->asSymbolInset()->isOrdAlpha())))
967 docstring asString(MathData const & ar)
970 otexrowstream ots(os);
977 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
979 bool quiet = pf & Parse::QUIET;
980 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
981 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
985 docstring asString(InsetMath const & inset)
988 otexrowstream ots(os);
995 docstring asString(MathAtom const & at)
998 otexrowstream ots(os);