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,
390 struct math_deco_struct {
396 math_deco_struct math_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 math_deco_compare {
453 /// for use by sort and lower_bound
454 int operator()(math_deco_struct const & a, math_deco_struct const & b) const
456 return a.code < b.code;
461 int const math_deco_table_size =
462 sizeof(math_deco_table) / sizeof(math_deco_struct);
465 // sort the table on startup
466 struct init_deco_table {
468 std::sort(math_deco_table,
469 math_deco_table + math_deco_table_size,
470 math_deco_compare());
474 static init_deco_table dummy;
477 math_deco_struct const * search_deco(int code)
479 static const math_deco_struct search_elem = { code, 0, 0 };
481 math_deco_struct const * res =
482 lower_bound(math_deco_table,
483 math_deco_table + math_deco_table_size,
484 search_elem, math_deco_compare());
485 if (res != math_deco_table + math_deco_table_size &&
495 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
496 int & asc, int & des, int & wid)
498 LyXFont const font = WhichFont(type, size);
499 des = lyxfont::descent(c, font);
500 asc = lyxfont::ascent(c, font);
501 wid = mathed_char_width(type, size, c);
505 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
506 int & asc, int & des)
508 LyXFont const font = WhichFont(type, size);
509 des = lyxfont::descent(c, font);
510 asc = lyxfont::ascent(c, font);
515 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
519 return mathed_char_height(type, size, c, asc, des);
522 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
524 LyXFont const font = WhichFont(type, size);
525 return lyxfont::ascent(c, font);
528 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
530 LyXFont const font = WhichFont(type, size);
531 return lyxfont::descent(c, font);
534 int mathed_char_width(MathTextCodes type, MathStyles size, unsigned char c)
536 LyXFont const font = WhichFont(type, size);
537 if (type == LM_TC_BOP)
538 return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
540 return lyxfont::width(c, font);
544 void mathed_string_dim(MathTextCodes type, MathStyles size, string const & s,
545 int & asc, int & des, int & wid)
547 mathed_string_height(type, size, s, asc, des);
548 wid = mathed_string_width(type, size, s);
551 int mathed_string_height(MathTextCodes type, MathStyles size, string const & s,
552 int & asc, int & des)
554 LyXFont const font = WhichFont(type, size);
556 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
557 des = max(des, lyxfont::descent(*it, font));
558 asc = max(asc, lyxfont::ascent(*it, font));
563 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
565 return lyxfont::width(s, WhichFont(type, size));
569 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
575 string name = l->name;
576 int code = (name.size() > 1) ? l->id : name[0];
578 math_deco_struct const * mds = search_deco(code);
580 lyxerr << "Deco was not found. Programming error?\n";
581 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
585 int const r = mds->angle;
586 float const * d = mds->data;
588 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
594 int const n = (w < h) ? w : h;
617 xx = d[i++]; yy = d[i++];
618 x2 = d[i++]; y2 = d[i++];
620 sqmt.transform(xx, yy, xx, yy);
622 mt.transform(xx, yy, xx, yy);
623 mt.transform(x2, y2, x2, y2);
624 pain.line(x + int(xx), y + int(yy),
625 x + int(x2), y + int(y2),
634 int const n = int(d[i++]);
635 for (int j = 0; j < n; ++j) {
636 xx = d[i++]; yy = d[i++];
637 // lyxerr << " " << xx << " " << yy << " ";
639 sqmt.transform(xx, yy, xx, yy);
641 mt.transform(xx, yy, xx, yy);
644 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
646 pain.lines(xp, yp, n, LColor::mathline);
653 bool isBinaryOp(char c)
659 // In a near future maybe we use a better fonts renderer
660 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
661 int x, int y, string const & s)
663 pain.text(x, y, s, WhichFont(type, siz));
668 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
671 if (type == LM_TC_BOP)
674 if (type == LM_TC_BOP)
676 drawStr(pain, type, siz, x, y, s);
679 // decrease math size for super- and subscripts
680 MathStyles smallerStyleScript(MathStyles st)
684 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
685 default: st = LM_ST_SCRIPTSCRIPT;
690 // decrease math size for fractions
691 MathStyles smallerStyleFrac(MathStyles st)
694 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
695 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
696 default: st = LM_ST_SCRIPTSCRIPT;
702 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
704 LyXFont font = WhichFont(code, siz);
705 asc = lyxfont::maxAscent(font);
706 des = lyxfont::maxDescent(font);
709 char const * latex_mathspace[] = {
710 "!", ",", ":", ";", "quad", "qquad"