5 #include "mathed/support.h"
9 #include "math_parser.h"
14 using std::lower_bound;
23 typedef float matriz_data[2][2];
29 void escalate(float, float);
31 void transform(float, float, float &, float &);
36 void multiply(matriz_data & a);
47 void Matrix::rotate(int code)
54 float const cs = (code & 1) ? 0 : (1 - code);
55 float const sn = (code & 1) ? (2 - code) : 0;
63 void Matrix::escalate(float x, float y)
73 void Matrix::multiply(matriz_data & a)
76 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
77 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
78 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
79 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
86 void Matrix::transform(float xp, float yp, float & x, float & y)
88 x = m_[0][0] * xp + m_[0][1] * yp;
89 y = m_[1][0] * xp + m_[1][1] * yp;
95 LyXFont * Math_Fonts = 0;
97 void mathed_init_fonts()
99 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
102 for (int i = 0 ; i < 8 ; ++i) {
103 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
106 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
108 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
110 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
111 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
113 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
115 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
116 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
118 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
120 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
122 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
128 LyXFont WhichFont(MathTextCodes type, MathStyles size)
162 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
176 if (type == LM_TC_BSYM) {
190 case LM_ST_SCRIPTSCRIPT:
197 lyxerr << "Math Error: wrong font size: " << size << endl;
201 if (type != LM_TC_TEXTRM)
202 f.setColor(LColor::math);
204 if (type == LM_TC_TEX)
205 f.setColor(LColor::latex);
210 char const * math_font_name[] = {
224 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
225 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
229 float const parenthHigh[] = {
231 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
232 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
233 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
234 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
240 float const parenth[] = {
242 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
243 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
244 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
245 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
251 float const brace[] = {
253 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
254 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
255 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
256 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
257 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
258 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
259 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
264 // Is this correct? (Lgb)
265 float const arrow[] = {
267 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
268 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
270 3, 0.5000, 0.1500, 0.5000, 0.9500,
275 // Is this correct? (Lgb)
276 float const Arrow[] = {
278 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
279 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
281 3, 0.3500, 0.5000, 0.3500, 0.9500,
282 3, 0.6500, 0.5000, 0.6500, 0.9500,
287 float const udarrow[] = {
289 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
291 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
292 1, 0.5, 0.2, 0.5, 0.8,
297 float const Udarrow[] = {
299 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
301 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
302 1, 0.35, 0.2, 0.35, 0.8,
303 1, 0.65, 0.2, 0.65, 0.8,
308 float const brack[] = {
310 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
315 float const corner[] = {
317 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
322 float const angle[] = {
324 1, 0, 0.05, 0.5, 1, 1,
329 float const slash[] = {
330 1, 0.95, 0.05, 0.05, 0.95,
335 float const hline[] = {
336 1, 0.05, 0.5, 0.95, 0.5,
341 float const hline2[] = {
342 1, 0.1, 0.5, 0.3, 0.5,
343 1, 0.7, 0.5, 0.9, 0.5,
348 float const hline3[] = {
350 1, 0.475, 0, 0.525, 0,
356 float const dline3[] = {
357 1, 0.1, 0.1, 0.15, 0.15,
358 1, 0.475, 0.475, 0.525, 0.525,
359 1, 0.85, 0.85, 0.9, 0.9,
364 float const hlinesmall[] = {
365 1, 0.4, 0.5, 0.6, 0.5,
370 float const vert[] = {
371 1, 0.5, 0.05, 0.5, 0.95,
376 float const Vert[] = {
377 1, 0.3, 0.05, 0.3, 0.95,
378 1, 0.7, 0.05, 0.7, 0.95,
383 float const tilde[] = {
385 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
396 deco_struct deco_table[] = {
398 { LM_widehat, &angle[0], 3 },
399 { LM_widetilde, &tilde[0], 0 },
400 { LM_underline, &hline[0], 0 },
401 { LM_overline, &hline[0], 0 },
402 { LM_underbrace, &brace[0], 1 },
403 { LM_overbrace, &brace[0], 3 },
404 { LM_overleftarrow, &arrow[0], 1 },
405 { LM_overightarrow, &arrow[0], 3 },
408 { '(', &parenth[0], 0 },
409 { ')', &parenth[0], 2 },
410 { '{', &brace[0], 0 },
411 { '}', &brace[0], 2 },
412 { '[', &brack[0], 0 },
413 { ']', &brack[0], 2 },
414 { '|', &vert[0], 0 },
415 { '/', &slash[0], 0 },
416 { LM_Vert, &Vert[0], 0 },
417 { '\\', &slash[0], 1 },
418 { LM_langle, &angle[0], 0 },
419 { LM_lceil, &corner[0], 0 },
420 { LM_lfloor, &corner[0], 1 },
421 { LM_rangle, &angle[0], 2 },
422 { LM_rceil, &corner[0], 3 },
423 { LM_rfloor, &corner[0], 2 },
424 { LM_downarrow, &arrow[0], 2 },
425 { LM_Downarrow, &Arrow[0], 2 },
426 { LM_uparrow, &arrow[0], 0 },
427 { LM_Uparrow, &Arrow[0], 0 },
428 { LM_updownarrow, &udarrow[0], 0 },
429 { LM_Updownarrow, &Udarrow[0], 0 },
432 { LM_ddot, &hline2[0], 0 },
433 { LM_hat, &angle[0], 3 },
434 { LM_grave, &slash[0], 1 },
435 { LM_acute, &slash[0], 0 },
436 { LM_tilde, &tilde[0], 0 },
437 { LM_bar, &hline[0], 0 },
438 { LM_dot, &hlinesmall[0], 0 },
439 { LM_check, &angle[0], 1 },
440 { LM_breve, &parenth[0], 1 },
441 { LM_vec, &arrow[0], 3 },
442 { LM_not, &slash[0], 0 },
445 { LM_ldots, &hline3[0], 0 },
446 { LM_cdots, &hline3[0], 0 },
447 { LM_vdots, &hline3[0], 1 },
448 { LM_ddots, &dline3[0], 0 }
452 struct deco_compare {
453 /// for use by sort and lower_bound
454 int operator()(deco_struct const & a, deco_struct const & b) const
456 return a.code < b.code;
461 int const deco_table_size =
462 sizeof(deco_table) / sizeof(deco_struct);
465 // sort the table on startup
466 struct init_deco_table {
468 std::sort(deco_table,
469 deco_table + deco_table_size,
474 static init_deco_table dummy;
477 deco_struct const * search_deco(int code)
479 const deco_struct search_elem = { code, 0, 0 };
481 deco_struct const * res =
482 lower_bound(deco_table, deco_table + deco_table_size, search_elem,
484 if (res != deco_table + deco_table_size &&
494 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
495 int & asc, int & des, int & wid)
497 LyXFont const font = WhichFont(type, size);
498 des = lyxfont::descent(c, font);
499 asc = lyxfont::ascent(c, font);
500 wid = mathed_char_width(type, size, c);
504 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
505 int & asc, int & des)
507 LyXFont const font = WhichFont(type, size);
508 des = lyxfont::descent(c, font);
509 asc = lyxfont::ascent(c, font);
514 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
518 return mathed_char_height(type, size, c, asc, des);
521 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
523 LyXFont const font = WhichFont(type, size);
524 return lyxfont::ascent(c, font);
527 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
529 LyXFont const font = WhichFont(type, size);
530 return lyxfont::descent(c, font);
533 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
535 LyXFont const font = WhichFont(type, size);
536 if (type == LM_TC_BOP)
537 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
539 return lyxfont::width(c, font);
543 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
544 int & asc, int & des, int & wid)
546 mathed_string_height(type, size, s, asc, des);
547 wid = mathed_string_width(type, size, s);
550 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
551 int & asc, int & des)
553 LyXFont const font = WhichFont(type, size);
555 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
556 des = max(des, lyxfont::descent(*it, font));
557 asc = max(asc, lyxfont::ascent(*it, font));
562 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
564 return lyxfont::width(s, WhichFont(type, size));
568 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
574 string name = l->name;
575 int code = (name.size() > 1) ? l->id : name[0];
577 deco_struct const * mds = search_deco(code);
579 lyxerr << "Deco was not found. Programming error?\n";
580 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
584 int const r = mds->angle;
585 float const * d = mds->data;
587 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
593 int const n = (w < h) ? w : h;
616 xx = d[i++]; yy = d[i++];
617 x2 = d[i++]; y2 = d[i++];
619 sqmt.transform(xx, yy, xx, yy);
621 mt.transform(xx, yy, xx, yy);
622 mt.transform(x2, y2, x2, y2);
623 pain.line(x + int(xx), y + int(yy),
624 x + int(x2), y + int(y2),
633 int const n = int(d[i++]);
634 for (int j = 0; j < n; ++j) {
635 xx = d[i++]; yy = d[i++];
636 // lyxerr << " " << xx << " " << yy << " ";
638 sqmt.transform(xx, yy, xx, yy);
640 mt.transform(xx, yy, xx, yy);
643 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
645 pain.lines(xp, yp, n, LColor::mathline);
652 bool isBinaryOp(char c)
658 // In a near future maybe we use a better fonts renderer
659 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
660 int x, int y, string const & s)
662 pain.text(x, y, s, WhichFont(type, siz));
667 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
670 if (type == LM_TC_BOP)
673 if (type == LM_TC_BOP)
675 drawStr(pain, type, siz, x, y, s);
678 // decrease math size for super- and subscripts
679 MathStyles smallerStyleScript(MathStyles st)
683 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
684 default: st = LM_ST_SCRIPTSCRIPT;
689 // decrease math size for fractions
690 MathStyles smallerStyleFrac(MathStyles st)
693 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
694 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
695 default: st = LM_ST_SCRIPTSCRIPT;
701 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
703 LyXFont font = WhichFont(code, siz);
704 asc = lyxfont::maxAscent(font);
705 des = lyxfont::maxDescent(font);
708 char const * latex_mathspace[] = {
709 "!", ",", ":", ";", "quad", "qquad"