5 #include "mathed/support.h"
9 #include "math_parser.h"
14 using std::lower_bound;
19 bool isBinaryOp(char c)
21 return strchr("+-<>=/*", c);
29 typedef float matriz_data[2][2];
35 void escalate(float, float);
37 void transform(float, float, float &, float &);
42 void multiply(matriz_data & a);
53 void Matrix::rotate(int code)
60 float const cs = (code & 1) ? 0 : (1 - code);
61 float const sn = (code & 1) ? (2 - code) : 0;
69 void Matrix::escalate(float x, float y)
79 void Matrix::multiply(matriz_data & a)
82 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
83 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
84 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
85 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
92 void Matrix::transform(float xp, float yp, float & x, float & y)
94 x = m_[0][0] * xp + m_[0][1] * yp;
95 y = m_[1][0] * xp + m_[1][1] * yp;
101 LyXFont * Math_Fonts = 0;
103 void mathed_init_fonts()
105 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
108 for (int i = 0 ; i < 8 ; ++i) {
109 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
112 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
114 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
116 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
117 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
119 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
121 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
122 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
124 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
126 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
128 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
134 LyXFont WhichFont(MathTextCodes type, MathStyles size)
168 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
183 if (type == LM_TC_BSYM) {
197 case LM_ST_SCRIPTSCRIPT:
204 lyxerr << "Math Error: wrong font size: " << size << endl;
208 if (type != LM_TC_TEXTRM)
209 f.setColor(LColor::math);
211 if (type == LM_TC_TEX)
212 f.setColor(LColor::latex);
217 char const * math_font_name[] = {
231 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
232 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
236 float const parenthHigh[] = {
238 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
239 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
240 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
241 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
247 float const parenth[] = {
249 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
250 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
251 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
252 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
258 float const brace[] = {
260 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
261 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
262 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
263 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
264 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
265 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
266 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
271 // Is this correct? (Lgb)
272 float const arrow[] = {
274 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
275 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
277 3, 0.5000, 0.1500, 0.5000, 0.9500,
282 // Is this correct? (Lgb)
283 float const Arrow[] = {
285 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
286 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
288 3, 0.3500, 0.5000, 0.3500, 0.9500,
289 3, 0.6500, 0.5000, 0.6500, 0.9500,
294 float const udarrow[] = {
296 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
298 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
299 1, 0.5, 0.2, 0.5, 0.8,
304 float const Udarrow[] = {
306 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
308 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
309 1, 0.35, 0.2, 0.35, 0.8,
310 1, 0.65, 0.2, 0.65, 0.8,
315 float const brack[] = {
317 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
322 float const corner[] = {
324 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
329 float const angle[] = {
331 1, 0, 0.05, 0.5, 1, 1,
336 float const slash[] = {
337 1, 0.95, 0.05, 0.05, 0.95,
342 float const hline[] = {
343 1, 0.05, 0.5, 0.95, 0.5,
348 float const hline2[] = {
349 1, 0.1, 0.5, 0.3, 0.5,
350 1, 0.7, 0.5, 0.9, 0.5,
355 float const hline3[] = {
357 1, 0.475, 0, 0.525, 0,
363 float const dline3[] = {
364 1, 0.1, 0.1, 0.15, 0.15,
365 1, 0.475, 0.475, 0.525, 0.525,
366 1, 0.85, 0.85, 0.9, 0.9,
371 float const hlinesmall[] = {
372 1, 0.4, 0.5, 0.6, 0.5,
377 float const vert[] = {
378 1, 0.5, 0.05, 0.5, 0.95,
383 float const Vert[] = {
384 1, 0.3, 0.05, 0.3, 0.95,
385 1, 0.7, 0.05, 0.7, 0.95,
390 float const tilde[] = {
392 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
403 deco_struct deco_table[] = {
405 { LM_widehat, &angle[0], 3 },
406 { LM_widetilde, &tilde[0], 0 },
407 { LM_underline, &hline[0], 0 },
408 { LM_overline, &hline[0], 0 },
409 { LM_underbrace, &brace[0], 1 },
410 { LM_overbrace, &brace[0], 3 },
411 { LM_overleftarrow, &arrow[0], 1 },
412 { LM_overightarrow, &arrow[0], 3 },
415 { '(', &parenth[0], 0 },
416 { ')', &parenth[0], 2 },
417 { '{', &brace[0], 0 },
418 { '}', &brace[0], 2 },
419 { '[', &brack[0], 0 },
420 { ']', &brack[0], 2 },
421 { '|', &vert[0], 0 },
422 { '/', &slash[0], 0 },
423 { LM_Vert, &Vert[0], 0 },
424 { '\\', &slash[0], 1 },
425 { LM_langle, &angle[0], 0 },
426 { LM_lceil, &corner[0], 0 },
427 { LM_lfloor, &corner[0], 1 },
428 { LM_rangle, &angle[0], 2 },
429 { LM_rceil, &corner[0], 3 },
430 { LM_rfloor, &corner[0], 2 },
431 { LM_downarrow, &arrow[0], 2 },
432 { LM_Downarrow, &Arrow[0], 2 },
433 { LM_uparrow, &arrow[0], 0 },
434 { LM_Uparrow, &Arrow[0], 0 },
435 { LM_updownarrow, &udarrow[0], 0 },
436 { LM_Updownarrow, &Udarrow[0], 0 },
439 { LM_ddot, &hline2[0], 0 },
440 { LM_hat, &angle[0], 3 },
441 { LM_grave, &slash[0], 1 },
442 { LM_acute, &slash[0], 0 },
443 { LM_tilde, &tilde[0], 0 },
444 { LM_bar, &hline[0], 0 },
445 { LM_dot, &hlinesmall[0], 0 },
446 { LM_check, &angle[0], 1 },
447 { LM_breve, &parenth[0], 1 },
448 { LM_vec, &arrow[0], 3 },
449 { LM_not, &slash[0], 0 },
452 { LM_ldots, &hline3[0], 0 },
453 { LM_cdots, &hline3[0], 0 },
454 { LM_vdots, &hline3[0], 1 },
455 { LM_ddots, &dline3[0], 0 }
459 struct deco_compare {
460 /// for use by sort and lower_bound
461 int operator()(deco_struct const & a, deco_struct const & b) const
463 return a.code < b.code;
468 int const deco_table_size =
469 sizeof(deco_table) / sizeof(deco_struct);
472 // sort the table on startup
473 struct init_deco_table {
475 std::sort(deco_table,
476 deco_table + deco_table_size,
481 static init_deco_table dummy;
484 deco_struct const * search_deco(int code)
486 const deco_struct search_elem = { code, 0, 0 };
488 deco_struct const * res =
489 lower_bound(deco_table, deco_table + deco_table_size, search_elem,
491 if (res != deco_table + deco_table_size &&
501 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
502 int & asc, int & des, int & wid)
504 LyXFont const font = WhichFont(type, size);
505 des = lyxfont::descent(c, font);
506 asc = lyxfont::ascent(c, font);
507 wid = mathed_char_width(type, size, c);
511 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
512 int & asc, int & des)
514 LyXFont const font = WhichFont(type, size);
515 des = lyxfont::descent(c, font);
516 asc = lyxfont::ascent(c, font);
521 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
525 return mathed_char_height(type, size, c, asc, des);
528 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
530 LyXFont const font = WhichFont(type, size);
531 return lyxfont::ascent(c, font);
534 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
536 LyXFont const font = WhichFont(type, size);
537 return lyxfont::descent(c, font);
540 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
542 LyXFont const font = WhichFont(type, size);
544 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
546 return lyxfont::width(c, font);
550 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
551 int & asc, int & des, int & wid)
553 mathed_string_height(type, size, s, asc, des);
554 wid = mathed_string_width(type, size, s);
557 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
558 int & asc, int & des)
560 LyXFont const font = WhichFont(type, size);
562 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
563 des = max(des, lyxfont::descent(*it, font));
564 asc = max(asc, lyxfont::ascent(*it, font));
569 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
571 return lyxfont::width(s, WhichFont(type, size));
575 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
581 string name = l->name;
582 int code = (name.size() > 1) ? l->id : name[0];
585 pain.line(x + w/2, y, x + w/2, y + h,
586 LColor::mathcursor, Painter::line_onoffdash);
590 deco_struct const * mds = search_deco(code);
592 lyxerr << "Deco was not found. Programming error?\n";
593 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
597 int const r = mds->angle;
598 float const * d = mds->data;
600 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
606 int const n = (w < h) ? w : h;
629 xx = d[i++]; yy = d[i++];
630 x2 = d[i++]; y2 = d[i++];
632 sqmt.transform(xx, yy, xx, yy);
634 mt.transform(xx, yy, xx, yy);
635 mt.transform(x2, y2, x2, y2);
636 pain.line(x + int(xx), y + int(yy),
637 x + int(x2), y + int(y2),
646 int const n = int(d[i++]);
647 for (int j = 0; j < n; ++j) {
648 xx = d[i++]; yy = d[i++];
649 // lyxerr << " " << xx << " " << yy << " ";
651 sqmt.transform(xx, yy, xx, yy);
653 mt.transform(xx, yy, xx, yy);
656 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
658 pain.lines(xp, yp, n, LColor::mathline);
665 // In a near future maybe we use a better fonts renderer
666 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
667 int x, int y, string const & s)
669 pain.text(x, y, s, WhichFont(type, siz));
674 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
682 drawStr(pain, type, siz, x, y, s);
685 // decrease math size for super- and subscripts
686 MathStyles smallerStyleScript(MathStyles st)
690 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
691 default: st = LM_ST_SCRIPTSCRIPT;
696 // decrease math size for fractions
697 MathStyles smallerStyleFrac(MathStyles st)
700 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
701 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
702 default: st = LM_ST_SCRIPTSCRIPT;
708 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
710 LyXFont font = WhichFont(code, siz);
711 asc = lyxfont::maxAscent(font);
712 des = lyxfont::maxDescent(font);
715 char const * latex_mathspace[] = {
716 "!", ",", ":", ";", "quad", "qquad"