5 #include "mathed/support.h"
9 #include "math_parser.h"
12 #include "math_utils.h"
15 using std::lower_bound;
20 bool MathIsInset(MathTextCodes x)
22 return LM_TC_INSET == x;
26 bool MathIsAlphaFont(MathTextCodes x)
28 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
32 bool MathIsBOPS(MathTextCodes x)
34 return MathLookupBOP(x) != LMB_NONE;
38 bool MathIsBinary(MathTextCodes x)
40 return x == LM_TC_BOP || x == LM_TC_BOPS;
44 bool MathIsSymbol(MathTextCodes x)
46 return x == LM_TC_SYMB || x == LM_TC_BOPS || x == LM_TC_BSYM;
55 typedef float matriz_data[2][2];
61 void escalate(float, float);
63 void transform(float, float, float &, float &);
68 void multiply(matriz_data & a);
79 void Matrix::rotate(int code)
86 float const cs = (code & 1) ? 0 : (1 - code);
87 float const sn = (code & 1) ? (2 - code) : 0;
95 void Matrix::escalate(float x, float y)
105 void Matrix::multiply(matriz_data & a)
108 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
109 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
110 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
111 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
118 void Matrix::transform(float xp, float yp, float & x, float & y)
120 x = m_[0][0] * xp + m_[0][1] * yp;
121 y = m_[1][0] * xp + m_[1][1] * yp;
127 LyXFont * Math_Fonts = 0;
129 void mathed_init_fonts()
131 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
134 for (int i = 0 ; i < 8 ; ++i) {
135 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
138 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
140 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
142 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
143 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
145 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
147 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
148 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
150 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
152 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
154 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
160 LyXFont WhichFont(MathTextCodes type, MathStyles size)
197 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
211 if (type == LM_TC_BSYM) {
224 case LM_ST_SCRIPTSCRIPT:
230 lyxerr << "Math Error: wrong font size: " << size << endl;
234 if (type != LM_TC_TEXTRM)
235 f.setColor(LColor::math);
237 if (type == LM_TC_TEX)
238 f.setColor(LColor::latex);
243 char const * math_font_name[] = {
254 char const * latex_mathspace[] = {
255 "!", ",", ":", ";", "quad", "qquad"
262 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
263 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
267 float const parenthHigh[] = {
269 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
270 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
271 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
272 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
278 float const parenth[] = {
280 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
281 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
282 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
283 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
289 float const brace[] = {
291 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
292 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
293 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
294 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
295 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
296 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
297 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
302 // Is this correct? (Lgb)
303 float const arrow[] = {
305 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
306 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
308 3, 0.5000, 0.1500, 0.5000, 0.9500,
313 // Is this correct? (Lgb)
314 float const Arrow[] = {
316 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
317 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
319 3, 0.3500, 0.5000, 0.3500, 0.9500,
320 3, 0.6500, 0.5000, 0.6500, 0.9500,
325 float const udarrow[] = {
327 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
329 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
330 1, 0.5, 0.2, 0.5, 0.8,
335 float const Udarrow[] = {
337 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
339 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
340 1, 0.35, 0.2, 0.35, 0.8,
341 1, 0.65, 0.2, 0.65, 0.8,
346 float const brack[] = {
348 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
353 float const corner[] = {
355 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
360 float const angle[] = {
362 1, 0, 0.05, 0.5, 1, 1,
367 float const slash[] = {
368 1, 0.95, 0.05, 0.05, 0.95,
373 float const hline[] = {
374 1, 0.05, 0.5, 0.95, 0.5,
379 float const hline2[] = {
380 1, 0.1, 0.5, 0.3, 0.5,
381 1, 0.7, 0.5, 0.9, 0.5,
386 float const hline3[] = {
388 1, 0.475, 0, 0.525, 0,
394 float const dline3[] = {
395 1, 0.1, 0.1, 0.15, 0.15,
396 1, 0.475, 0.475, 0.525, 0.525,
397 1, 0.85, 0.85, 0.9, 0.9,
402 float const hlinesmall[] = {
403 1, 0.4, 0.5, 0.6, 0.5,
408 float const vert[] = {
409 1, 0.5, 0.05, 0.5, 0.95,
414 float const Vert[] = {
415 1, 0.3, 0.05, 0.3, 0.95,
416 1, 0.7, 0.05, 0.7, 0.95,
421 float const tilde[] = {
423 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
428 struct math_deco_struct {
434 math_deco_struct math_deco_table[] = {
436 { LM_widehat, &angle[0], 3 },
437 { LM_widetilde, &tilde[0], 0 },
438 { LM_underline, &hline[0], 0 },
439 { LM_overline, &hline[0], 0 },
440 { LM_underbrace, &brace[0], 1 },
441 { LM_overbrace, &brace[0], 3 },
442 { LM_overleftarrow, &arrow[0], 1 },
443 { LM_overightarrow, &arrow[0], 3 },
446 { '(', &parenth[0], 0 },
447 { ')', &parenth[0], 2 },
448 { '{', &brace[0], 0 },
449 { '}', &brace[0], 2 },
450 { '[', &brack[0], 0 },
451 { ']', &brack[0], 2 },
452 { '|', &vert[0], 0 },
453 { '/', &slash[0], 0 },
454 { LM_Vert, &Vert[0], 0 },
455 { LM_backslash, &slash[0], 1 },
456 { LM_langle, &angle[0], 0 },
457 { LM_lceil, &corner[0], 0 },
458 { LM_lfloor, &corner[0], 1 },
459 { LM_rangle, &angle[0], 2 },
460 { LM_rceil, &corner[0], 3 },
461 { LM_rfloor, &corner[0], 2 },
462 { LM_downarrow, &arrow[0], 2 },
463 { LM_Downarrow, &Arrow[0], 2 },
464 { LM_uparrow, &arrow[0], 0 },
465 { LM_Uparrow, &Arrow[0], 0 },
466 { LM_updownarrow, &udarrow[0], 0 },
467 { LM_Updownarrow, &Udarrow[0], 0 },
470 { LM_ddot, &hline2[0], 0 },
471 { LM_hat, &angle[0], 3 },
472 { LM_grave, &slash[0], 1 },
473 { LM_acute, &slash[0], 0 },
474 { LM_tilde, &tilde[0], 0 },
475 { LM_bar, &hline[0], 0 },
476 { LM_dot, &hlinesmall[0], 0 },
477 { LM_check, &angle[0], 1 },
478 { LM_breve, &parenth[0], 1 },
479 { LM_vec, &arrow[0], 3 },
480 { LM_not, &slash[0], 0 },
483 { LM_ldots, &hline3[0], 0 },
484 { LM_cdots, &hline3[0], 0 },
485 { LM_vdots, &hline3[0], 1 },
486 { LM_ddots, &dline3[0], 0 }
490 struct math_deco_compare {
491 /// for use by sort and lower_bound
493 int operator()(math_deco_struct const & a,
494 math_deco_struct const & b) const {
495 return a.code < b.code;
500 int const math_deco_table_size =
501 sizeof(math_deco_table) /sizeof(math_deco_struct);
504 class init_deco_table {
508 sort(math_deco_table,
509 math_deco_table + math_deco_table_size,
510 math_deco_compare());
511 init_deco_table::init = true;
519 bool init_deco_table::init = false;
520 static init_deco_table idt;
524 void mathed_char_dim (MathTextCodes type, MathStyles size, unsigned char c,
525 int & asc, int & des, int & wid)
527 LyXFont const font = WhichFont(type, size);
528 des = lyxfont::descent(c, font);
529 asc = lyxfont::ascent(c, font);
530 wid = mathed_char_width(type, size, c);
533 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
534 int & asc, int & des)
536 LyXFont const font = WhichFont(type, size);
537 des = lyxfont::descent(c, font);
538 asc = lyxfont::ascent(c, font);
543 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
545 if (MathIsBinary(type)) {
548 return mathed_string_width(type, size, s);
550 return lyxfont::width(c, WhichFont(type, size));
554 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
555 int & asc, int & des, int & wid)
557 mathed_string_height(type, size, s, asc, des);
558 wid = mathed_string_width(type, size, s);
561 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
562 int & asc, int & des)
564 LyXFont const font = WhichFont(type, size);
566 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
567 des = max(des, lyxfont::descent(*it, font));
568 asc = max(asc, lyxfont::ascent(*it, font));
574 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
577 if (MathIsBinary(type))
578 for (string::const_iterator it = s.begin();
579 it != s.end(); ++it) {
587 return lyxfont::width(st, WhichFont(type, size));
593 math_deco_struct const * search_deco(int code)
595 math_deco_struct search_elem = { code, 0, 0 };
597 math_deco_struct const * res =
598 lower_bound(math_deco_table,
599 math_deco_table + math_deco_table_size,
600 search_elem, math_deco_compare());
601 if (res != math_deco_table + math_deco_table_size &&
609 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
619 math_deco_struct const * mds = search_deco(code);
621 // Should this ever happen?
622 lyxerr << "Deco was not found. Programming error?" << endl;
626 int const r = mds->angle;
627 float const * d = mds->data;
629 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
635 int const n = (w < h) ? w : h;
638 if (r > 0 && r < 3) y += h;
647 xx = d[i++]; yy = d[i++];
648 x2 = d[i++]; y2 = d[i++];
650 sqmt.transform(xx, yy, xx, yy);
652 mt.transform(xx, yy, xx, yy);
653 mt.transform(x2, y2, x2, y2);
654 pain.line(x + int(xx), y + int(yy),
655 x + int(x2), y + int(y2),
664 int const n = int(d[i++]);
665 for (int j = 0; j < n; ++j) {
666 xx = d[i++]; yy = d[i++];
667 // lyxerr << " " << xx << " " << yy << " ";
669 sqmt.transform(xx, yy, xx, yy);
671 mt.transform(xx, yy, xx, yy);
674 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
676 pain.lines(xp, yp, n, LColor::mathline);
684 // In a near future maybe we use a better fonts renderer
685 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
686 int x, int y, string const & s)
689 if (MathIsBinary(type))
690 for (string::const_iterator it = s.begin();
691 it != s.end(); ++it) {
699 pain.text(x, y, st, WhichFont(type, siz));
702 void drawChar(Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
706 drawStr(pain, type, siz, x, y, s);
709 // decrease math size for super- and subscripts
710 MathStyles smallerStyleScript(MathStyles st)
714 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
715 default: st = LM_ST_SCRIPTSCRIPT;
720 // decrease math size for fractions
721 MathStyles smallerStyleFrac(MathStyles st)
724 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
725 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
726 default: st = LM_ST_SCRIPTSCRIPT;
731 bool MathIsRelOp(unsigned char c, MathTextCodes f)
733 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
735 #ifndef WITH_WARNINGS
736 #warning implement me properly
738 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))
744 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
746 LyXFont font = WhichFont(code, siz);
747 asc = lyxfont::maxAscent(font);
748 des = lyxfont::maxDescent(font);