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;
24 typedef float matriz_data[2][2];
30 void escalate(float, float);
32 void transform(float, float, float &, float &);
37 void multiply(matriz_data & a);
48 void Matrix::rotate(int code)
55 float const cs = (code & 1) ? 0 : (1 - code);
56 float const sn = (code & 1) ? (2 - code) : 0;
64 void Matrix::escalate(float x, float y)
74 void Matrix::multiply(matriz_data & a)
77 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
78 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
79 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
80 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
87 void Matrix::transform(float xp, float yp, float & x, float & y)
89 x = m_[0][0] * xp + m_[0][1] * yp;
90 y = m_[1][0] * xp + m_[1][1] * yp;
95 extern LyXFont WhichFont(short type, int size);
97 char const * math_font_name[] = {
108 char const * latex_mathspace[] = {
109 "!", ",", ":", ";", "quad", "qquad"
116 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
117 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
121 float const parenthHigh[] = {
123 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
124 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
125 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
126 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
132 float const parenth[] = {
134 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
135 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
136 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
137 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
143 float const brace[] = {
145 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
146 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
147 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
148 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
149 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
150 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
151 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
156 // Is this correct? (Lgb)
157 float const arrow[] = {
159 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
160 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
162 3, 0.5000, 0.1500, 0.5000, 0.9500,
167 // Is this correct? (Lgb)
168 float const Arrow[] = {
170 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
171 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
173 3, 0.3500, 0.5000, 0.3500, 0.9500,
174 3, 0.6500, 0.5000, 0.6500, 0.9500,
179 float const udarrow[] = {
181 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
183 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
184 1, 0.5, 0.2, 0.5, 0.8,
189 float const Udarrow[] = {
191 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
193 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
194 1, 0.35, 0.2, 0.35, 0.8,
195 1, 0.65, 0.2, 0.65, 0.8,
200 float const brack[] = {
202 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
207 float const corner[] = {
209 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
214 float const angle[] = {
216 1, 0, 0.05, 0.5, 1, 1,
221 float const slash[] = {
222 1, 0.95, 0.05, 0.05, 0.95,
227 float const hline[] = {
228 1, 0.05, 0.5, 0.95, 0.5,
233 float const hline2[] = {
234 1, 0.1, 0.5, 0.3, 0.5,
235 1, 0.7, 0.5, 0.9, 0.5,
240 float const hline3[] = {
242 1, 0.475, 0, 0.525, 0,
248 float const dline3[] = {
249 1, 0.1, 0.1, 0.15, 0.15,
250 1, 0.475, 0.475, 0.525, 0.525,
251 1, 0.85, 0.85, 0.9, 0.9,
256 float const hlinesmall[] = {
257 1, 0.4, 0.5, 0.6, 0.5,
262 float const vert[] = {
263 1, 0.5, 0.05, 0.5, 0.95,
268 float const Vert[] = {
269 1, 0.3, 0.05, 0.3, 0.95,
270 1, 0.7, 0.05, 0.7, 0.95,
275 float const tilde[] = {
277 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
282 struct math_deco_struct {
288 math_deco_struct math_deco_table[] = {
290 { LM_widehat, &angle[0], 3 },
291 { LM_widetilde, &tilde[0], 0 },
292 { LM_underline, &hline[0], 0 },
293 { LM_overline, &hline[0], 0 },
294 { LM_underbrace, &brace[0], 1 },
295 { LM_overbrace, &brace[0], 3 },
296 { LM_overleftarrow, &arrow[0], 1 },
297 { LM_overightarrow, &arrow[0], 3 },
300 { '(', &parenth[0], 0 },
301 { ')', &parenth[0], 2 },
302 { '{', &brace[0], 0 },
303 { '}', &brace[0], 2 },
304 { '[', &brack[0], 0 },
305 { ']', &brack[0], 2 },
306 { '|', &vert[0], 0 },
307 { '/', &slash[0], 0 },
308 { LM_Vert, &Vert[0], 0 },
309 { LM_backslash, &slash[0], 1 },
310 { LM_langle, &angle[0], 0 },
311 { LM_lceil, &corner[0], 0 },
312 { LM_lfloor, &corner[0], 1 },
313 { LM_rangle, &angle[0], 2 },
314 { LM_rceil, &corner[0], 3 },
315 { LM_rfloor, &corner[0], 2 },
316 { LM_downarrow, &arrow[0], 2 },
317 { LM_Downarrow, &Arrow[0], 2 },
318 { LM_uparrow, &arrow[0], 0 },
319 { LM_Uparrow, &Arrow[0], 0 },
320 { LM_updownarrow, &udarrow[0], 0 },
321 { LM_Updownarrow, &Udarrow[0], 0 },
324 { LM_ddot, &hline2[0], 0 },
325 { LM_hat, &angle[0], 3 },
326 { LM_grave, &slash[0], 1 },
327 { LM_acute, &slash[0], 0 },
328 { LM_tilde, &tilde[0], 0 },
329 { LM_bar, &hline[0], 0 },
330 { LM_dot, &hlinesmall[0], 0 },
331 { LM_check, &angle[0], 1 },
332 { LM_breve, &parenth[0], 1 },
333 { LM_vec, &arrow[0], 3 },
334 { LM_not, &slash[0], 0 },
337 { LM_ldots, &hline3[0], 0 },
338 { LM_cdots, &hline3[0], 0 },
339 { LM_vdots, &hline3[0], 1 },
340 { LM_ddots, &dline3[0], 0 }
344 struct math_deco_compare {
345 /// for use by sort and lower_bound
347 int operator()(math_deco_struct const & a,
348 math_deco_struct const & b) const {
349 return a.code < b.code;
354 int const math_deco_table_size =
355 sizeof(math_deco_table) /sizeof(math_deco_struct);
358 class init_deco_table {
362 sort(math_deco_table,
363 math_deco_table + math_deco_table_size,
364 math_deco_compare());
365 init_deco_table::init = true;
373 bool init_deco_table::init = false;
374 static init_deco_table idt;
378 void mathed_char_dim (short type, int size, byte c, int & asc, int & des, int & wid)
380 LyXFont const font = WhichFont(type, size);
381 des = lyxfont::descent(c, font);
382 asc = lyxfont::ascent(c, font);
383 wid = mathed_char_width(type, size, c);
386 int mathed_char_height(short type, int size, byte c, int & asc, int & des)
388 LyXFont const font = WhichFont(type, size);
389 des = lyxfont::descent(c, font);
390 asc = lyxfont::ascent(c, font);
395 int mathed_char_width(short type, int size, byte c)
397 if (MathIsBinary(type)) {
400 return mathed_string_width(type, size, s);
402 return lyxfont::width(c, WhichFont(type, size));
406 void mathed_string_dim(short type, int size, string const & s,
407 int & asc, int & des, int & wid)
409 mathed_string_height(type, size, s, asc, des);
410 wid = mathed_string_width(type, size, s);
413 int mathed_string_height(short type, int size, string const & s,
414 int & asc, int & des)
416 LyXFont const font = WhichFont(type, size);
418 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
419 des = max(des, lyxfont::descent(*it, font));
420 asc = max(asc, lyxfont::ascent(*it, font));
426 int mathed_string_width(short type, int size, string const & s)
429 if (MathIsBinary(type))
430 for (string::const_iterator it = s.begin();
431 it != s.end(); ++it) {
439 LyXFont const f = WhichFont(type, size);
440 return lyxfont::width(st, f);
444 LyXFont mathed_get_font(short type, int size)
446 LyXFont f = WhichFont(type, size);
448 if (type == LM_TC_TEX) {
449 f.setLatex(LyXFont::ON);
458 math_deco_struct const * search_deco(int code)
460 math_deco_struct search_elem = { code, 0, 0 };
462 math_deco_struct const * res =
463 lower_bound(math_deco_table,
464 math_deco_table + math_deco_table_size,
465 search_elem, math_deco_compare());
466 if (res != math_deco_table + math_deco_table_size &&
474 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
484 math_deco_struct const * mds = search_deco(code);
486 // Should this ever happen?
487 lyxerr << "Deco was not found. Programming error?" << endl;
491 int const r = mds->angle;
492 float const * d = mds->data;
494 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
500 int const n = (w < h) ? w : h;
503 if (r > 0 && r < 3) y += h;
512 xx = d[i++]; yy = d[i++];
513 x2 = d[i++]; y2 = d[i++];
515 sqmt.transform(xx, yy, xx, yy);
517 mt.transform(xx, yy, xx, yy);
518 mt.transform(x2, y2, x2, y2);
519 pain.line(x + int(xx), y + int(yy),
520 x + int(x2), y + int(y2),
529 int const n = int(d[i++]);
530 for (int j = 0; j < n; ++j) {
531 xx = d[i++]; yy = d[i++];
532 // lyxerr << " " << xx << " " << yy << " ";
534 sqmt.transform(xx, yy, xx, yy);
536 mt.transform(xx, yy, xx, yy);
539 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
541 pain.lines(xp, yp, n, LColor::mathline);
549 bool MathIsInset(short x)
551 return LM_TC_INSET == x;
555 bool MathIsAlphaFont(short x)
557 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
561 bool MathIsBOPS(short x)
563 return MathLookupBOP(x) > LMB_NONE;
567 bool MathIsBinary(short x)
569 return x == LM_TC_BOP || x == LM_TC_BOPS;
573 bool MathIsSymbol(short x)
575 return x == LM_TC_SYMB || x == LM_TC_BOPS || x == LM_TC_BSYM;
579 bool is_matrix_type(short int type)
581 return type == LM_OT_MATRIX;
584 // In a near future maybe we use a better fonts renderer
585 void drawStr(Painter & pain, short type, int siz,
586 int x, int y, string const & s)
589 if (MathIsBinary(type))
590 for (string::const_iterator it = s.begin();
591 it != s.end(); ++it) {
599 LyXFont const mf = mathed_get_font(type, siz);
600 pain.text(x, y, st, mf);
603 void drawChar(Painter & pain, short type, int siz, int x, int y, char c)
607 drawStr(pain, type, siz, x, y, s);
610 // decrease math size for super- and subscripts
611 MathStyles smallerStyleScript(MathStyles st)
615 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
616 default: st = LM_ST_SCRIPTSCRIPT;
621 // decrease math size for fractions
622 MathStyles smallerStyleFrac(MathStyles st)
625 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
626 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
627 default: st = LM_ST_SCRIPTSCRIPT;
632 bool MathIsRelOp(byte c, MathTextCodes f)
634 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
636 #ifndef WITH_WARNINGS
637 #warning implement me properly
639 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))