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];
578 pain.line(x + w/2, y, x + w/2, y + h,
579 LColor::mathcursor, Painter::line_onoffdash);
583 deco_struct const * mds = search_deco(code);
585 lyxerr << "Deco was not found. Programming error?\n";
586 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
590 int const r = mds->angle;
591 float const * d = mds->data;
593 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
599 int const n = (w < h) ? w : h;
622 xx = d[i++]; yy = d[i++];
623 x2 = d[i++]; y2 = d[i++];
625 sqmt.transform(xx, yy, xx, yy);
627 mt.transform(xx, yy, xx, yy);
628 mt.transform(x2, y2, x2, y2);
629 pain.line(x + int(xx), y + int(yy),
630 x + int(x2), y + int(y2),
639 int const n = int(d[i++]);
640 for (int j = 0; j < n; ++j) {
641 xx = d[i++]; yy = d[i++];
642 // lyxerr << " " << xx << " " << yy << " ";
644 sqmt.transform(xx, yy, xx, yy);
646 mt.transform(xx, yy, xx, yy);
649 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
651 pain.lines(xp, yp, n, LColor::mathline);
658 bool isBinaryOp(char c)
664 // In a near future maybe we use a better fonts renderer
665 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
666 int x, int y, string const & s)
668 pain.text(x, y, s, WhichFont(type, siz));
673 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
676 if (type == LM_TC_BOP)
679 if (type == LM_TC_BOP)
681 drawStr(pain, type, siz, x, y, s);
684 // decrease math size for super- and subscripts
685 MathStyles smallerStyleScript(MathStyles st)
689 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
690 default: st = LM_ST_SCRIPTSCRIPT;
695 // decrease math size for fractions
696 MathStyles smallerStyleFrac(MathStyles st)
699 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
700 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
701 default: st = LM_ST_SCRIPTSCRIPT;
707 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
709 LyXFont font = WhichFont(code, siz);
710 asc = lyxfont::maxAscent(font);
711 des = lyxfont::maxDescent(font);
714 char const * latex_mathspace[] = {
715 "!", ",", ":", ";", "quad", "qquad"