5 #include "mathed/support.h"
9 #include "math_parser.h"
11 #include "symbol_def.h"
13 #include "math_utils.h"
16 using std::lower_bound;
28 typedef float matriz_data[2][2];
34 void escala(float, float);
36 void transf(float, float, float &, float &);
41 void matmat(matriz_data & a);
43 static matriz_data const MATIDEN;
47 #define mateq(m1, m2) memcpy(m1, m2, sizeof(matriz_data))
50 Matrix::matriz_data const Matrix::MATIDEN = { {1, 0}, {0, 1}};
59 void Matrix::rota(int code)
63 float const cs = (code & 1) ? 0 : (1 - code);
64 float const sn = (code & 1) ? (2 - code) : 0;
73 void Matrix::escala(float x, float y)
83 void Matrix::matmat(matriz_data & a)
86 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
87 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
88 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
89 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
94 void Matrix::transf(float xp, float yp, float & x, float & y)
96 x = m_[0][0] * xp + m_[0][1] * yp;
97 y = m_[1][0] * xp + m_[1][1] * yp;
108 extern LyXFont WhichFont(short type, int size);
110 char const * math_font_name[] = {
121 char const * latex_mathspace[] = {
122 "!", ",", ":", ";", "quad", "qquad"
129 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
130 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
134 float const parenthHigh[] = {
136 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
137 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
138 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
139 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
145 float const parenth[] = {
147 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
148 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
149 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
150 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
156 float const brace[] = {
158 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
159 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
160 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
161 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
162 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
163 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
164 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
169 // Is this correct? (Lgb)
170 float const arrow[] = {
172 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
173 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
175 3, 0.5000, 0.1500, 0.5000, 0.9500,
180 // Is this correct? (Lgb)
181 float const Arrow[] = {
183 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
184 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
186 3, 0.3500, 0.5000, 0.3500, 0.9500,
187 3, 0.6500, 0.5000, 0.6500, 0.9500,
192 float const udarrow[] = {
194 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
196 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
197 1, 0.5, 0.2, 0.5, 0.8,
202 float const Udarrow[] = {
204 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
206 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
207 1, 0.35, 0.2, 0.35, 0.8,
208 1, 0.65, 0.2, 0.65, 0.8,
213 float const brack[] = {
215 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
220 float const corner[] = {
222 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
227 float const angle[] = {
229 1, 0, 0.05, 0.5, 1, 1,
234 float const slash[] = {
235 1, 0.95, 0.05, 0.05, 0.95,
240 float const hline[] = {
241 1, 0.05, 0.5, 0.95, 0.5,
246 float const hline2[] = {
247 1, 0.1, 0.5, 0.3, 0.5,
248 1, 0.7, 0.5, 0.9, 0.5,
253 float const hline3[] = {
255 1, 0.475, 0, 0.525, 0,
261 float const dline3[] = {
262 1, 0.1, 0.1, 0.15, 0.15,
263 1, 0.475, 0.475, 0.525, 0.525,
264 1, 0.85, 0.85, 0.9, 0.9,
269 float const hlinesmall[] = {
270 1, 0.4, 0.5, 0.6, 0.5,
275 float const vert[] = {
276 1, 0.5, 0.05, 0.5, 0.95,
281 float const Vert[] = {
282 1, 0.3, 0.05, 0.3, 0.95,
283 1, 0.7, 0.05, 0.7, 0.95,
288 float const tilde[] = {
290 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
295 struct math_deco_struct {
301 math_deco_struct math_deco_table[] = {
303 { LM_widehat, &angle[0], 3 },
304 { LM_widetilde, &tilde[0], 0 },
305 { LM_underline, &hline[0], 0 },
306 { LM_overline, &hline[0], 0 },
307 { LM_underbrace, &brace[0], 1 },
308 { LM_overbrace, &brace[0], 3 },
309 { LM_overleftarrow, &arrow[0], 1 },
310 { LM_overightarrow, &arrow[0], 3 },
313 { '(', &parenth[0], 0 },
314 { ')', &parenth[0], 2 },
315 { '{', &brace[0], 0 },
316 { '}', &brace[0], 2 },
317 { '[', &brack[0], 0 },
318 { ']', &brack[0], 2 },
319 { '|', &vert[0], 0 },
320 { '/', &slash[0], 0 },
321 { LM_Vert, &Vert[0], 0 },
322 { LM_backslash, &slash[0], 1 },
323 { LM_langle, &angle[0], 0 },
324 { LM_lceil, &corner[0], 0 },
325 { LM_lfloor, &corner[0], 1 },
326 { LM_rangle, &angle[0], 2 },
327 { LM_rceil, &corner[0], 3 },
328 { LM_rfloor, &corner[0], 2 },
329 { LM_downarrow, &arrow[0], 2 },
330 { LM_Downarrow, &Arrow[0], 2 },
331 { LM_uparrow, &arrow[0], 0 },
332 { LM_Uparrow, &Arrow[0], 0 },
333 { LM_updownarrow, &udarrow[0], 0 },
334 { LM_Updownarrow, &Udarrow[0], 0 },
337 { LM_ddot, &hline2[0], 0 },
338 { LM_hat, &angle[0], 3 },
339 { LM_grave, &slash[0], 1 },
340 { LM_acute, &slash[0], 0 },
341 { LM_tilde, &tilde[0], 0 },
342 { LM_bar, &hline[0], 0 },
343 { LM_dot, &hlinesmall[0], 0 },
344 { LM_check, &angle[0], 1 },
345 { LM_breve, &parenth[0], 1 },
346 { LM_vec, &arrow[0], 3 },
347 { LM_not, &slash[0], 0 },
350 { LM_ldots, &hline3[0], 0 },
351 { LM_cdots, &hline3[0], 0 },
352 { LM_vdots, &hline3[0], 1 },
353 { LM_ddots, &dline3[0], 0 }
357 struct math_deco_compare {
358 /// for use by sort and lower_bound
360 int operator()(math_deco_struct const & a,
361 math_deco_struct const & b) const {
362 return a.code < b.code;
367 int const math_deco_table_size =
368 sizeof(math_deco_table) /sizeof(math_deco_struct);
371 class init_deco_table {
375 sort(math_deco_table,
376 math_deco_table + math_deco_table_size,
377 math_deco_compare());
378 init_deco_table::init = true;
386 bool init_deco_table::init = false;
387 static init_deco_table idt;
392 (short type, int size, byte c, int & asc, int & des, int & wid)
394 LyXFont const font = WhichFont(type, size);
395 des = lyxfont::descent(c, font);
396 asc = lyxfont::ascent(c, font);
397 wid = mathed_char_width(type, size, c);
400 int mathed_char_height(short type, int size, byte c, int & asc, int & des)
402 LyXFont const font = WhichFont(type, size);
403 des = lyxfont::descent(c, font);
404 asc = lyxfont::ascent(c, font);
409 int mathed_char_width(short type, int size, byte c)
411 if (MathIsBinary(type)) {
414 return mathed_string_width(type, size, s);
416 return lyxfont::width(c, WhichFont(type, size));
420 void mathed_string_dim(short type, int size, string const & s,
421 int & asc, int & des, int & wid)
423 mathed_string_height(type, size, s, asc, des);
424 wid = mathed_string_width(type, size, s);
427 int mathed_string_height(short type, int size, string const & s,
428 int & asc, int & des)
430 LyXFont const font = WhichFont(type, size);
432 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
433 des = max(des, lyxfont::descent(*it, font));
434 asc = max(asc, lyxfont::ascent(*it, font));
440 int mathed_string_width(short type, int size, string const & s)
443 if (MathIsBinary(type))
444 for (string::const_iterator it = s.begin();
445 it != s.end(); ++it) {
453 LyXFont const f = WhichFont(type, size);
454 return lyxfont::width(st, f);
458 LyXFont mathed_get_font(short type, int size)
460 LyXFont f = WhichFont(type, size);
462 if (type == LM_TC_TEX) {
463 f.setLatex(LyXFont::ON);
472 math_deco_struct const * search_deco(int code)
474 math_deco_struct search_elem = { code, 0, 0 };
476 math_deco_struct const * res =
477 lower_bound(math_deco_table,
478 math_deco_table + math_deco_table_size,
479 search_elem, math_deco_compare());
480 if (res != math_deco_table + math_deco_table_size &&
488 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
498 math_deco_struct const * mds = search_deco(code);
500 // Should this ever happen?
501 lyxerr << "Deco was not found. Programming error?" << endl;
505 int const r = mds->angle;
506 float const * d = mds->data;
508 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
514 int const n = (w < h) ? w : h;
517 if (r > 0 && r < 3) y += h;
526 xx = d[i++]; yy = d[i++];
527 x2 = d[i++]; y2 = d[i++];
529 sqmt.transf(xx, yy, xx, yy);
531 mt.transf(xx, yy, xx, yy);
532 mt.transf(x2, y2, x2, y2);
533 pain.line(x + int(xx), y + int(yy),
534 x + int(x2), y + int(y2),
543 int const n = int(d[i++]);
544 for (int j = 0; j < n; ++j) {
545 xx = d[i++]; yy = d[i++];
546 // lyxerr << " " << xx << " " << yy << " ";
548 sqmt.transf(xx, yy, xx, yy);
550 mt.transf(xx, yy, xx, yy);
553 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
555 pain.lines(xp, yp, n, LColor::mathline);
563 bool MathIsInset(short x)
565 return LM_TC_INSET == x;
569 bool MathIsAlphaFont(short x)
571 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
575 bool MathIsBOPS(short x)
577 return MathLookupBOP(x) > LMB_NONE;
581 bool MathIsBinary(short x)
583 return x == LM_TC_BOP || x == LM_TC_BOPS;
587 bool MathIsSymbol(short x)
589 return x == LM_TC_SYMB || x == LM_TC_BOPS || x == LM_TC_BSYM;
593 bool is_matrix_type(short int type)
595 return type == LM_OT_MATRIX;
598 // In a near future maybe we use a better fonts renderer
599 void drawStr(Painter & pain, short type, int siz,
600 int x, int y, string const & s)
603 if (MathIsBinary(type))
604 for (string::const_iterator it = s.begin();
605 it != s.end(); ++it) {
613 LyXFont const mf = mathed_get_font(type, siz);
614 pain.text(x, y, st, mf);
617 void drawChar(Painter & pain, short type, int siz, int x, int y, char c)
621 drawStr(pain, type, siz, x, y, s);
624 // decrease math size for super- and subscripts
625 MathStyles smallerStyleScript(MathStyles st)
629 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
630 default: st = LM_ST_SCRIPTSCRIPT;
635 // decrease math size for fractions
636 MathStyles smallerStyleFrac(MathStyles st)
639 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
640 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
641 default: st = LM_ST_SCRIPTSCRIPT;
646 bool MathIsRelOp(byte c, MathTextCodes f)
648 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
650 #ifndef WITH_WARNINGS
651 #warning implement me properly
653 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))