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
85 * 5 = rounded thick line (i.e. dot for short line)
89 double const parenthHigh[] = {
91 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
92 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
93 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
94 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
100 double const parenth[] = {
102 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
103 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
104 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
105 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
111 double const brace[] = {
113 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
114 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
115 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
116 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
117 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
118 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
119 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
124 double const mapsto[] = {
126 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
127 1, 0.015, 0.475, 0.945, 0.475,
128 1, 0.015, 0.015, 0.015, 0.985,
133 double const lhook[] = {
135 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
136 1, 0.015, 0.475, 0.7, 0.475,
138 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
139 0.825, 0.35, 0.7, 0.475,
144 double const rhook[] = {
146 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
147 1, 0.3, 0.475, 0.985, 0.475,
149 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
150 0.175, 0.35, 0.3, 0.475,
155 double const LRArrow[] = {
157 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
159 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
160 1, 0.2, 0.8, 0.8, 0.8,
161 1, 0.2, 0.2, 0.8, 0.2,
166 double const LArrow[] = {
168 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
169 1, 0.2, 0.8, 0.985, 0.8,
170 1, 0.2, 0.2, 0.985, 0.2,
175 double const lharpoondown[] = {
177 0.015, 0.5, 0.25, 0.985,
178 1, 0.02, 0.475, 0.985, 0.475,
183 double const lharpoonup[] = {
185 0.25, 0.015, 0.015, 0.5,
186 1, 0.02, 0.525, 0.985, 0.525,
191 double const lrharpoons[] = {
193 0.25, 0.015, 0.015, 0.225,
194 1, 0.02, 0.23, 0.985, 0.23,
196 0.75, 0.985, 0.985, 0.775,
197 1, 0.02, 0.7, 0.980, 0.7,
202 double const rlharpoons[] = {
204 0.75, 0.015, 0.985, 0.225,
205 1, 0.02, 0.23, 0.985, 0.23,
207 0.25, 0.985, 0.015, 0.775,
208 1, 0.02, 0.7, 0.980, 0.7,
213 double const arrow[] = {
215 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
216 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
218 3, 0.5000, 0.1500, 0.5000, 0.9500,
223 double const Arrow[] = {
225 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
226 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
228 3, 0.3500, 0.5000, 0.3500, 0.9500,
229 3, 0.6500, 0.5000, 0.6500, 0.9500,
234 double const udarrow[] = {
236 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
238 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
239 1, 0.5, 0.1, 0.5, 0.9,
244 double const Udarrow[] = {
246 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
248 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
249 1, 0.35, 0.2, 0.35, 0.8,
250 1, 0.65, 0.2, 0.65, 0.8,
255 double const brack[] = {
257 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
262 double const dbrack[] = {
264 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
266 0.50, 0.05, 0.50, 0.95,
271 double const corner[] = {
273 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
278 double const angle[] = {
280 1, 0, 0.05, 0.5, 1, 1,
285 double const slash[] = {
286 1, 0.95, 0.05, 0.05, 0.95,
291 double const hline[] = {
292 1, 0.00, 0.5, 1.0, 0.5,
297 double const dot[] = {
298 // 1, 0.5, 0.2, 0.5, 0.2,
299 // 1, 0.4, 0.4, 0.6, 0.4,
300 // 1, 0.5, 0.5, 0.5, 0.5,
301 5, 0.4, 0.4, 0.6, 0.4,
306 double const ddot[] = {
307 5, 0.0, 0.4, 0.3, 0.4,
308 5, 0.6, 0.4, 1.0, 0.4,
313 double const dddot[] = {
314 1, 0.1, 0.5, 0.2, 0.5,
315 1, 0.45, 0.5, 0.55, 0.5,
316 1, 0.8, 0.5, 0.9, 0.5,
321 double const ddddot[] = {
322 1, 0.1, 0.5, 0.2, 0.5,
323 1, 0.45, 0.5, 0.55, 0.5,
324 1, 0.8, 0.5, 0.9, 0.5,
325 1, 1.15, 0.5, 1.25, 0.5,
330 double const hline3[] = {
332 1, 0.475, 0, 0.525, 0,
338 double const dline3[] = {
339 1, 0.1, 0.1, 0.15, 0.15,
340 1, 0.475, 0.475, 0.525, 0.525,
341 1, 0.85, 0.85, 0.9, 0.9,
346 double const ring[] = {
348 0.5, 0.8, 0.8, 0.5, 0.5, 0.2, 0.2, 0.5, 0.5, 0.8,
353 double const vert[] = {
354 1, 0.5, 0.05, 0.5, 0.95,
359 double const Vert[] = {
360 1, 0.3, 0.05, 0.3, 0.95,
361 1, 0.7, 0.05, 0.7, 0.95,
366 double const tilde[] = {
368 0.00, 0.8, 0.25, 0.2, 0.75, 0.8, 1.00, 0.2,
378 struct named_deco_struct {
384 named_deco_struct deco_table[] = {
386 {"widehat", angle, 3 },
387 {"widetilde", tilde, 0 },
388 {"underbar", hline, 0 },
389 {"underline", hline, 0 },
390 {"overline", hline, 0 },
391 {"underbrace", brace, 1 },
392 {"overbrace", brace, 3 },
393 {"overleftarrow", arrow, 1 },
394 {"overrightarrow", arrow, 3 },
395 {"overleftrightarrow", udarrow, 1 },
396 {"xhookleftarrow", lhook, 0 },
397 {"xhookrightarrow", rhook, 0 },
398 {"xleftarrow", arrow, 1 },
399 {"xLeftarrow", LArrow, 0 },
400 {"xleftharpoondown", lharpoondown, 0 },
401 {"xleftharpoonup", lharpoonup, 0 },
402 {"xleftrightharpoons", lrharpoons, 0 },
403 {"xleftrightarrow", udarrow, 1 },
404 {"xLeftrightarrow", LRArrow, 0 },
405 {"xmapsto", mapsto, 0 },
406 {"xrightarrow", arrow, 3 },
407 {"xRightarrow", LArrow, 2 },
408 {"xrightharpoondown", lharpoonup, 2 },
409 {"xrightharpoonup", lharpoondown, 2 },
410 {"xrightleftharpoons", rlharpoons, 0 },
411 {"underleftarrow", arrow, 1 },
412 {"underrightarrow", arrow, 3 },
413 {"underleftrightarrow", udarrow, 1 },
414 {"undertilde", tilde, 0 },
415 {"utilde", tilde, 0 },
422 {"lbrace", brace, 0 },
423 {"rbrace", brace, 2 },
426 {"llbracket", dbrack, 0 },
427 {"rrbracket", dbrack, 2 },
430 {"slash", slash, 0 },
441 {"backslash", slash, 1 },
442 {"langle", angle, 0 },
443 {"lceil", corner, 0 },
444 {"lfloor", corner, 1 },
445 {"rangle", angle, 2 },
446 {"rceil", corner, 3 },
447 {"rfloor", corner, 2 },
448 {"downarrow", arrow, 2 },
449 {"Downarrow", Arrow, 2 },
450 {"uparrow", arrow, 0 },
451 {"Uparrow", Arrow, 0 },
452 {"updownarrow", udarrow, 0 },
453 {"Updownarrow", Udarrow, 0 },
457 {"dddot", dddot, 0 },
458 {"ddddot", ddddot, 0 },
460 {"grave", slash, 1 },
461 {"acute", slash, 0 },
462 {"tilde", tilde, 0 },
465 {"check", angle, 1 },
466 {"breve", parenth, 1 },
468 {"mathring", ring, 0 },
471 {"dots", hline3, 0 },
472 {"ldots", hline3, 0 },
473 {"cdots", hline3, 0 },
474 {"vdots", hline3, 1 },
475 {"ddots", dline3, 0 },
476 {"adots", dline3, 1 },
477 {"iddots", dline3, 1 },
478 {"dotsb", hline3, 0 },
479 {"dotsc", hline3, 0 },
480 {"dotsi", hline3, 0 },
481 {"dotsm", hline3, 0 },
482 {"dotso", hline3, 0 }
486 map<docstring, deco_struct> deco_list;
488 // sort the table on startup
489 class init_deco_table {
492 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
493 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
497 deco_list[from_ascii(p->name)] = d;
502 static init_deco_table dummy_deco_table;
505 deco_struct const * search_deco(docstring const & name)
507 map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
508 return p == deco_list.end() ? 0 : &(p->second);
515 int mathed_font_em(FontInfo const & font)
517 return theFontMetrics(font).em();
521 int mathed_font_x_height(FontInfo const & font)
523 return theFontMetrics(font).xHeight();
526 /* The math units. Quoting TeX by Topic, p.205:
528 * Spacing around mathematical objects is measured in mu units. A mu
529 * is 1/18th part of \fontdimen6 of the font in family 2 in the
530 * current style, the ‘quad’ value of the symbol font.
532 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
533 * inserted around (binary) relations, except where these are preceded
534 * or followed by other relations or punctuation, and except if they
535 * follow an open, or precede a close symbol.
537 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
538 * is put around binary operators.
540 * A \thinmuskip (default value in plain TeX: 3mu) follows after
541 * punctuation, and is put around inner objects, except where these
542 * are followed by a close or preceded by an open symbol, and except
543 * if the other object is a large operator or a binary relation.
545 * See the file MathClass.cpp for a formal implementation of the rules
549 int mathed_mu(FontInfo const & font, double mu)
551 MetricsBase mb(nullptr, font);
552 return mb.inPixels(Length(mu, Length::MU));
555 int mathed_thinmuskip(FontInfo const & font) { return mathed_mu(font, 3.0); }
556 int mathed_medmuskip(FontInfo const & font) { return mathed_mu(font, 4.0); }
557 int mathed_thickmuskip(FontInfo const & font) { return mathed_mu(font, 5.0); }
560 int mathed_char_width(FontInfo const & font, char_type c)
562 return theFontMetrics(font).width(c);
566 int mathed_char_kerning(FontInfo const & font, char_type c)
568 frontend::FontMetrics const & fm = theFontMetrics(font);
569 return max(0, fm.rbearing(c) - fm.width(c));
573 void mathed_string_dim(FontInfo const & font,
577 frontend::FontMetrics const & fm = theFontMetrics(font);
580 for (docstring::const_iterator it = s.begin();
583 dim.asc = max(dim.asc, fm.ascent(*it));
584 dim.des = max(dim.des, fm.descent(*it));
586 dim.wid = fm.width(s);
590 int mathed_string_width(FontInfo const & font, docstring const & s)
592 return theFontMetrics(font).width(s);
596 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
597 docstring const & name)
600 pi.pain.line(x + w/2, y, x + w/2, y + h,
601 Color_cursor, Painter::line_onoffdash);
605 deco_struct const * mds = search_deco(name);
607 lyxerr << "Deco was not found. Programming error?" << endl;
608 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
612 int const n = (w < h) ? w : h;
613 int const r = mds->angle;
614 double const * d = mds->data;
616 if (h > 70 && (name == "(" || name == ")"))
620 Matrix sqmt(r, n, n);
628 for (int i = 0; d[i]; ) {
629 int code = int(d[i++]);
630 if (code & 1) { // code == 1 || code == 3 || code == 5
636 sqmt.transform(xx, yy);
638 mt.transform(xx, yy);
639 mt.transform(x2, y2);
641 int(x + xx + 0.5), int(y + yy + 0.5),
642 int(x + x2 + 0.5), int(y + y2 + 0.5),
643 pi.base.font.color());
644 if (code == 5) { // thicker, but rounded
646 int(x + xx + 0.5+1), int(y + yy + 0.5-1),
647 int(x + x2 + 0.5-1), int(y + y2 + 0.5-1),
648 pi.base.font.color());
650 int(x + xx + 0.5+1), int(y + yy + 0.5+1),
651 int(x + x2 + 0.5-1), int(y + y2 + 0.5+1),
652 pi.base.font.color());
657 int const n2 = int(d[i++]);
658 for (int j = 0; j < n2; ++j) {
661 // lyxerr << ' ' << xx << ' ' << yy << ' ';
663 sqmt.transform(xx, yy);
665 mt.transform(xx, yy);
666 xp[j] = int(x + xx + 0.5);
667 yp[j] = int(y + yy + 0.5);
668 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
670 pi.pain.lines(xp, yp, n2, pi.base.font.color());
676 void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
678 LASSERT((bool)sym, return);
679 //lyxerr << "metrics: symbol: '" << sym->name
680 // << "' in font: '" << sym->inset
681 // << "' drawn as: '" << sym->draw
684 bool const italic_upcase_greek = sym->inset == "cmr" &&
685 sym->extra == "mathalpha" &&
686 mb.fontname == "mathit";
687 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
688 Changer dummy = mb.changeFontSet(font);
689 mathed_string_dim(mb.font, sym->draw, dim);
693 void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
695 LASSERT((bool)sym, return);
696 //lyxerr << "drawing: symbol: '" << sym->name
697 // << "' in font: '" << sym->inset
698 // << "' drawn as: '" << sym->draw
701 bool const italic_upcase_greek = sym->inset == "cmr" &&
702 sym->extra == "mathalpha" &&
703 pi.base.fontname == "mathit";
704 std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
706 Changer dummy = pi.base.changeFontSet(font);
707 pi.draw(x, y, sym->draw);
711 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
713 FontInfo font = mi.base.font;
714 augmentFont(font, "mathnormal");
715 mathed_string_dim(font, str, dim);
719 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
721 FontInfo f = pi.base.font;
722 augmentFont(f, "mathnormal");
723 f.setColor(Color_latex);
724 pi.pain.text(x, y, str, f);
728 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
730 FontInfo f = pi.base.font;
731 augmentFont(f, "mathnormal");
732 f.setColor(Color_foreground);
733 pi.pain.text(x, y, str, f);
737 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
739 frontend::FontMetrics const & fm = theFontMetrics(font);
740 asc = fm.maxAscent();
741 des = fm.maxDescent();
754 FontFamily const inh_family = INHERIT_FAMILY;
755 FontSeries const inh_series = INHERIT_SERIES;
756 FontShape const inh_shape = INHERIT_SHAPE;
759 // mathnormal should be the first, otherwise the fallback further down
761 fontinfo fontinfos[] = {
763 // Color_math determines which fonts are math (see isMathFont)
764 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
765 ITALIC_SHAPE, Color_math},
766 {"mathbf", inh_family, BOLD_SERIES,
767 inh_shape, Color_math},
768 {"mathcal", CMSY_FAMILY, inh_series,
769 inh_shape, Color_math},
770 {"mathfrak", EUFRAK_FAMILY, inh_series,
771 inh_shape, Color_math},
772 {"mathrm", ROMAN_FAMILY, inh_series,
773 UP_SHAPE, Color_math},
774 {"mathsf", SANS_FAMILY, inh_series,
775 inh_shape, Color_math},
776 {"mathbb", MSB_FAMILY, inh_series,
777 inh_shape, Color_math},
778 {"mathds", DS_FAMILY, inh_series,
779 inh_shape, Color_math},
780 {"mathtt", TYPEWRITER_FAMILY, inh_series,
781 inh_shape, Color_math},
782 {"mathit", inh_family, inh_series,
783 ITALIC_SHAPE, Color_math},
784 {"mathscr", RSFS_FAMILY, inh_series,
785 inh_shape, Color_math},
786 {"cmex", CMEX_FAMILY, inh_series,
787 inh_shape, Color_math},
788 {"cmm", CMM_FAMILY, inh_series,
789 inh_shape, Color_math},
790 {"cmr", CMR_FAMILY, inh_series,
791 inh_shape, Color_math},
792 {"cmsy", CMSY_FAMILY, inh_series,
793 inh_shape, Color_math},
794 {"eufrak", EUFRAK_FAMILY, inh_series,
795 inh_shape, Color_math},
796 {"msa", MSA_FAMILY, inh_series,
797 inh_shape, Color_math},
798 {"msb", MSB_FAMILY, inh_series,
799 inh_shape, Color_math},
800 {"stmry", STMARY_FAMILY, inh_series,
801 inh_shape, Color_math},
802 {"wasy", WASY_FAMILY, inh_series,
803 inh_shape, Color_math},
804 {"esint", ESINT_FAMILY, inh_series,
805 inh_shape, Color_math},
808 {"text", inh_family, inh_series,
809 inh_shape, Color_foreground},
810 {"textbf", inh_family, BOLD_SERIES,
811 inh_shape, Color_foreground},
812 {"textit", inh_family, inh_series,
813 ITALIC_SHAPE, Color_foreground},
814 {"textmd", inh_family, MEDIUM_SERIES,
815 inh_shape, Color_foreground},
816 {"textnormal", inh_family, inh_series,
817 UP_SHAPE, Color_foreground},
818 {"textrm", ROMAN_FAMILY,
819 inh_series, UP_SHAPE,Color_foreground},
820 {"textsc", inh_family, inh_series,
821 SMALLCAPS_SHAPE, Color_foreground},
822 {"textsf", SANS_FAMILY, inh_series,
823 inh_shape, Color_foreground},
824 {"textsl", inh_family, inh_series,
825 SLANTED_SHAPE, Color_foreground},
826 {"texttt", TYPEWRITER_FAMILY, inh_series,
827 inh_shape, Color_foreground},
828 {"textup", inh_family, inh_series,
829 UP_SHAPE, Color_foreground},
832 {"textipa", inh_family, inh_series,
833 inh_shape, Color_foreground},
836 {"ce", inh_family, inh_series,
837 inh_shape, Color_foreground},
838 {"cf", inh_family, inh_series,
839 inh_shape, Color_foreground},
841 // LyX internal usage
842 {"lyxtex", inh_family, inh_series,
843 UP_SHAPE, Color_latex},
844 // FIXME: The following two don't work on OS X, since the Symbol font
845 // uses a different encoding, and is therefore disabled in
846 // FontLoader::available().
847 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
848 inh_shape, Color_math},
849 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
850 inh_shape, Color_math},
851 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
852 UP_SHAPE, Color_foreground},
853 {"lyxnochange", inh_family, inh_series,
854 inh_shape, Color_foreground},
855 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
856 UP_SHAPE, Color_math},
857 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
858 ITALIC_SHAPE, Color_math},
859 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
860 ITALIC_SHAPE, Color_math}
864 fontinfo * lookupFont(string const & name)
866 //lyxerr << "searching font '" << name << "'" << endl;
867 int const n = sizeof(fontinfos) / sizeof(fontinfo);
868 for (int i = 0; i < n; ++i)
869 if (fontinfos[i].cmd_ == name) {
870 //lyxerr << "found '" << i << "'" << endl;
871 return fontinfos + i;
877 fontinfo * searchFont(string const & name)
879 fontinfo * f = lookupFont(name);
880 return f ? f : fontinfos;
881 // this should be mathnormal
882 //return searchFont("mathnormal");
886 bool isFontName(string const & name)
888 return lookupFont(name);
892 bool isMathFont(string const & name)
894 fontinfo * f = lookupFont(name);
895 return f && f->color_ == Color_math;
899 bool isTextFont(string const & name)
901 fontinfo * f = lookupFont(name);
902 return f && f->color_ == Color_foreground;
906 FontInfo getFont(string const & name)
909 augmentFont(font, name);
914 void fakeFont(string const & orig, string const & fake)
916 fontinfo * forig = searchFont(orig);
917 fontinfo * ffake = searchFont(fake);
918 if (forig && ffake) {
919 forig->family_ = ffake->family_;
920 forig->series_ = ffake->series_;
921 forig->shape_ = ffake->shape_;
922 forig->color_ = ffake->color_;
924 lyxerr << "Can't fake font '" << orig << "' with '"
925 << fake << "'" << endl;
930 void augmentFont(FontInfo & font, string const & name)
932 static bool initialized = false;
935 // fake fonts if necessary
936 if (!theFontLoader().available(getFont("mathfrak")))
937 fakeFont("mathfrak", "lyxfakefrak");
938 if (!theFontLoader().available(getFont("mathcal")))
939 fakeFont("mathcal", "lyxfakecal");
941 fontinfo * info = searchFont(name);
942 if (info->family_ != inh_family)
943 font.setFamily(info->family_);
944 if (info->series_ != inh_series)
945 font.setSeries(info->series_);
946 if (info->shape_ != inh_shape)
947 font.setShape(info->shape_);
948 if (info->color_ != Color_none)
949 font.setColor(info->color_);
953 bool isAlphaSymbol(MathAtom const & at)
955 if (at->asCharInset() ||
956 (at->asSymbolInset() &&
957 at->asSymbolInset()->isOrdAlpha()))
960 if (at->asFontInset()) {
961 MathData const & ar = at->asFontInset()->cell(0);
962 for (size_t i = 0; i < ar.size(); ++i) {
963 if (!(ar[i]->asCharInset() ||
964 (ar[i]->asSymbolInset() &&
965 ar[i]->asSymbolInset()->isOrdAlpha())))
974 docstring asString(MathData const & ar)
977 otexrowstream ots(os);
984 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
986 // If the QUIET flag is set, we are going to parse for either
987 // a paste operation or a macro definition. We try to do the
988 // right thing in all cases.
990 bool quiet = pf & Parse::QUIET;
991 bool macro = pf & Parse::MACRODEF;
992 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet && !macro))
993 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
997 docstring asString(InsetMath const & inset)
1000 otexrowstream ots(os);
1001 WriteStream ws(ots);
1007 docstring asString(MathAtom const & at)
1009 odocstringstream os;
1010 otexrowstream ots(os);
1011 WriteStream ws(ots);
1017 int axis_height(MetricsBase & mb)
1019 Changer dummy = mb.changeFontSet("mathnormal");
1020 return theFontMetrics(mb.font).ascent('-') - 1;
1024 void validate_math_word(LaTeXFeatures & features, docstring const & word)
1026 MathWordList const & words = mathedWordList();
1027 MathWordList::const_iterator it = words.find(word);
1028 if (it != words.end()) {
1029 string const req = it->second.required;
1031 features.require(req);