5 #include "mathed/support.h"
7 #include "FontLoader.h"
10 #include "math_parser.h"
18 bool isBinaryOp(char c, MathTextCodes type)
20 return type < LM_TC_SYMB && strchr("+-<>=/*", c);
28 typedef float matriz_data[2][2];
34 void escalate(float, float);
36 void transform(float, float, float &, float &);
41 void multiply(matriz_data & a);
52 void Matrix::rotate(int code)
59 float const cs = (code & 1) ? 0 : (1 - code);
60 float const sn = (code & 1) ? (2 - code) : 0;
68 void Matrix::escalate(float x, float y)
78 void Matrix::multiply(matriz_data & a)
81 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
82 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
83 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
84 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
91 void Matrix::transform(float xp, float yp, float & x, float & y)
93 x = m_[0][0] * xp + m_[0][1] * yp;
94 y = m_[1][0] * xp + m_[1][1] * yp;
100 LyXFont * MathFonts = 0;
101 bool font_available[LM_FONT_END];
102 bool font_available_initialized[LM_FONT_END];
123 void mathed_init_fonts()
125 MathFonts = new LyXFont[FONT_NUM]; //DEC cxx cannot initialize all fonts
128 for (int i = 0 ; i < FONT_NUM ; ++i) {
129 MathFonts[i] = LyXFont(LyXFont::ALL_SANE);
132 MathFonts[FONT_IT].setShape(LyXFont::ITALIC_SHAPE);
134 MathFonts[FONT_SYMBOL].setFamily(LyXFont::SYMBOL_FAMILY);
136 MathFonts[FONT_SYMBOLI].setFamily(LyXFont::SYMBOL_FAMILY);
137 MathFonts[FONT_SYMBOLI].setShape(LyXFont::ITALIC_SHAPE);
139 MathFonts[FONT_BF].setSeries(LyXFont::BOLD_SERIES);
141 MathFonts[FONT_BB].setSeries(LyXFont::BOLD_SERIES);
142 MathFonts[FONT_BB].setFamily(LyXFont::TYPEWRITER_FAMILY);
144 MathFonts[FONT_CAL].setFamily(LyXFont::SANS_FAMILY);
145 MathFonts[FONT_CAL].setShape(LyXFont::ITALIC_SHAPE);
147 MathFonts[FONT_TT].setFamily(LyXFont::TYPEWRITER_FAMILY);
149 MathFonts[FONT_RM].setFamily(LyXFont::ROMAN_FAMILY);
151 MathFonts[FONT_SF].setFamily(LyXFont::SANS_FAMILY);
153 MathFonts[FONT_CMR].setFamily(LyXFont::CMR_FAMILY);
154 MathFonts[FONT_CMSY].setFamily(LyXFont::CMSY_FAMILY);
155 MathFonts[FONT_CMM].setFamily(LyXFont::CMM_FAMILY);
156 MathFonts[FONT_CMEX].setFamily(LyXFont::CMEX_FAMILY);
157 MathFonts[FONT_MSA].setFamily(LyXFont::MSA_FAMILY);
158 MathFonts[FONT_MSB].setFamily(LyXFont::MSB_FAMILY);
160 for (int i = 0; i < LM_FONT_END; ++i)
161 font_available_initialized[i] = false;
165 LyXFont const & whichFontBase(MathTextCodes type)
173 return MathFonts[FONT_SYMBOLI];
177 return MathFonts[FONT_IT];
180 return MathFonts[FONT_BF];
183 if (math_font_available(LM_TC_MSB))
184 return MathFonts[FONT_MSB];
186 return MathFonts[FONT_BB];
189 if (math_font_available(LM_TC_CMSY))
190 return MathFonts[FONT_CMSY];
192 return MathFonts[FONT_CAL];
195 return MathFonts[FONT_TT];
201 return MathFonts[FONT_RM];
204 return MathFonts[FONT_SF];
207 return MathFonts[FONT_CMR];
210 return MathFonts[FONT_CMSY];
213 return MathFonts[FONT_CMM];
216 return MathFonts[FONT_CMEX];
219 return MathFonts[FONT_MSA];
222 return MathFonts[FONT_MSB];
231 LyXFont whichFont(MathTextCodes type, MathStyles size)
233 LyXFont f = whichFontBase(type);
237 if (type == LM_TC_BOLDSYMB || type == LM_TC_CMEX) {
251 case LM_ST_SCRIPTSCRIPT:
258 lyxerr << "Math Error: wrong font size: " << size << endl;
262 if (type != LM_TC_TEXTRM)
263 f.setColor(LColor::math);
265 if (type == LM_TC_TEX)
266 f.setColor(LColor::latex);
274 bool math_font_available(MathTextCodes type)
276 if (!font_available_initialized[type]) {
277 font_available_initialized[type] = true;
278 font_available[type] =
279 fontloader.available(whichFontBase(type));
281 return font_available[type];
288 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
289 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
293 float const parenthHigh[] = {
295 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
296 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
297 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
298 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
304 float const parenth[] = {
306 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
307 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
308 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
309 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
315 float const brace[] = {
317 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
318 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
319 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
320 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
321 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
322 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
323 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
328 // Is this correct? (Lgb)
329 float const arrow[] = {
331 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
332 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
334 3, 0.5000, 0.1500, 0.5000, 0.9500,
339 // Is this correct? (Lgb)
340 float const Arrow[] = {
342 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
343 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
345 3, 0.3500, 0.5000, 0.3500, 0.9500,
346 3, 0.6500, 0.5000, 0.6500, 0.9500,
351 float const udarrow[] = {
353 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
355 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
356 1, 0.5, 0.2, 0.5, 0.8,
361 float const Udarrow[] = {
363 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
365 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
366 1, 0.35, 0.2, 0.35, 0.8,
367 1, 0.65, 0.2, 0.65, 0.8,
372 float const brack[] = {
374 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
379 float const corner[] = {
381 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
386 float const angle[] = {
388 1, 0, 0.05, 0.5, 1, 1,
393 float const slash[] = {
394 1, 0.95, 0.05, 0.05, 0.95,
399 float const hline[] = {
400 1, 0.05, 0.5, 0.95, 0.5,
405 float const hline2[] = {
406 1, 0.1, 0.5, 0.3, 0.5,
407 1, 0.7, 0.5, 0.9, 0.5,
412 float const hline3[] = {
414 1, 0.475, 0, 0.525, 0,
420 float const dline3[] = {
421 1, 0.1, 0.1, 0.15, 0.15,
422 1, 0.475, 0.475, 0.525, 0.525,
423 1, 0.85, 0.85, 0.9, 0.9,
428 float const hlinesmall[] = {
429 1, 0.4, 0.5, 0.6, 0.5,
434 float const vert[] = {
435 1, 0.5, 0.05, 0.5, 0.95,
440 float const Vert[] = {
441 1, 0.3, 0.05, 0.3, 0.95,
442 1, 0.7, 0.05, 0.7, 0.95,
447 float const tilde[] = {
449 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
459 struct named_deco_struct {
465 named_deco_struct deco_table[] = {
467 {"widehat", angle, 3 },
468 {"widetilde", tilde, 0 },
469 {"underline", hline, 0 },
470 {"overline", hline, 0 },
471 {"underbrace", brace, 1 },
472 {"overbrace", brace, 3 },
473 {"overleftarrow", arrow, 1 },
474 {"overightarrow", arrow, 3 },
487 {"langle", angle, 0 },
488 {"lceil", corner, 0 },
489 {"lfloor", corner, 1 },
490 {"rangle", angle, 2 },
491 {"rceil", corner, 3 },
492 {"rfloor", corner, 2 },
493 {"downarrow", arrow, 2 },
494 {"Downarrow", Arrow, 2 },
495 {"uparrow", arrow, 0 },
496 {"Uparrow", Arrow, 0 },
497 {"updownarrow", udarrow, 0 },
498 {"Updownarrow", Udarrow, 0 },
501 {"ddot", hline2, 0 },
503 {"grave", slash, 1 },
504 {"acute", slash, 0 },
505 {"tilde", tilde, 0 },
507 {"dot", hlinesmall, 0 },
508 {"check", angle, 1 },
509 {"breve", parenth, 1 },
514 {"ldots", hline3, 0 },
515 {"cdots", hline3, 0 },
516 {"vdots", hline3, 1 },
517 {"ddots", dline3, 0 }
521 std::map<string, deco_struct> deco_list;
523 // sort the table on startup
524 struct init_deco_table {
526 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
527 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
531 deco_list[p->name]= d;
536 static init_deco_table dummy;
539 deco_struct const * search_deco(string const & name)
541 map<string, deco_struct>::const_iterator p = deco_list.find(name);
542 return (p == deco_list.end()) ? 0 : &(p->second);
549 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
550 int & asc, int & des, int & wid)
552 LyXFont const font = whichFont(type, size);
553 des = lyxfont::descent(c, font);
554 asc = lyxfont::ascent(c, font);
555 wid = mathed_char_width(type, size, c);
559 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
560 int & asc, int & des)
562 LyXFont const font = whichFont(type, size);
563 des = lyxfont::descent(c, font);
564 asc = lyxfont::ascent(c, font);
569 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
573 return mathed_char_height(type, size, c, asc, des);
577 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
579 LyXFont const font = whichFont(type, size);
580 return lyxfont::ascent(c, font);
584 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
586 LyXFont const font = whichFont(type, size);
587 return lyxfont::descent(c, font);
591 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
593 LyXFont const font = whichFont(type, size);
594 LyXFont const f1 = whichFont(LM_TC_TEXTRM, size);
595 #warning why f1 is used ?
596 if (isBinaryOp(c, type))
597 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', f1);
599 return lyxfont::width(c, font);
603 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
604 int & asc, int & des, int & wid)
606 mathed_string_height(type, size, s, asc, des);
607 wid = mathed_string_width(type, size, s);
611 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
612 int & asc, int & des)
614 LyXFont const font = whichFont(type, size);
616 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
617 des = max(des, lyxfont::descent(*it, font));
618 asc = max(asc, lyxfont::ascent(*it, font));
624 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
626 return lyxfont::width(s, whichFont(type, size));
630 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
638 pain.line(x + w/2, y, x + w/2, y + h,
639 LColor::mathcursor, Painter::line_onoffdash);
643 deco_struct const * mds = search_deco(name);
645 lyxerr << "Deco was not found. Programming error?\n";
646 lyxerr << "name: '" << name << "\n";
650 int const r = mds->angle;
651 float const * d = mds->data;
653 if (h > 70 && (name == "(" || name == ")"))
659 int const n = (w < h) ? w : h;
683 xx = d[i++]; yy = d[i++];
684 x2 = d[i++]; y2 = d[i++];
686 sqmt.transform(xx, yy, xx, yy);
688 mt.transform(xx, yy, xx, yy);
689 mt.transform(x2, y2, x2, y2);
690 pain.line(x + int(xx), y + int(yy),
691 x + int(x2), y + int(y2),
700 int const n = int(d[i++]);
701 for (int j = 0; j < n; ++j) {
702 xx = d[i++]; yy = d[i++];
703 // lyxerr << " " << xx << " " << yy << " ";
705 sqmt.transform(xx, yy, xx, yy);
707 mt.transform(xx, yy, xx, yy);
710 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
712 pain.lines(xp, yp, n, LColor::mathline);
719 // In the future maybe we use a better fonts renderer
720 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
721 int x, int y, string const & s)
723 pain.text(x, y, s, whichFont(type, siz));
728 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
731 if (isBinaryOp(c, type))
734 if (isBinaryOp(c, type))
736 drawStr(pain, type, siz, x, y, s);
740 // decrease math size for super- and subscripts
741 MathStyles smallerStyleScript(MathStyles st)
745 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
746 default: st = LM_ST_SCRIPTSCRIPT;
752 // decrease math size for fractions
753 MathStyles smallerStyleFrac(MathStyles st)
756 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
757 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
758 default: st = LM_ST_SCRIPTSCRIPT;
764 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
766 LyXFont font = whichFont(code, siz);
767 asc = lyxfont::maxAscent(font);
768 des = lyxfont::maxDescent(font);
772 char const * latex_mathspace[] = {
773 "!", ",", ":", ";", "quad", "qquad"