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) {
225 case LM_ST_SCRIPTSCRIPT:
232 lyxerr << "Math Error: wrong font size: " << size << endl;
236 if (type != LM_TC_TEXTRM)
237 f.setColor(LColor::math);
239 if (type == LM_TC_TEX)
240 f.setColor(LColor::latex);
245 char const * math_font_name[] = {
256 char const * latex_mathspace[] = {
257 "!", ",", ":", ";", "quad", "qquad"
264 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
265 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
269 float const parenthHigh[] = {
271 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
272 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
273 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
274 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
280 float const parenth[] = {
282 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
283 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
284 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
285 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
291 float const brace[] = {
293 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
294 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
295 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
296 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
297 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
298 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
299 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
304 // Is this correct? (Lgb)
305 float const arrow[] = {
307 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
308 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
310 3, 0.5000, 0.1500, 0.5000, 0.9500,
315 // Is this correct? (Lgb)
316 float const Arrow[] = {
318 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
319 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
321 3, 0.3500, 0.5000, 0.3500, 0.9500,
322 3, 0.6500, 0.5000, 0.6500, 0.9500,
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.5, 0.2, 0.5, 0.8,
337 float const Udarrow[] = {
339 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
341 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
342 1, 0.35, 0.2, 0.35, 0.8,
343 1, 0.65, 0.2, 0.65, 0.8,
348 float const brack[] = {
350 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
355 float const corner[] = {
357 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
362 float const angle[] = {
364 1, 0, 0.05, 0.5, 1, 1,
369 float const slash[] = {
370 1, 0.95, 0.05, 0.05, 0.95,
375 float const hline[] = {
376 1, 0.05, 0.5, 0.95, 0.5,
381 float const hline2[] = {
382 1, 0.1, 0.5, 0.3, 0.5,
383 1, 0.7, 0.5, 0.9, 0.5,
388 float const hline3[] = {
390 1, 0.475, 0, 0.525, 0,
396 float const dline3[] = {
397 1, 0.1, 0.1, 0.15, 0.15,
398 1, 0.475, 0.475, 0.525, 0.525,
399 1, 0.85, 0.85, 0.9, 0.9,
404 float const hlinesmall[] = {
405 1, 0.4, 0.5, 0.6, 0.5,
410 float const vert[] = {
411 1, 0.5, 0.05, 0.5, 0.95,
416 float const Vert[] = {
417 1, 0.3, 0.05, 0.3, 0.95,
418 1, 0.7, 0.05, 0.7, 0.95,
423 float const tilde[] = {
425 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
430 struct math_deco_struct {
436 math_deco_struct math_deco_table[] = {
438 { LM_widehat, &angle[0], 3 },
439 { LM_widetilde, &tilde[0], 0 },
440 { LM_underline, &hline[0], 0 },
441 { LM_overline, &hline[0], 0 },
442 { LM_underbrace, &brace[0], 1 },
443 { LM_overbrace, &brace[0], 3 },
444 { LM_overleftarrow, &arrow[0], 1 },
445 { LM_overightarrow, &arrow[0], 3 },
448 { '(', &parenth[0], 0 },
449 { ')', &parenth[0], 2 },
450 { '{', &brace[0], 0 },
451 { '}', &brace[0], 2 },
452 { '[', &brack[0], 0 },
453 { ']', &brack[0], 2 },
454 { '|', &vert[0], 0 },
455 { '/', &slash[0], 0 },
456 { LM_Vert, &Vert[0], 0 },
457 { LM_backslash, &slash[0], 1 },
458 { LM_langle, &angle[0], 0 },
459 { LM_lceil, &corner[0], 0 },
460 { LM_lfloor, &corner[0], 1 },
461 { LM_rangle, &angle[0], 2 },
462 { LM_rceil, &corner[0], 3 },
463 { LM_rfloor, &corner[0], 2 },
464 { LM_downarrow, &arrow[0], 2 },
465 { LM_Downarrow, &Arrow[0], 2 },
466 { LM_uparrow, &arrow[0], 0 },
467 { LM_Uparrow, &Arrow[0], 0 },
468 { LM_updownarrow, &udarrow[0], 0 },
469 { LM_Updownarrow, &Udarrow[0], 0 },
472 { LM_ddot, &hline2[0], 0 },
473 { LM_hat, &angle[0], 3 },
474 { LM_grave, &slash[0], 1 },
475 { LM_acute, &slash[0], 0 },
476 { LM_tilde, &tilde[0], 0 },
477 { LM_bar, &hline[0], 0 },
478 { LM_dot, &hlinesmall[0], 0 },
479 { LM_check, &angle[0], 1 },
480 { LM_breve, &parenth[0], 1 },
481 { LM_vec, &arrow[0], 3 },
482 { LM_not, &slash[0], 0 },
485 { LM_ldots, &hline3[0], 0 },
486 { LM_cdots, &hline3[0], 0 },
487 { LM_vdots, &hline3[0], 1 },
488 { LM_ddots, &dline3[0], 0 }
492 struct math_deco_compare {
493 /// for use by sort and lower_bound
495 int operator()(math_deco_struct const & a,
496 math_deco_struct const & b) const {
497 return a.code < b.code;
502 int const math_deco_table_size =
503 sizeof(math_deco_table) /sizeof(math_deco_struct);
506 class init_deco_table {
510 sort(math_deco_table,
511 math_deco_table + math_deco_table_size,
512 math_deco_compare());
513 init_deco_table::init = true;
521 bool init_deco_table::init = false;
522 static init_deco_table idt;
526 void mathed_char_dim (MathTextCodes type, MathStyles size, unsigned char c,
527 int & asc, int & des, int & wid)
529 LyXFont const font = WhichFont(type, size);
530 des = lyxfont::descent(c, font);
531 asc = lyxfont::ascent(c, font);
532 wid = mathed_char_width(type, size, c);
535 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
536 int & asc, int & des)
538 LyXFont const font = WhichFont(type, size);
539 des = lyxfont::descent(c, font);
540 asc = lyxfont::ascent(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;
733 bool MathIsRelOp(unsigned char c, MathTextCodes f)
735 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
737 #ifndef WITH_WARNINGS
738 #warning implement me properly
740 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))
746 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
748 LyXFont font = WhichFont(code, siz);
749 asc = lyxfont::maxAscent(font);
750 des = lyxfont::maxDescent(font);