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;
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,
396 struct math_deco_struct {
402 math_deco_struct math_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 math_deco_compare {
459 /// for use by sort and lower_bound
461 int operator()(math_deco_struct const & a,
462 math_deco_struct const & b) const {
463 return a.code < b.code;
468 int const math_deco_table_size =
469 sizeof(math_deco_table) /sizeof(math_deco_struct);
472 class init_deco_table {
476 sort(math_deco_table,
477 math_deco_table + math_deco_table_size,
478 math_deco_compare());
479 init_deco_table::init = true;
487 bool init_deco_table::init = false;
488 static init_deco_table idt;
493 void mathed_char_dim(MathTextCodes type, MathStyles size, unsigned char c,
494 int & asc, int & des, int & wid)
496 LyXFont const font = WhichFont(type, size);
497 des = lyxfont::descent(c, font);
498 asc = lyxfont::ascent(c, font);
499 wid = mathed_char_width(type, size, c);
503 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c,
504 int & asc, int & des)
506 LyXFont const font = WhichFont(type, size);
507 des = lyxfont::descent(c, font);
508 asc = lyxfont::ascent(c, font);
513 int mathed_char_height(MathTextCodes type, MathStyles size, unsigned char c)
517 return mathed_char_height(type, size, c, asc, des);
520 int mathed_char_ascent(MathTextCodes type, MathStyles size, unsigned char c)
522 LyXFont const font = WhichFont(type, size);
523 return lyxfont::ascent(c, font);
526 int mathed_char_descent(MathTextCodes type, MathStyles size, unsigned char c)
528 LyXFont const font = WhichFont(type, size);
529 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));
564 int mathed_string_width(MathTextCodes type, MathStyles size, string const & s)
566 return lyxfont::width(s, WhichFont(type, size));
572 math_deco_struct const * search_deco(int code)
574 math_deco_struct search_elem = { code, 0, 0 };
576 math_deco_struct const * res =
577 lower_bound(math_deco_table,
578 math_deco_table + math_deco_table_size,
579 search_elem, math_deco_compare());
580 if (res != math_deco_table + math_deco_table_size &&
588 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
594 string name = l->name;
595 int code = (name.size() > 1) ? l->id : name[0];
597 math_deco_struct const * mds = search_deco(code);
599 lyxerr << "Deco was not found. Programming error?\n";
600 lyxerr << "name: '" << l->name << "', code: " << code << "\n";
604 int const r = mds->angle;
605 float const * d = mds->data;
607 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
613 int const n = (w < h) ? w : h;
636 xx = d[i++]; yy = d[i++];
637 x2 = d[i++]; y2 = d[i++];
639 sqmt.transform(xx, yy, xx, yy);
641 mt.transform(xx, yy, xx, yy);
642 mt.transform(x2, y2, x2, y2);
643 pain.line(x + int(xx), y + int(yy),
644 x + int(x2), y + int(y2),
653 int const n = int(d[i++]);
654 for (int j = 0; j < n; ++j) {
655 xx = d[i++]; yy = d[i++];
656 // lyxerr << " " << xx << " " << yy << " ";
658 sqmt.transform(xx, yy, xx, yy);
660 mt.transform(xx, yy, xx, yy);
663 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
665 pain.lines(xp, yp, n, LColor::mathline);
673 // In a near future maybe we use a better fonts renderer
674 void drawStr(Painter & pain, MathTextCodes type, MathStyles siz,
675 int x, int y, string const & s)
677 pain.text(x, y, s, WhichFont(type, siz));
682 (Painter & pain, MathTextCodes type, MathStyles siz, int x, int y, char c)
685 if (type == LM_TC_BOP)
688 if (type == LM_TC_BOP)
690 drawStr(pain, type, siz, x, y, s);
693 // decrease math size for super- and subscripts
694 MathStyles smallerStyleScript(MathStyles st)
698 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
699 default: st = LM_ST_SCRIPTSCRIPT;
704 // decrease math size for fractions
705 MathStyles smallerStyleFrac(MathStyles st)
708 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
709 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
710 default: st = LM_ST_SCRIPTSCRIPT;
716 void math_font_max_dim(MathTextCodes code, MathStyles siz, int & asc, int & des)
718 LyXFont font = WhichFont(code, siz);
719 asc = lyxfont::maxAscent(font);
720 des = lyxfont::maxDescent(font);
723 char const * latex_mathspace[] = {
724 "!", ",", ":", ";", "quad", "qquad"