5 #include "mathed/support.h"
9 #include "math_parser.h"
14 using std::lower_bound;
19 bool isBinaryOp(char c)
21 return strchr("+-<>=/*", c);
29 typedef float matriz_data[2][2];
35 void escalate(float, float);
37 void transform(float, float, float &, float &);
42 void multiply(matriz_data & a);
53 void Matrix::rotate(int code)
60 float const cs = (code & 1) ? 0 : (1 - code);
61 float const sn = (code & 1) ? (2 - code) : 0;
69 void Matrix::escalate(float x, float y)
79 void Matrix::multiply(matriz_data & a)
82 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
83 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
84 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
85 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
92 void Matrix::transform(float xp, float yp, float & x, float & y)
94 x = m_[0][0] * xp + m_[0][1] * yp;
95 y = m_[1][0] * xp + m_[1][1] * yp;
101 LyXFont * Math_Fonts = 0;
103 void mathed_init_fonts()
105 Math_Fonts = new LyXFont[8]; //DEC cxx cannot initialize all fonts
108 for (int i = 0 ; i < 8 ; ++i) {
109 Math_Fonts[i] = LyXFont(LyXFont::ALL_SANE);
112 Math_Fonts[0].setShape(LyXFont::ITALIC_SHAPE);
114 Math_Fonts[1].setFamily(LyXFont::SYMBOL_FAMILY);
116 Math_Fonts[2].setFamily(LyXFont::SYMBOL_FAMILY);
117 Math_Fonts[2].setShape(LyXFont::ITALIC_SHAPE);
119 Math_Fonts[3].setSeries(LyXFont::BOLD_SERIES);
121 Math_Fonts[4].setFamily(LyXFont::SANS_FAMILY);
122 Math_Fonts[4].setShape(LyXFont::ITALIC_SHAPE);
124 Math_Fonts[5].setFamily(LyXFont::TYPEWRITER_FAMILY);
126 Math_Fonts[6].setFamily(LyXFont::ROMAN_FAMILY);
128 Math_Fonts[7].setFamily(LyXFont::SANS_FAMILY);
134 LyXFont WhichFont(MathTextCodes type, MathStyles size)
168 case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
182 if (type == LM_TC_BSYM) {
196 case LM_ST_SCRIPTSCRIPT:
203 lyxerr << "Math Error: wrong font size: " << size << endl;
207 if (type != LM_TC_TEXTRM)
208 f.setColor(LColor::math);
210 if (type == LM_TC_TEX)
211 f.setColor(LColor::latex);
216 char const * math_font_name[] = {
230 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
231 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
235 float const parenthHigh[] = {
237 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
238 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
239 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
240 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
246 float const parenth[] = {
248 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
249 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
250 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
251 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
257 float const brace[] = {
259 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
260 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
261 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
262 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
263 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
264 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
265 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
270 // Is this correct? (Lgb)
271 float const arrow[] = {
273 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
274 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
276 3, 0.5000, 0.1500, 0.5000, 0.9500,
281 // Is this correct? (Lgb)
282 float const Arrow[] = {
284 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
285 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
287 3, 0.3500, 0.5000, 0.3500, 0.9500,
288 3, 0.6500, 0.5000, 0.6500, 0.9500,
293 float const udarrow[] = {
295 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
297 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
298 1, 0.5, 0.2, 0.5, 0.8,
303 float const Udarrow[] = {
305 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
307 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
308 1, 0.35, 0.2, 0.35, 0.8,
309 1, 0.65, 0.2, 0.65, 0.8,
314 float const brack[] = {
316 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
321 float const corner[] = {
323 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
328 float const angle[] = {
330 1, 0, 0.05, 0.5, 1, 1,
335 float const slash[] = {
336 1, 0.95, 0.05, 0.05, 0.95,
341 float const hline[] = {
342 1, 0.05, 0.5, 0.95, 0.5,
347 float const hline2[] = {
348 1, 0.1, 0.5, 0.3, 0.5,
349 1, 0.7, 0.5, 0.9, 0.5,
354 float const hline3[] = {
356 1, 0.475, 0, 0.525, 0,
362 float const dline3[] = {
363 1, 0.1, 0.1, 0.15, 0.15,
364 1, 0.475, 0.475, 0.525, 0.525,
365 1, 0.85, 0.85, 0.9, 0.9,
370 float const hlinesmall[] = {
371 1, 0.4, 0.5, 0.6, 0.5,
376 float const vert[] = {
377 1, 0.5, 0.05, 0.5, 0.95,
382 float const Vert[] = {
383 1, 0.3, 0.05, 0.3, 0.95,
384 1, 0.7, 0.05, 0.7, 0.95,
389 float const tilde[] = {
391 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
402 deco_struct deco_table[] = {
404 { LM_widehat, &angle[0], 3 },
405 { LM_widetilde, &tilde[0], 0 },
406 { LM_underline, &hline[0], 0 },
407 { LM_overline, &hline[0], 0 },
408 { LM_underbrace, &brace[0], 1 },
409 { LM_overbrace, &brace[0], 3 },
410 { LM_overleftarrow, &arrow[0], 1 },
411 { LM_overightarrow, &arrow[0], 3 },
414 { '(', &parenth[0], 0 },
415 { ')', &parenth[0], 2 },
416 { '{', &brace[0], 0 },
417 { '}', &brace[0], 2 },
418 { '[', &brack[0], 0 },
419 { ']', &brack[0], 2 },
420 { '|', &vert[0], 0 },
421 { '/', &slash[0], 0 },
422 { LM_Vert, &Vert[0], 0 },
423 { '\\', &slash[0], 1 },
424 { LM_langle, &angle[0], 0 },
425 { LM_lceil, &corner[0], 0 },
426 { LM_lfloor, &corner[0], 1 },
427 { LM_rangle, &angle[0], 2 },
428 { LM_rceil, &corner[0], 3 },
429 { LM_rfloor, &corner[0], 2 },
430 { LM_downarrow, &arrow[0], 2 },
431 { LM_Downarrow, &Arrow[0], 2 },
432 { LM_uparrow, &arrow[0], 0 },
433 { LM_Uparrow, &Arrow[0], 0 },
434 { LM_updownarrow, &udarrow[0], 0 },
435 { LM_Updownarrow, &Udarrow[0], 0 },
438 { LM_ddot, &hline2[0], 0 },
439 { LM_hat, &angle[0], 3 },
440 { LM_grave, &slash[0], 1 },
441 { LM_acute, &slash[0], 0 },
442 { LM_tilde, &tilde[0], 0 },
443 { LM_bar, &hline[0], 0 },
444 { LM_dot, &hlinesmall[0], 0 },
445 { LM_check, &angle[0], 1 },
446 { LM_breve, &parenth[0], 1 },
447 { LM_vec, &arrow[0], 3 },
448 { LM_not, &slash[0], 0 },
451 { LM_ldots, &hline3[0], 0 },
452 { LM_cdots, &hline3[0], 0 },
453 { LM_vdots, &hline3[0], 1 },
454 { LM_ddots, &dline3[0], 0 }
458 struct deco_compare {
459 /// for use by sort and lower_bound
460 int operator()(deco_struct const & a, deco_struct const & b) const
462 return a.code < b.code;
467 int const deco_table_size =
468 sizeof(deco_table) / sizeof(deco_struct);
471 // sort the table on startup
472 struct init_deco_table {
474 std::sort(deco_table,
475 deco_table + deco_table_size,
480 static init_deco_table dummy;
483 deco_struct const * search_deco(int code)
485 const deco_struct search_elem = { code, 0, 0 };
487 deco_struct const * res =
488 lower_bound(deco_table, deco_table + deco_table_size, search_elem,
490 if (res != deco_table + deco_table_size &&
500 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
501 int & asc, int & des, int & wid)
503 LyXFont const font = WhichFont(type, size);
504 des = lyxfont::descent(c, font);
505 asc = lyxfont::ascent(c, font);
506 wid = mathed_char_width(type, size, c);
510 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
511 int & asc, int & des)
513 LyXFont const font = WhichFont(type, size);
514 des = lyxfont::descent(c, font);
515 asc = lyxfont::ascent(c, font);
520 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
524 return mathed_char_height(type, size, c, asc, des);
527 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
529 LyXFont const font = WhichFont(type, size);
530 return lyxfont::ascent(c, font);
533 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
535 LyXFont const font = WhichFont(type, size);
536 return lyxfont::descent(c, font);
539 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
541 LyXFont const font = WhichFont(type, size);
543 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
545 return lyxfont::width(c, font);
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));
568 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
570 return lyxfont::width(s, WhichFont(type, size));
574 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
580 string name = l->name;
581 int code = (name.size() > 1) ? l->id : name[0];
584 pain.line(x + w/2, y, x + w/2, y + h,
585 LColor::mathcursor, Painter::line_onoffdash);
589 deco_struct const * mds = search_deco(code);
591 lyxerr << "Deco was not found. Programming error?\n";
592 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
596 int const r = mds->angle;
597 float const * d = mds->data;
599 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
605 int const n = (w < h) ? w : h;
628 xx = d[i++]; yy = d[i++];
629 x2 = d[i++]; y2 = d[i++];
631 sqmt.transform(xx, yy, xx, yy);
633 mt.transform(xx, yy, xx, yy);
634 mt.transform(x2, y2, x2, y2);
635 pain.line(x + int(xx), y + int(yy),
636 x + int(x2), y + int(y2),
645 int const n = int(d[i++]);
646 for (int j = 0; j < n; ++j) {
647 xx = d[i++]; yy = d[i++];
648 // lyxerr << " " << xx << " " << yy << " ";
650 sqmt.transform(xx, yy, xx, yy);
652 mt.transform(xx, yy, xx, yy);
655 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
657 pain.lines(xp, yp, n, LColor::mathline);
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)
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"