5 #include "mathed/support.h"
9 #include "math_parser.h"
14 using std::lower_bound;
19 bool MathIsAlphaFont(MathTextCodes x)
21 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
25 bool MathIsBinary(MathTextCodes x)
27 return x == LM_TC_BOP;
31 bool MathIsSymbol(MathTextCodes x)
33 return x == LM_TC_SYMB || x == LM_TC_BSYM;
42 typedef float matriz_data[2][2];
48 void escalate(float, float);
50 void transform(float, float, float &, float &);
55 void multiply(matriz_data & a);
66 void Matrix::rotate(int code)
73 float const cs = (code & 1) ? 0 : (1 - code);
74 float const sn = (code & 1) ? (2 - code) : 0;
82 void Matrix::escalate(float x, float y)
92 void Matrix::multiply(matriz_data & a)
95 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
96 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
97 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
98 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
105 void Matrix::transform(float xp, float yp, float & x, float & y)
107 x = m_[0][0] * xp + m_[0][1] * yp;
108 y = m_[1][0] * xp + m_[1][1] * yp;
114 LyXFont * Math_Fonts = 0;
116 void mathed_init_fonts()
118 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
121 for (int i = 0 ; i < 8 ; ++i) {
122 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
125 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
127 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
129 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
130 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
132 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
134 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
135 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
137 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
139 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
141 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
147 LyXFont WhichFont(MathTextCodes type, MathStyles size)
181 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
195 if (type == LM_TC_BSYM) {
209 case LM_ST_SCRIPTSCRIPT:
216 lyxerr << "Math Error: wrong font size: " << size << endl;
220 if (type != LM_TC_TEXTRM)
221 f.setColor(LColor::math);
223 if (type == LM_TC_TEX)
224 f.setColor(LColor::latex);
229 char const * math_font_name[] = {
243 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
244 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
248 float const parenthHigh[] = {
250 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
251 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
252 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
253 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
259 float const parenth[] = {
261 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
262 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
263 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
264 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
270 float const brace[] = {
272 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
273 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
274 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
275 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
276 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
277 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
278 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
283 // Is this correct? (Lgb)
284 float const arrow[] = {
286 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
287 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
289 3, 0.5000, 0.1500, 0.5000, 0.9500,
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.3500, 0.5000, 0.3500, 0.9500,
301 3, 0.6500, 0.5000, 0.6500, 0.9500,
306 float const udarrow[] = {
308 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
310 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
311 1, 0.5, 0.2, 0.5, 0.8,
316 float const Udarrow[] = {
318 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
320 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
321 1, 0.35, 0.2, 0.35, 0.8,
322 1, 0.65, 0.2, 0.65, 0.8,
327 float const brack[] = {
329 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
334 float const corner[] = {
336 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
341 float const angle[] = {
343 1, 0, 0.05, 0.5, 1, 1,
348 float const slash[] = {
349 1, 0.95, 0.05, 0.05, 0.95,
354 float const hline[] = {
355 1, 0.05, 0.5, 0.95, 0.5,
360 float const hline2[] = {
361 1, 0.1, 0.5, 0.3, 0.5,
362 1, 0.7, 0.5, 0.9, 0.5,
367 float const hline3[] = {
369 1, 0.475, 0, 0.525, 0,
375 float const dline3[] = {
376 1, 0.1, 0.1, 0.15, 0.15,
377 1, 0.475, 0.475, 0.525, 0.525,
378 1, 0.85, 0.85, 0.9, 0.9,
383 float const hlinesmall[] = {
384 1, 0.4, 0.5, 0.6, 0.5,
389 float const vert[] = {
390 1, 0.5, 0.05, 0.5, 0.95,
395 float const Vert[] = {
396 1, 0.3, 0.05, 0.3, 0.95,
397 1, 0.7, 0.05, 0.7, 0.95,
402 float const tilde[] = {
404 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
409 struct math_deco_struct {
415 math_deco_struct math_deco_table[] = {
417 { LM_widehat, &angle[0], 3 },
418 { LM_widetilde, &tilde[0], 0 },
419 { LM_underline, &hline[0], 0 },
420 { LM_overline, &hline[0], 0 },
421 { LM_underbrace, &brace[0], 1 },
422 { LM_overbrace, &brace[0], 3 },
423 { LM_overleftarrow, &arrow[0], 1 },
424 { LM_overightarrow, &arrow[0], 3 },
427 { '(', &parenth[0], 0 },
428 { ')', &parenth[0], 2 },
429 { '{', &brace[0], 0 },
430 { '}', &brace[0], 2 },
431 { '[', &brack[0], 0 },
432 { ']', &brack[0], 2 },
433 { '|', &vert[0], 0 },
434 { '/', &slash[0], 0 },
435 { LM_Vert, &Vert[0], 0 },
436 { LM_backslash, &slash[0], 1 },
437 { LM_langle, &angle[0], 0 },
438 { LM_lceil, &corner[0], 0 },
439 { LM_lfloor, &corner[0], 1 },
440 { LM_rangle, &angle[0], 2 },
441 { LM_rceil, &corner[0], 3 },
442 { LM_rfloor, &corner[0], 2 },
443 { LM_downarrow, &arrow[0], 2 },
444 { LM_Downarrow, &Arrow[0], 2 },
445 { LM_uparrow, &arrow[0], 0 },
446 { LM_Uparrow, &Arrow[0], 0 },
447 { LM_updownarrow, &udarrow[0], 0 },
448 { LM_Updownarrow, &Udarrow[0], 0 },
451 { LM_ddot, &hline2[0], 0 },
452 { LM_hat, &angle[0], 3 },
453 { LM_grave, &slash[0], 1 },
454 { LM_acute, &slash[0], 0 },
455 { LM_tilde, &tilde[0], 0 },
456 { LM_bar, &hline[0], 0 },
457 { LM_dot, &hlinesmall[0], 0 },
458 { LM_check, &angle[0], 1 },
459 { LM_breve, &parenth[0], 1 },
460 { LM_vec, &arrow[0], 3 },
461 { LM_not, &slash[0], 0 },
464 { LM_ldots, &hline3[0], 0 },
465 { LM_cdots, &hline3[0], 0 },
466 { LM_vdots, &hline3[0], 1 },
467 { LM_ddots, &dline3[0], 0 }
471 struct math_deco_compare {
472 /// for use by sort and lower_bound
474 int operator()(math_deco_struct const & a,
475 math_deco_struct const & b) const {
476 return a.code < b.code;
481 int const math_deco_table_size =
482 sizeof(math_deco_table) /sizeof(math_deco_struct);
485 class init_deco_table {
489 sort(math_deco_table,
490 math_deco_table + math_deco_table_size,
491 math_deco_compare());
492 init_deco_table::init = true;
500 bool init_deco_table::init = false;
501 static init_deco_table idt;
505 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
506 int & asc, int & des, int & wid)
508 LyXFont const font = WhichFont(type, size);
509 des = lyxfont::descent(c, font);
510 asc = lyxfont::ascent(c, font);
511 wid = mathed_char_width(type, size, c);
514 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
515 int & asc, int & des)
517 LyXFont const font = WhichFont(type, size);
518 des = lyxfont::descent(c, font);
519 asc = lyxfont::ascent(c, font);
524 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
528 return mathed_char_height(type, size, c, asc, des);
531 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
533 LyXFont const font = WhichFont(type, size);
534 return lyxfont::ascent(c, font);
537 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
539 LyXFont const font = WhichFont(type, size);
540 return lyxfont::descent(c, font);
545 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
547 if (MathIsBinary(type)) {
550 return mathed_string_width(type, size, s);
552 return lyxfont::width(c, WhichFont(type, size));
556 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
557 int & asc, int & des, int & wid)
559 mathed_string_height(type, size, s, asc, des);
560 wid = mathed_string_width(type, size, s);
563 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
564 int & asc, int & des)
566 LyXFont const font = WhichFont(type, size);
568 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
569 des = max(des, lyxfont::descent(*it, font));
570 asc = max(asc, lyxfont::ascent(*it, font));
576 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
579 if (MathIsBinary(type))
580 for (string::const_iterator it = s.begin();
581 it != s.end(); ++it) {
589 return lyxfont::width(st, WhichFont(type, size));
595 math_deco_struct const * search_deco(int code)
597 math_deco_struct search_elem = { code, 0, 0 };
599 math_deco_struct const * res =
600 lower_bound(math_deco_table,
601 math_deco_table + math_deco_table_size,
602 search_elem, math_deco_compare());
603 if (res != math_deco_table + math_deco_table_size &&
611 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
621 math_deco_struct const * mds = search_deco(code);
623 // Should this ever happen?
624 lyxerr << "Deco was not found. Programming error?" << endl;
628 int const r = mds->angle;
629 float const * d = mds->data;
631 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
637 int const n = (w < h) ? w : h;
640 if (r > 0 && r < 3) y += h;
649 xx = d[i++]; yy = d[i++];
650 x2 = d[i++]; y2 = d[i++];
652 sqmt.transform(xx, yy, xx, yy);
654 mt.transform(xx, yy, xx, yy);
655 mt.transform(x2, y2, x2, y2);
656 pain.line(x + int(xx), y + int(yy),
657 x + int(x2), y + int(y2),
666 int const n = int(d[i++]);
667 for (int j = 0; j < n; ++j) {
668 xx = d[i++]; yy = d[i++];
669 // lyxerr << " " << xx << " " << yy << " ";
671 sqmt.transform(xx, yy, xx, yy);
673 mt.transform(xx, yy, xx, yy);
676 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
678 pain.lines(xp, yp, n, LColor::mathline);
686 // In a near future maybe we use a better fonts renderer
687 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
688 int x, int y, string const & s)
691 if (MathIsBinary(type))
692 for (string::const_iterator it = s.begin();
693 it != s.end(); ++it) {
701 pain.text(x, y, st, WhichFont(type, siz));
704 void drawChar(Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
708 drawStr(pain, type, siz, x, y, s);
711 // decrease math size for super- and subscripts
712 MathStyles smallerStyleScript(MathStyles st)
716 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
717 default: st = LM_ST_SCRIPTSCRIPT;
722 // decrease math size for fractions
723 MathStyles smallerStyleFrac(MathStyles st)
726 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
727 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
728 default: st = LM_ST_SCRIPTSCRIPT;
734 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
736 LyXFont font = WhichFont(code, siz);
737 asc = lyxfont::maxAscent(font);
738 des = lyxfont::maxDescent(font);
741 char const * latex_mathspace[] = {
742 "!", ",", ":", ";", "quad", "qquad"