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;
35 typedef float matriz_data[2][2];
41 void escalate(float, float);
43 void transform(float, float, float &, float &);
48 void multiply(matriz_data & a);
59 void Matrix::rotate(int code)
66 float const cs = (code & 1) ? 0 : (1 - code);
67 float const sn = (code & 1) ? (2 - code) : 0;
75 void Matrix::escalate(float x, float y)
85 void Matrix::multiply(matriz_data & a)
88 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
89 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
90 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
91 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
98 void Matrix::transform(float xp, float yp, float & x, float & y)
100 x = m_[0][0] * xp + m_[0][1] * yp;
101 y = m_[1][0] * xp + m_[1][1] * yp;
107 LyXFont * Math_Fonts = 0;
109 void mathed_init_fonts()
111 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
114 for (int i = 0 ; i < 8 ; ++i) {
115 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
118 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
120 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
122 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
123 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
125 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
127 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
128 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
130 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
132 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
134 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
140 LyXFont WhichFont(MathTextCodes type, MathStyles size)
174 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
188 if (type == LM_TC_BSYM) {
202 case LM_ST_SCRIPTSCRIPT:
209 lyxerr << "Math Error: wrong font size: " << size << endl;
213 if (type != LM_TC_TEXTRM)
214 f.setColor(LColor::math);
216 if (type == LM_TC_TEX)
217 f.setColor(LColor::latex);
222 char const * math_font_name[] = {
236 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
237 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
241 float const parenthHigh[] = {
243 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
244 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
245 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
246 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
252 float const parenth[] = {
254 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
255 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
256 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
257 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
263 float const brace[] = {
265 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
266 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
267 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
268 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
269 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
270 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
271 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
276 // Is this correct? (Lgb)
277 float const arrow[] = {
279 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
280 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
282 3, 0.5000, 0.1500, 0.5000, 0.9500,
287 // Is this correct? (Lgb)
288 float const Arrow[] = {
290 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
291 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
293 3, 0.3500, 0.5000, 0.3500, 0.9500,
294 3, 0.6500, 0.5000, 0.6500, 0.9500,
299 float const udarrow[] = {
301 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
303 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
304 1, 0.5, 0.2, 0.5, 0.8,
309 float const Udarrow[] = {
311 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
313 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
314 1, 0.35, 0.2, 0.35, 0.8,
315 1, 0.65, 0.2, 0.65, 0.8,
320 float const brack[] = {
322 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
327 float const corner[] = {
329 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
334 float const angle[] = {
336 1, 0, 0.05, 0.5, 1, 1,
341 float const slash[] = {
342 1, 0.95, 0.05, 0.05, 0.95,
347 float const hline[] = {
348 1, 0.05, 0.5, 0.95, 0.5,
353 float const hline2[] = {
354 1, 0.1, 0.5, 0.3, 0.5,
355 1, 0.7, 0.5, 0.9, 0.5,
360 float const hline3[] = {
362 1, 0.475, 0, 0.525, 0,
368 float const dline3[] = {
369 1, 0.1, 0.1, 0.15, 0.15,
370 1, 0.475, 0.475, 0.525, 0.525,
371 1, 0.85, 0.85, 0.9, 0.9,
376 float const hlinesmall[] = {
377 1, 0.4, 0.5, 0.6, 0.5,
382 float const vert[] = {
383 1, 0.5, 0.05, 0.5, 0.95,
388 float const Vert[] = {
389 1, 0.3, 0.05, 0.3, 0.95,
390 1, 0.7, 0.05, 0.7, 0.95,
395 float const tilde[] = {
397 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
402 struct math_deco_struct {
408 math_deco_struct math_deco_table[] = {
410 { LM_widehat, &angle[0], 3 },
411 { LM_widetilde, &tilde[0], 0 },
412 { LM_underline, &hline[0], 0 },
413 { LM_overline, &hline[0], 0 },
414 { LM_underbrace, &brace[0], 1 },
415 { LM_overbrace, &brace[0], 3 },
416 { LM_overleftarrow, &arrow[0], 1 },
417 { LM_overightarrow, &arrow[0], 3 },
420 { '(', &parenth[0], 0 },
421 { ')', &parenth[0], 2 },
422 { '{', &brace[0], 0 },
423 { '}', &brace[0], 2 },
424 { '[', &brack[0], 0 },
425 { ']', &brack[0], 2 },
426 { '|', &vert[0], 0 },
427 { '/', &slash[0], 0 },
428 { LM_Vert, &Vert[0], 0 },
429 { '\\', &slash[0], 1 },
430 { LM_langle, &angle[0], 0 },
431 { LM_lceil, &corner[0], 0 },
432 { LM_lfloor, &corner[0], 1 },
433 { LM_rangle, &angle[0], 2 },
434 { LM_rceil, &corner[0], 3 },
435 { LM_rfloor, &corner[0], 2 },
436 { LM_downarrow, &arrow[0], 2 },
437 { LM_Downarrow, &Arrow[0], 2 },
438 { LM_uparrow, &arrow[0], 0 },
439 { LM_Uparrow, &Arrow[0], 0 },
440 { LM_updownarrow, &udarrow[0], 0 },
441 { LM_Updownarrow, &Udarrow[0], 0 },
444 { LM_ddot, &hline2[0], 0 },
445 { LM_hat, &angle[0], 3 },
446 { LM_grave, &slash[0], 1 },
447 { LM_acute, &slash[0], 0 },
448 { LM_tilde, &tilde[0], 0 },
449 { LM_bar, &hline[0], 0 },
450 { LM_dot, &hlinesmall[0], 0 },
451 { LM_check, &angle[0], 1 },
452 { LM_breve, &parenth[0], 1 },
453 { LM_vec, &arrow[0], 3 },
454 { LM_not, &slash[0], 0 },
457 { LM_ldots, &hline3[0], 0 },
458 { LM_cdots, &hline3[0], 0 },
459 { LM_vdots, &hline3[0], 1 },
460 { LM_ddots, &dline3[0], 0 }
464 struct math_deco_compare {
465 /// for use by sort and lower_bound
467 int operator()(math_deco_struct const & a,
468 math_deco_struct const & b) const {
469 return a.code < b.code;
474 int const math_deco_table_size =
475 sizeof(math_deco_table) /sizeof(math_deco_struct);
478 class init_deco_table {
482 sort(math_deco_table,
483 math_deco_table + math_deco_table_size,
484 math_deco_compare());
485 init_deco_table::init = true;
493 bool init_deco_table::init = false;
494 static init_deco_table idt;
498 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
499 int & asc, int & des, int & wid)
501 LyXFont const font = WhichFont(type, size);
502 des = lyxfont::descent(c, font);
503 asc = lyxfont::ascent(c, font);
504 wid = mathed_char_width(type, size, c);
507 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
508 int & asc, int & des)
510 LyXFont const font = WhichFont(type, size);
511 des = lyxfont::descent(c, font);
512 asc = lyxfont::ascent(c, font);
517 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
521 return mathed_char_height(type, size, c, asc, des);
524 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
526 LyXFont const font = WhichFont(type, size);
527 return lyxfont::ascent(c, font);
530 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
532 LyXFont const font = WhichFont(type, size);
533 return lyxfont::descent(c, font);
538 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
540 if (MathIsBinary(type)) {
543 return mathed_string_width(type, size, s);
545 return lyxfont::width(c, WhichFont(type, size));
549 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
550 int & asc, int & des, int & wid)
552 mathed_string_height(type, size, s, asc, des);
553 wid = mathed_string_width(type, size, s);
556 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
557 int & asc, int & des)
559 LyXFont const font = WhichFont(type, size);
561 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
562 des = max(des, lyxfont::descent(*it, font));
563 asc = max(asc, lyxfont::ascent(*it, font));
569 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
572 if (MathIsBinary(type))
573 for (string::const_iterator it = s.begin();
574 it != s.end(); ++it) {
582 return lyxfont::width(st, WhichFont(type, size));
588 math_deco_struct const * search_deco(int code)
590 math_deco_struct search_elem = { code, 0, 0 };
592 math_deco_struct const * res =
593 lower_bound(math_deco_table,
594 math_deco_table + math_deco_table_size,
595 search_elem, math_deco_compare());
596 if (res != math_deco_table + math_deco_table_size &&
604 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
610 string name = l->name;
611 int code = (name.size() > 1) ? l->id : name[0];
613 math_deco_struct const * mds = search_deco(code);
615 lyxerr << "Deco was not found. Programming error?\n";
616 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
620 int const r = mds->angle;
621 float const * d = mds->data;
623 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
629 int const n = (w < h) ? w : h;
652 xx = d[i++]; yy = d[i++];
653 x2 = d[i++]; y2 = d[i++];
655 sqmt.transform(xx, yy, xx, yy);
657 mt.transform(xx, yy, xx, yy);
658 mt.transform(x2, y2, x2, y2);
659 pain.line(x + int(xx), y + int(yy),
660 x + int(x2), y + int(y2),
669 int const n = int(d[i++]);
670 for (int j = 0; j < n; ++j) {
671 xx = d[i++]; yy = d[i++];
672 // lyxerr << " " << xx << " " << yy << " ";
674 sqmt.transform(xx, yy, xx, yy);
676 mt.transform(xx, yy, xx, yy);
679 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
681 pain.lines(xp, yp, n, LColor::mathline);
689 // In a near future maybe we use a better fonts renderer
690 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
691 int x, int y, string const & s)
694 if (MathIsBinary(type))
695 for (string::const_iterator it = s.begin();
696 it != s.end(); ++it) {
704 pain.text(x, y, st, WhichFont(type, siz));
707 void drawChar(Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
711 drawStr(pain, type, siz, x, y, s);
714 // decrease math size for super- and subscripts
715 MathStyles smallerStyleScript(MathStyles st)
719 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
720 default: st = LM_ST_SCRIPTSCRIPT;
725 // decrease math size for fractions
726 MathStyles smallerStyleFrac(MathStyles st)
729 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
730 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
731 default: st = LM_ST_SCRIPTSCRIPT;
737 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
739 LyXFont font = WhichFont(code, siz);
740 asc = lyxfont::maxAscent(font);
741 des = lyxfont::maxDescent(font);
744 char const * latex_mathspace[] = {
745 "!", ",", ":", ";", "quad", "qquad"