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 // Is this correct? (Lgb)
289 double const arrow[] = {
291 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
292 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
294 3, 0.5000, 0.1500, 0.5000, 0.9500,
299 // Is this correct? (Lgb)
300 double const Arrow[] = {
302 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
303 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
305 3, 0.3500, 0.5000, 0.3500, 0.9500,
306 3, 0.6500, 0.5000, 0.6500, 0.9500,
311 double const udarrow[] = {
313 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
315 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
316 1, 0.5, 0.2, 0.5, 0.8,
321 double const Udarrow[] = {
323 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
325 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
326 1, 0.35, 0.2, 0.35, 0.8,
327 1, 0.65, 0.2, 0.65, 0.8,
332 double const brack[] = {
334 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
339 double const corner[] = {
341 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
346 double const angle[] = {
348 1, 0, 0.05, 0.5, 1, 1,
353 double const slash[] = {
354 1, 0.95, 0.05, 0.05, 0.95,
359 double const hline[] = {
360 1, 0.05, 0.5, 0.95, 0.5,
365 double const hline2[] = {
366 1, 0.1, 0.5, 0.3, 0.5,
367 1, 0.7, 0.5, 0.9, 0.5,
372 double const hline3[] = {
374 1, 0.475, 0, 0.525, 0,
380 double const dline3[] = {
381 1, 0.1, 0.1, 0.15, 0.15,
382 1, 0.475, 0.475, 0.525, 0.525,
383 1, 0.85, 0.85, 0.9, 0.9,
388 double const hlinesmall[] = {
389 1, 0.4, 0.5, 0.6, 0.5,
394 double const vert[] = {
395 1, 0.5, 0.05, 0.5, 0.95,
400 double const Vert[] = {
401 1, 0.3, 0.05, 0.3, 0.95,
402 1, 0.7, 0.05, 0.7, 0.95,
407 double const tilde[] = {
409 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
419 struct named_deco_struct {
425 named_deco_struct deco_table[] = {
427 {"widehat", angle, 3 },
428 {"widetilde", tilde, 0 },
429 {"underline", hline, 0 },
430 {"overline", hline, 0 },
431 {"underbrace", brace, 1 },
432 {"overbrace", brace, 3 },
433 {"overleftarrow", arrow, 1 },
434 {"overrightarrow", arrow, 3 },
447 {"backslash", slash, 1 },
448 {"langle", angle, 0 },
449 {"lceil", corner, 0 },
450 {"lfloor", corner, 1 },
451 {"rangle", angle, 2 },
452 {"rceil", corner, 3 },
453 {"rfloor", corner, 2 },
454 {"downarrow", arrow, 2 },
455 {"Downarrow", Arrow, 2 },
456 {"uparrow", arrow, 0 },
457 {"Uparrow", Arrow, 0 },
458 {"updownarrow", udarrow, 0 },
459 {"Updownarrow", Udarrow, 0 },
462 {"ddot", hline2, 0 },
464 {"grave", slash, 1 },
465 {"acute", slash, 0 },
466 {"tilde", tilde, 0 },
468 {"dot", hlinesmall, 0 },
469 {"check", angle, 1 },
470 {"breve", parenth, 1 },
475 {"ldots", hline3, 0 },
476 {"cdots", hline3, 0 },
477 {"vdots", hline3, 1 },
478 {"ddots", dline3, 0 }
482 map<string, deco_struct> deco_list;
484 // sort the table on startup
485 struct init_deco_table {
487 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
488 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
492 deco_list[p->name]= d;
497 static init_deco_table dummy;
500 deco_struct const * search_deco(string const & name)
502 map<string, deco_struct>::const_iterator p = deco_list.find(name);
503 return (p == deco_list.end()) ? 0 : &(p->second);
510 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
511 int & asc, int & des, int & wid)
513 LyXFont const font = whichFont(type, size);
514 des = lyxfont::descent(c, font);
515 asc = lyxfont::ascent(c, font);
516 wid = mathed_char_width(type, size, c);
520 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
521 int & asc, int & des)
523 LyXFont const font = whichFont(type, size);
524 des = lyxfont::descent(c, font);
525 asc = lyxfont::ascent(c, font);
530 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
534 return mathed_char_height(type, size, c, asc, des);
538 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
540 LyXFont const font = whichFont(type, size);
541 return lyxfont::ascent(c, font);
545 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
547 LyXFont const font = whichFont(type, size);
548 return lyxfont::descent(c, font);
552 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
554 LyXFont const font = whichFont(type, size);
555 LyXFont const f1 = whichFont(LM_TC_TEXTRM, size);
556 #warning why f1 is used ?
557 if (isBinaryOp(c, type))
558 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', f1);
560 return lyxfont::width(c, font);
564 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
565 int & asc, int & des, int & wid)
567 mathed_string_height(type, size, s, asc, des);
568 wid = mathed_string_width(type, size, s);
572 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
573 int & asc, int & des)
575 LyXFont const font = whichFont(type, size);
577 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
578 des = max(des, lyxfont::descent(*it, font));
579 asc = max(asc, lyxfont::ascent(*it, font));
585 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
587 return lyxfont::width(s, whichFont(type, size));
591 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
595 pain.line(x + w/2, y, x + w/2, y + h,
596 LColor::mathcursor, Painter::line_onoffdash);
600 deco_struct const * mds = search_deco(name);
602 lyxerr << "Deco was not found. Programming error?\n";
603 lyxerr << "name: '" << name << "'\n";
607 int const n = (w < h) ? w : h;
608 int const r = mds->angle;
609 double const * d = mds->data;
611 if (h > 70 && (name == "(" || name == ")"))
615 Matrix sqmt(r, n, n);
623 for (int i = 0; d[i]; ) {
624 int code = int(d[i++]);
625 if (code & 1) { // code == 1 || code == 3
631 sqmt.transform(xx, yy);
633 mt.transform(xx, yy);
634 mt.transform(x2, y2);
635 pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
640 int const n = int(d[i++]);
641 for (int j = 0; j < n; ++j) {
644 // lyxerr << " " << xx << " " << yy << " ";
646 sqmt.transform(xx, yy);
648 mt.transform(xx, yy);
651 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
653 pain.lines(xp, yp, n, LColor::mathline);
659 // In the future maybe we use a better fonts renderer
660 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
661 int x, int y, string const & s)
663 pain.text(x, y, s, whichFont(type, siz));
668 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
671 if (isBinaryOp(c, type))
674 if (isBinaryOp(c, type))
676 drawStr(pain, type, siz, x, y, s);
680 // decrease math size for super- and subscripts
681 MathStyles smallerStyleScript(MathStyles st)
685 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
686 default: st = LM_ST_SCRIPTSCRIPT;
692 // decrease math size for fractions
693 MathStyles smallerStyleFrac(MathStyles st)
696 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
697 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
698 default: st = LM_ST_SCRIPTSCRIPT;
704 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
706 LyXFont font = whichFont(code, siz);
707 asc = lyxfont::maxAscent(font);
708 des = lyxfont::maxDescent(font);
712 char const * latex_mathspace[] = {
713 "!", ",", ":", ";", "quad", "qquad"