5 #include "mathed/support.h"
9 #include "math_parser.h"
14 using std::lower_bound;
19 bool MathIsInset(MathTextCodes x)
21 return LM_TC_INSET == x;
25 bool MathIsAlphaFont(MathTextCodes x)
27 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
31 bool MathIsBinary(MathTextCodes x)
33 return x == LM_TC_BOP;
37 bool MathIsSymbol(MathTextCodes x)
39 return x == LM_TC_SYMB || x == LM_TC_BSYM;
48 typedef float matriz_data[2][2];
54 void escalate(float, float);
56 void transform(float, float, float &, float &);
61 void multiply(matriz_data & a);
72 void Matrix::rotate(int code)
79 float const cs = (code & 1) ? 0 : (1 - code);
80 float const sn = (code & 1) ? (2 - code) : 0;
88 void Matrix::escalate(float x, float y)
98 void Matrix::multiply(matriz_data & a)
101 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
102 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
103 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
104 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
111 void Matrix::transform(float xp, float yp, float & x, float & y)
113 x = m_[0][0] * xp + m_[0][1] * yp;
114 y = m_[1][0] * xp + m_[1][1] * yp;
120 LyXFont * Math_Fonts = 0;
122 void mathed_init_fonts()
124 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
127 for (int i = 0 ; i < 8 ; ++i) {
128 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
131 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
133 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
135 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
136 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
138 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
140 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
141 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
143 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
145 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
147 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
153 LyXFont WhichFont(MathTextCodes type, MathStyles size)
187 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
201 if (type == LM_TC_BSYM) {
215 case LM_ST_SCRIPTSCRIPT:
222 lyxerr << "Math Error: wrong font size: " << size << endl;
226 if (type != LM_TC_TEXTRM)
227 f.setColor(LColor::math);
229 if (type == LM_TC_TEX)
230 f.setColor(LColor::latex);
235 char const * math_font_name[] = {
246 char const * latex_mathspace[] = {
247 "!", ",", ":", ";", "quad", "qquad"
254 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
255 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
259 float const parenthHigh[] = {
261 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
262 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
263 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
264 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
270 float const parenth[] = {
272 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
273 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
274 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
275 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
281 float const brace[] = {
283 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
284 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
285 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
286 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
287 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
288 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
289 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
294 // Is this correct? (Lgb)
295 float const arrow[] = {
297 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
298 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
300 3, 0.5000, 0.1500, 0.5000, 0.9500,
305 // Is this correct? (Lgb)
306 float const Arrow[] = {
308 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
309 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
311 3, 0.3500, 0.5000, 0.3500, 0.9500,
312 3, 0.6500, 0.5000, 0.6500, 0.9500,
317 float const udarrow[] = {
319 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
321 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
322 1, 0.5, 0.2, 0.5, 0.8,
327 float const Udarrow[] = {
329 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
331 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
332 1, 0.35, 0.2, 0.35, 0.8,
333 1, 0.65, 0.2, 0.65, 0.8,
338 float const brack[] = {
340 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
345 float const corner[] = {
347 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
352 float const angle[] = {
354 1, 0, 0.05, 0.5, 1, 1,
359 float const slash[] = {
360 1, 0.95, 0.05, 0.05, 0.95,
365 float const hline[] = {
366 1, 0.05, 0.5, 0.95, 0.5,
371 float const hline2[] = {
372 1, 0.1, 0.5, 0.3, 0.5,
373 1, 0.7, 0.5, 0.9, 0.5,
378 float const hline3[] = {
380 1, 0.475, 0, 0.525, 0,
386 float const dline3[] = {
387 1, 0.1, 0.1, 0.15, 0.15,
388 1, 0.475, 0.475, 0.525, 0.525,
389 1, 0.85, 0.85, 0.9, 0.9,
394 float const hlinesmall[] = {
395 1, 0.4, 0.5, 0.6, 0.5,
400 float const vert[] = {
401 1, 0.5, 0.05, 0.5, 0.95,
406 float const Vert[] = {
407 1, 0.3, 0.05, 0.3, 0.95,
408 1, 0.7, 0.05, 0.7, 0.95,
413 float const tilde[] = {
415 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
420 struct math_deco_struct {
426 math_deco_struct math_deco_table[] = {
428 { LM_widehat, &angle[0], 3 },
429 { LM_widetilde, &tilde[0], 0 },
430 { LM_underline, &hline[0], 0 },
431 { LM_overline, &hline[0], 0 },
432 { LM_underbrace, &brace[0], 1 },
433 { LM_overbrace, &brace[0], 3 },
434 { LM_overleftarrow, &arrow[0], 1 },
435 { LM_overightarrow, &arrow[0], 3 },
438 { '(', &parenth[0], 0 },
439 { ')', &parenth[0], 2 },
440 { '{', &brace[0], 0 },
441 { '}', &brace[0], 2 },
442 { '[', &brack[0], 0 },
443 { ']', &brack[0], 2 },
444 { '|', &vert[0], 0 },
445 { '/', &slash[0], 0 },
446 { LM_Vert, &Vert[0], 0 },
447 { LM_backslash, &slash[0], 1 },
448 { LM_langle, &angle[0], 0 },
449 { LM_lceil, &corner[0], 0 },
450 { LM_lfloor, &corner[0], 1 },
451 { LM_rangle, &angle[0], 2 },
452 { LM_rceil, &corner[0], 3 },
453 { LM_rfloor, &corner[0], 2 },
454 { LM_downarrow, &arrow[0], 2 },
455 { LM_Downarrow, &Arrow[0], 2 },
456 { LM_uparrow, &arrow[0], 0 },
457 { LM_Uparrow, &Arrow[0], 0 },
458 { LM_updownarrow, &udarrow[0], 0 },
459 { LM_Updownarrow, &Udarrow[0], 0 },
462 { LM_ddot, &hline2[0], 0 },
463 { LM_hat, &angle[0], 3 },
464 { LM_grave, &slash[0], 1 },
465 { LM_acute, &slash[0], 0 },
466 { LM_tilde, &tilde[0], 0 },
467 { LM_bar, &hline[0], 0 },
468 { LM_dot, &hlinesmall[0], 0 },
469 { LM_check, &angle[0], 1 },
470 { LM_breve, &parenth[0], 1 },
471 { LM_vec, &arrow[0], 3 },
472 { LM_not, &slash[0], 0 },
475 { LM_ldots, &hline3[0], 0 },
476 { LM_cdots, &hline3[0], 0 },
477 { LM_vdots, &hline3[0], 1 },
478 { LM_ddots, &dline3[0], 0 }
482 struct math_deco_compare {
483 /// for use by sort and lower_bound
485 int operator()(math_deco_struct const & a,
486 math_deco_struct const & b) const {
487 return a.code < b.code;
492 int const math_deco_table_size =
493 sizeof(math_deco_table) /sizeof(math_deco_struct);
496 class init_deco_table {
500 sort(math_deco_table,
501 math_deco_table + math_deco_table_size,
502 math_deco_compare());
503 init_deco_table::init = true;
511 bool init_deco_table::init = false;
512 static init_deco_table idt;
516 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
517 int & asc, int & des, int & wid)
519 LyXFont const font = WhichFont(type, size);
520 des = lyxfont::descent(c, font);
521 asc = lyxfont::ascent(c, font);
522 wid = mathed_char_width(type, size, c);
525 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
526 int & asc, int & des)
528 LyXFont const font = WhichFont(type, size);
529 des = lyxfont::descent(c, font);
530 asc = lyxfont::ascent(c, font);
535 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
539 return mathed_char_height(type, size, c, asc, des);
542 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
544 LyXFont const font = WhichFont(type, size);
545 return lyxfont::ascent(c, font);
548 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
550 LyXFont const font = WhichFont(type, size);
551 return lyxfont::descent(c, font);
556 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
558 if (MathIsBinary(type)) {
561 return mathed_string_width(type, size, s);
563 return lyxfont::width(c, WhichFont(type, size));
567 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
568 int & asc, int & des, int & wid)
570 mathed_string_height(type, size, s, asc, des);
571 wid = mathed_string_width(type, size, s);
574 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
575 int & asc, int & des)
577 LyXFont const font = WhichFont(type, size);
579 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
580 des = max(des, lyxfont::descent(*it, font));
581 asc = max(asc, lyxfont::ascent(*it, font));
587 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
590 if (MathIsBinary(type))
591 for (string::const_iterator it = s.begin();
592 it != s.end(); ++it) {
600 return lyxfont::width(st, WhichFont(type, size));
606 math_deco_struct const * search_deco(int code)
608 math_deco_struct search_elem = { code, 0, 0 };
610 math_deco_struct const * res =
611 lower_bound(math_deco_table,
612 math_deco_table + math_deco_table_size,
613 search_elem, math_deco_compare());
614 if (res != math_deco_table + math_deco_table_size &&
622 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
632 math_deco_struct const * mds = search_deco(code);
634 // Should this ever happen?
635 lyxerr << "Deco was not found. Programming error?" << endl;
639 int const r = mds->angle;
640 float const * d = mds->data;
642 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
648 int const n = (w < h) ? w : h;
651 if (r > 0 && r < 3) y += h;
660 xx = d[i++]; yy = d[i++];
661 x2 = d[i++]; y2 = d[i++];
663 sqmt.transform(xx, yy, xx, yy);
665 mt.transform(xx, yy, xx, yy);
666 mt.transform(x2, y2, x2, y2);
667 pain.line(x + int(xx), y + int(yy),
668 x + int(x2), y + int(y2),
677 int const n = int(d[i++]);
678 for (int j = 0; j < n; ++j) {
679 xx = d[i++]; yy = d[i++];
680 // lyxerr << " " << xx << " " << yy << " ";
682 sqmt.transform(xx, yy, xx, yy);
684 mt.transform(xx, yy, xx, yy);
687 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
689 pain.lines(xp, yp, n, LColor::mathline);
697 // In a near future maybe we use a better fonts renderer
698 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
699 int x, int y, string const & s)
702 if (MathIsBinary(type))
703 for (string::const_iterator it = s.begin();
704 it != s.end(); ++it) {
712 pain.text(x, y, st, WhichFont(type, siz));
715 void drawChar(Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
719 drawStr(pain, type, siz, x, y, s);
722 // decrease math size for super- and subscripts
723 MathStyles smallerStyleScript(MathStyles st)
727 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
728 default: st = LM_ST_SCRIPTSCRIPT;
733 // decrease math size for fractions
734 MathStyles smallerStyleFrac(MathStyles st)
737 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
738 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
739 default: st = LM_ST_SCRIPTSCRIPT;
744 bool MathIsRelOp(unsigned char c, MathTextCodes f)
746 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
748 #ifndef WITH_WARNINGS
749 #warning implement me properly
751 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))
757 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
759 LyXFont font = WhichFont(code, siz);
760 asc = lyxfont::maxAscent(font);
761 des = lyxfont::maxDescent(font);