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;
21 bool MathIsInset(short x)
23 return LM_TC_INSET == x;
27 bool MathIsAlphaFont(short x)
29 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
33 bool MathIsBOPS(short x)
35 return MathLookupBOP(x) > LMB_NONE;
39 bool MathIsBinary(short x)
41 return x == LM_TC_BOP || x == LM_TC_BOPS;
45 bool MathIsSymbol(short x)
47 return x == LM_TC_SYMB || x == LM_TC_BOPS || x == LM_TC_BSYM;
56 typedef float matriz_data[2][2];
62 void escalate(float, float);
64 void transform(float, float, float &, float &);
69 void multiply(matriz_data & a);
80 void Matrix::rotate(int code)
87 float const cs = (code & 1) ? 0 : (1 - code);
88 float const sn = (code & 1) ? (2 - code) : 0;
96 void Matrix::escalate(float x, float y)
106 void Matrix::multiply(matriz_data & a)
109 c[0][0] = a[0][0] * m_[0][0] + a[0][1] * m_[1][0];
110 c[1][0] = a[1][0] * m_[0][0] + a[1][1] * m_[1][0];
111 c[0][1] = a[0][0] * m_[0][1] + a[0][1] * m_[1][1];
112 c[1][1] = a[1][0] * m_[0][1] + a[1][1] * m_[1][1];
119 void Matrix::transform(float xp, float yp, float & x, float & y)
121 x = m_[0][0] * xp + m_[0][1] * yp;
122 y = m_[1][0] * xp + m_[1][1] * yp;
127 extern LyXFont WhichFont(short type, int size);
129 char const * math_font_name[] = {
140 char const * latex_mathspace[] = {
141 "!", ",", ":", ";", "quad", "qquad"
148 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
149 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
153 float const parenthHigh[] = {
155 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
156 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
157 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
158 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
164 float const parenth[] = {
166 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
167 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
168 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
169 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
175 float const brace[] = {
177 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
178 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
179 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
180 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
181 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
182 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
183 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
188 // Is this correct? (Lgb)
189 float const arrow[] = {
191 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
192 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
194 3, 0.5000, 0.1500, 0.5000, 0.9500,
199 // Is this correct? (Lgb)
200 float const Arrow[] = {
202 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
203 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
205 3, 0.3500, 0.5000, 0.3500, 0.9500,
206 3, 0.6500, 0.5000, 0.6500, 0.9500,
211 float const udarrow[] = {
213 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
215 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
216 1, 0.5, 0.2, 0.5, 0.8,
221 float const Udarrow[] = {
223 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
225 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
226 1, 0.35, 0.2, 0.35, 0.8,
227 1, 0.65, 0.2, 0.65, 0.8,
232 float const brack[] = {
234 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
239 float const corner[] = {
241 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
246 float const angle[] = {
248 1, 0, 0.05, 0.5, 1, 1,
253 float const slash[] = {
254 1, 0.95, 0.05, 0.05, 0.95,
259 float const hline[] = {
260 1, 0.05, 0.5, 0.95, 0.5,
265 float const hline2[] = {
266 1, 0.1, 0.5, 0.3, 0.5,
267 1, 0.7, 0.5, 0.9, 0.5,
272 float const hline3[] = {
274 1, 0.475, 0, 0.525, 0,
280 float const dline3[] = {
281 1, 0.1, 0.1, 0.15, 0.15,
282 1, 0.475, 0.475, 0.525, 0.525,
283 1, 0.85, 0.85, 0.9, 0.9,
288 float const hlinesmall[] = {
289 1, 0.4, 0.5, 0.6, 0.5,
294 float const vert[] = {
295 1, 0.5, 0.05, 0.5, 0.95,
300 float const Vert[] = {
301 1, 0.3, 0.05, 0.3, 0.95,
302 1, 0.7, 0.05, 0.7, 0.95,
307 float const tilde[] = {
309 0.05, 0.8, 0.25, 0.2, 0.75, 0.8, 0.95, 0.2,
314 struct math_deco_struct {
320 math_deco_struct math_deco_table[] = {
322 { LM_widehat, &angle[0], 3 },
323 { LM_widetilde, &tilde[0], 0 },
324 { LM_underline, &hline[0], 0 },
325 { LM_overline, &hline[0], 0 },
326 { LM_underbrace, &brace[0], 1 },
327 { LM_overbrace, &brace[0], 3 },
328 { LM_overleftarrow, &arrow[0], 1 },
329 { LM_overightarrow, &arrow[0], 3 },
332 { '(', &parenth[0], 0 },
333 { ')', &parenth[0], 2 },
334 { '{', &brace[0], 0 },
335 { '}', &brace[0], 2 },
336 { '[', &brack[0], 0 },
337 { ']', &brack[0], 2 },
338 { '|', &vert[0], 0 },
339 { '/', &slash[0], 0 },
340 { LM_Vert, &Vert[0], 0 },
341 { LM_backslash, &slash[0], 1 },
342 { LM_langle, &angle[0], 0 },
343 { LM_lceil, &corner[0], 0 },
344 { LM_lfloor, &corner[0], 1 },
345 { LM_rangle, &angle[0], 2 },
346 { LM_rceil, &corner[0], 3 },
347 { LM_rfloor, &corner[0], 2 },
348 { LM_downarrow, &arrow[0], 2 },
349 { LM_Downarrow, &Arrow[0], 2 },
350 { LM_uparrow, &arrow[0], 0 },
351 { LM_Uparrow, &Arrow[0], 0 },
352 { LM_updownarrow, &udarrow[0], 0 },
353 { LM_Updownarrow, &Udarrow[0], 0 },
356 { LM_ddot, &hline2[0], 0 },
357 { LM_hat, &angle[0], 3 },
358 { LM_grave, &slash[0], 1 },
359 { LM_acute, &slash[0], 0 },
360 { LM_tilde, &tilde[0], 0 },
361 { LM_bar, &hline[0], 0 },
362 { LM_dot, &hlinesmall[0], 0 },
363 { LM_check, &angle[0], 1 },
364 { LM_breve, &parenth[0], 1 },
365 { LM_vec, &arrow[0], 3 },
366 { LM_not, &slash[0], 0 },
369 { LM_ldots, &hline3[0], 0 },
370 { LM_cdots, &hline3[0], 0 },
371 { LM_vdots, &hline3[0], 1 },
372 { LM_ddots, &dline3[0], 0 }
376 struct math_deco_compare {
377 /// for use by sort and lower_bound
379 int operator()(math_deco_struct const & a,
380 math_deco_struct const & b) const {
381 return a.code < b.code;
386 int const math_deco_table_size =
387 sizeof(math_deco_table) /sizeof(math_deco_struct);
390 class init_deco_table {
394 sort(math_deco_table,
395 math_deco_table + math_deco_table_size,
396 math_deco_compare());
397 init_deco_table::init = true;
405 bool init_deco_table::init = false;
406 static init_deco_table idt;
410 void mathed_char_dim (short type, int size, unsigned char c,
411 int & asc, int & des, int & wid)
413 LyXFont const font = WhichFont(type, size);
414 des = lyxfont::descent(c, font);
415 asc = lyxfont::ascent(c, font);
416 wid = mathed_char_width(type, size, c);
419 int mathed_char_height(short type, int size, unsigned char c,
420 int & asc, int & des)
422 LyXFont const font = WhichFont(type, size);
423 des = lyxfont::descent(c, font);
424 asc = lyxfont::ascent(c, font);
429 int mathed_char_width(short type, int size, unsigned char c)
431 if (MathIsBinary(type)) {
434 return mathed_string_width(type, size, s);
436 return lyxfont::width(c, WhichFont(type, size));
440 void mathed_string_dim(short type, int size, string const & s,
441 int & asc, int & des, int & wid)
443 mathed_string_height(type, size, s, asc, des);
444 wid = mathed_string_width(type, size, s);
447 int mathed_string_height(short type, int size, string const & s,
448 int & asc, int & des)
450 LyXFont const font = WhichFont(type, size);
452 for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
453 des = max(des, lyxfont::descent(*it, font));
454 asc = max(asc, lyxfont::ascent(*it, font));
460 int mathed_string_width(short type, int size, string const & s)
463 if (MathIsBinary(type))
464 for (string::const_iterator it = s.begin();
465 it != s.end(); ++it) {
473 LyXFont const f = WhichFont(type, size);
474 return lyxfont::width(st, f);
478 LyXFont mathed_get_font(short type, int size)
480 LyXFont f = WhichFont(type, size);
482 if (type == LM_TC_TEX) {
483 f.setLatex(LyXFont::ON);
492 math_deco_struct const * search_deco(int code)
494 math_deco_struct search_elem = { code, 0, 0 };
496 math_deco_struct const * res =
497 lower_bound(math_deco_table,
498 math_deco_table + math_deco_table_size,
499 search_elem, math_deco_compare());
500 if (res != math_deco_table + math_deco_table_size &&
508 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
518 math_deco_struct const * mds = search_deco(code);
520 // Should this ever happen?
521 lyxerr << "Deco was not found. Programming error?" << endl;
525 int const r = mds->angle;
526 float const * d = mds->data;
528 if (h > 70 && (mds->code == int('(') || mds->code == int(')')))
534 int const n = (w < h) ? w : h;
537 if (r > 0 && r < 3) y += h;
546 xx = d[i++]; yy = d[i++];
547 x2 = d[i++]; y2 = d[i++];
549 sqmt.transform(xx, yy, xx, yy);
551 mt.transform(xx, yy, xx, yy);
552 mt.transform(x2, y2, x2, y2);
553 pain.line(x + int(xx), y + int(yy),
554 x + int(x2), y + int(y2),
563 int const n = int(d[i++]);
564 for (int j = 0; j < n; ++j) {
565 xx = d[i++]; yy = d[i++];
566 // lyxerr << " " << xx << " " << yy << " ";
568 sqmt.transform(xx, yy, xx, yy);
570 mt.transform(xx, yy, xx, yy);
573 // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
575 pain.lines(xp, yp, n, LColor::mathline);
583 // In a near future maybe we use a better fonts renderer
584 void drawStr(Painter & pain, short type, int siz,
585 int x, int y, string const & s)
588 if (MathIsBinary(type))
589 for (string::const_iterator it = s.begin();
590 it != s.end(); ++it) {
598 LyXFont const mf = mathed_get_font(type, siz);
599 pain.text(x, y, st, mf);
602 void drawChar(Painter & pain, short type, int siz, int x, int y, char c)
606 drawStr(pain, type, siz, x, y, s);
609 // decrease math size for super- and subscripts
610 MathStyles smallerStyleScript(MathStyles st)
614 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
615 default: st = LM_ST_SCRIPTSCRIPT;
620 // decrease math size for fractions
621 MathStyles smallerStyleFrac(MathStyles st)
624 case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
625 case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
626 default: st = LM_ST_SCRIPTSCRIPT;
631 bool MathIsRelOp(unsigned char c, MathTextCodes f)
633 if (f == LM_TC_BOP && (c == '=' || c == '<' || c == '>'))
635 #ifndef WITH_WARNINGS
636 #warning implement me properly
638 if (f == LM_TC_SYMB && (c == LM_leq || c == LM_geq))