5 #include "mathed/support.h"
7 #include "FontLoader.h"
10 #include "math_parser.h"
19 bool isBinaryOp(char c, MathTextCodes type)
21 return type < LM_TC_SYMB && strchr("+-<>=/*", c);
29 Matrix(int, double, double);
31 void transform(double &, double &);
38 Matrix::Matrix(int code, double x, double y)
40 double const cs = (code & 1) ? 0 : (1 - code);
41 double const sn = (code & 1) ? (2 - code) : 0;
49 void Matrix::transform(double & x, double & y)
51 double xx = m_[0][0] * x + m_[0][1] * y;
52 double yy = m_[1][0] * x + m_[1][1] * y;
60 LyXFont * MathFonts = 0;
61 bool font_available[LM_FONT_END];
62 bool font_available_initialized[LM_FONT_END];
83 void mathed_init_fonts()
85 MathFonts = new LyXFont[FONT_NUM]; //DEC cxx cannot initialize all fonts
88 for (int i = 0 ; i < FONT_NUM ; ++i) {
89 MathFonts[i] = LyXFont(LyXFont::ALL_SANE);
92 MathFonts[FONT_IT].setShape(LyXFont::ITALIC_SHAPE);
94 MathFonts[FONT_SYMBOL].setFamily(LyXFont::SYMBOL_FAMILY);
96 MathFonts[FONT_SYMBOLI].setFamily(LyXFont::SYMBOL_FAMILY);
97 MathFonts[FONT_SYMBOLI].setShape(LyXFont::ITALIC_SHAPE);
99 MathFonts[FONT_BF].setSeries(LyXFont::BOLD_SERIES);
101 MathFonts[FONT_BB].setSeries(LyXFont::BOLD_SERIES);
102 MathFonts[FONT_BB].setFamily(LyXFont::TYPEWRITER_FAMILY);
104 MathFonts[FONT_CAL].setFamily(LyXFont::SANS_FAMILY);
105 MathFonts[FONT_CAL].setShape(LyXFont::ITALIC_SHAPE);
107 MathFonts[FONT_TT].setFamily(LyXFont::TYPEWRITER_FAMILY);
109 MathFonts[FONT_RM].setFamily(LyXFont::ROMAN_FAMILY);
111 MathFonts[FONT_SF].setFamily(LyXFont::SANS_FAMILY);
113 MathFonts[FONT_CMR].setFamily(LyXFont::CMR_FAMILY);
114 MathFonts[FONT_CMSY].setFamily(LyXFont::CMSY_FAMILY);
115 MathFonts[FONT_CMM].setFamily(LyXFont::CMM_FAMILY);
116 MathFonts[FONT_CMEX].setFamily(LyXFont::CMEX_FAMILY);
117 MathFonts[FONT_MSA].setFamily(LyXFont::MSA_FAMILY);
118 MathFonts[FONT_MSB].setFamily(LyXFont::MSB_FAMILY);
120 for (int i = 0; i < LM_FONT_END; ++i)
121 font_available_initialized[i] = false;
125 LyXFont const & whichFontBase(MathTextCodes type)
133 return MathFonts[FONT_SYMBOLI];
137 return MathFonts[FONT_IT];
140 return MathFonts[FONT_BF];
143 if (math_font_available(LM_TC_MSB))
144 return MathFonts[FONT_MSB];
146 return MathFonts[FONT_BB];
149 if (math_font_available(LM_TC_CMSY))
150 return MathFonts[FONT_CMSY];
152 return MathFonts[FONT_CAL];
155 return MathFonts[FONT_TT];
161 return MathFonts[FONT_RM];
164 return MathFonts[FONT_SF];
167 return MathFonts[FONT_CMR];
170 return MathFonts[FONT_CMSY];
173 return MathFonts[FONT_CMM];
176 return MathFonts[FONT_CMEX];
179 return MathFonts[FONT_MSA];
182 return MathFonts[FONT_MSB];
191 LyXFont whichFont(MathTextCodes type, MathStyles size)
193 LyXFont f = whichFontBase(type);
197 if (type == LM_TC_BOLDSYMB || type == LM_TC_CMEX) {
211 case LM_ST_SCRIPTSCRIPT:
218 lyxerr << "Math Error: wrong font size: " << size << endl;
222 if (type != LM_TC_TEXTRM)
223 f.setColor(LColor::math);
225 if (type == LM_TC_TEX)
226 f.setColor(LColor::latex);
234 bool math_font_available(MathTextCodes type)
236 if (!font_available_initialized[type]) {
237 font_available_initialized[type] = true;
238 font_available[type] =
239 fontloader.available(whichFontBase(type));
241 return font_available[type];
248 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
249 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
253 double const parenthHigh[] = {
255 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
256 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
257 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
258 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
264 double const parenth[] = {
266 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
267 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
268 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
269 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
275 double const brace[] = {
277 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
278 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
279 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
280 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
281 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
282 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
283 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
288 double const arrow[] = {
290 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
291 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
293 3, 0.5000, 0.1500, 0.5000, 0.9500,
298 double const Arrow[] = {
300 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
301 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
303 3, 0.3500, 0.5000, 0.3500, 0.9500,
304 3, 0.6500, 0.5000, 0.6500, 0.9500,
309 double const udarrow[] = {
311 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
313 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
314 1, 0.5, 0.2, 0.5, 0.8,
319 double const Udarrow[] = {
321 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
323 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
324 1, 0.35, 0.2, 0.35, 0.8,
325 1, 0.65, 0.2, 0.65, 0.8,
330 double const brack[] = {
332 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
337 double const corner[] = {
339 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
344 double const angle[] = {
346 1, 0, 0.05, 0.5, 1, 1,
351 double const slash[] = {
352 1, 0.95, 0.05, 0.05, 0.95,
357 double const hline[] = {
358 1, 0.05, 0.5, 0.95, 0.5,
363 double const hline2[] = {
364 1, 0.1, 0.5, 0.3, 0.5,
365 1, 0.7, 0.5, 0.9, 0.5,
370 double const hline3[] = {
372 1, 0.475, 0, 0.525, 0,
378 double const dline3[] = {
379 1, 0.1, 0.1, 0.15, 0.15,
380 1, 0.475, 0.475, 0.525, 0.525,
381 1, 0.85, 0.85, 0.9, 0.9,
386 double const hlinesmall[] = {
387 1, 0.4, 0.5, 0.6, 0.5,
392 double const vert[] = {
393 1, 0.5, 0.05, 0.5, 0.95,
398 double const Vert[] = {
399 1, 0.3, 0.05, 0.3, 0.95,
400 1, 0.7, 0.05, 0.7, 0.95,
405 double const tilde[] = {
407 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
417 struct named_deco_struct {
423 named_deco_struct deco_table[] = {
425 {"widehat", angle, 3 },
426 {"widetilde", tilde, 0 },
427 {"underline", hline, 0 },
428 {"overline", hline, 0 },
429 {"underbrace", brace, 1 },
430 {"overbrace", brace, 3 },
431 {"overleftarrow", arrow, 1 },
432 {"overrightarrow", arrow, 3 },
445 {"backslash", slash, 1 },
446 {"langle", angle, 0 },
447 {"lceil", corner, 0 },
448 {"lfloor", corner, 1 },
449 {"rangle", angle, 2 },
450 {"rceil", corner, 3 },
451 {"rfloor", corner, 2 },
452 {"downarrow", arrow, 2 },
453 {"Downarrow", Arrow, 2 },
454 {"uparrow", arrow, 0 },
455 {"Uparrow", Arrow, 0 },
456 {"updownarrow", udarrow, 0 },
457 {"Updownarrow", Udarrow, 0 },
460 {"ddot", hline2, 0 },
462 {"grave", slash, 1 },
463 {"acute", slash, 0 },
464 {"tilde", tilde, 0 },
466 {"dot", hlinesmall, 0 },
467 {"check", angle, 1 },
468 {"breve", parenth, 1 },
473 {"ldots", hline3, 0 },
474 {"cdots", hline3, 0 },
475 {"vdots", hline3, 1 },
476 {"ddots", dline3, 0 }
480 map<string, deco_struct> deco_list;
482 // sort the table on startup
483 struct 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[p->name]= d;
495 static init_deco_table dummy;
498 deco_struct const * search_deco(string const & name)
500 map<string, deco_struct>::const_iterator p = deco_list.find(name);
501 return (p == deco_list.end()) ? 0 : &(p->second);
508 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
509 int & asc, int & des, int & wid)
511 LyXFont const font = whichFont(type, size);
512 des = lyxfont::descent(c, font);
513 asc = lyxfont::ascent(c, font);
514 wid = mathed_char_width(type, size, c);
518 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
519 int & asc, int & des)
521 LyXFont const font = whichFont(type, size);
522 des = lyxfont::descent(c, font);
523 asc = lyxfont::ascent(c, font);
528 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
532 return mathed_char_height(type, size, c, asc, des);
536 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
538 LyXFont const font = whichFont(type, size);
539 return lyxfont::ascent(c, font);
543 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
545 LyXFont const font = whichFont(type, size);
546 return lyxfont::descent(c, font);
550 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
552 LyXFont const font = whichFont(type, size);
553 LyXFont const f1 = whichFont(LM_TC_TEXTRM, size);
554 #warning why f1 is used ?
555 if (isBinaryOp(c, type))
556 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', f1);
558 return lyxfont::width(c, font);
562 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
563 int & asc, int & des, int & wid)
565 mathed_string_height(type, size, s, asc, des);
566 wid = mathed_string_width(type, size, s);
570 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
571 int & asc, int & des)
573 LyXFont const font = whichFont(type, size);
575 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
576 des = max(des, lyxfont::descent(*it, font));
577 asc = max(asc, lyxfont::ascent(*it, font));
583 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
585 return lyxfont::width(s, whichFont(type, size));
589 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
593 pain.line(x + w/2, y, x + w/2, y + h,
594 LColor::mathcursor, Painter::line_onoffdash);
598 deco_struct const * mds = search_deco(name);
600 lyxerr << "Deco was not found. Programming error?\n";
601 lyxerr << "name: '" << name << "'\n";
605 int const n = (w < h) ? w : h;
606 int const r = mds->angle;
607 double const * d = mds->data;
609 if (h > 70 && (name == "(" || name == ")"))
613 Matrix sqmt(r, n, n);
621 for (int i = 0; d[i]; ) {
622 int code = int(d[i++]);
623 if (code & 1) { // code == 1 || code == 3
629 sqmt.transform(xx, yy);
631 mt.transform(xx, yy);
632 mt.transform(x2, y2);
633 pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
638 int const n = int(d[i++]);
639 for (int j = 0; j < n; ++j) {
642 // lyxerr << " " << xx << " " << yy << " ";
644 sqmt.transform(xx, yy);
646 mt.transform(xx, yy);
649 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
651 pain.lines(xp, yp, n, LColor::mathline);
657 // In the future maybe we use a better fonts renderer
658 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
659 int x, int y, string const & s)
661 pain.text(x, y, s, whichFont(type, siz));
666 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
669 if (isBinaryOp(c, type))
672 if (isBinaryOp(c, type))
674 drawStr(pain, type, siz, x, y, s);
678 // decrease math size for super- and subscripts
679 MathStyles smallerStyleScript(MathStyles st)
683 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
684 default: st = LM_ST_SCRIPTSCRIPT;
690 // decrease math size for fractions
691 MathStyles smallerStyleFrac(MathStyles st)
694 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
695 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
696 default: st = LM_ST_SCRIPTSCRIPT;
702 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
704 LyXFont font = whichFont(code, siz);
705 asc = lyxfont::maxAscent(font);
706 des = lyxfont::maxDescent(font);
710 char const * latex_mathspace[] = {
711 "!", ",", ":", ";", "quad", "qquad"