*
* Dependencies: Xlib, XForms
*
- * Copyright: (c) 1996, Alejandro Aguilar Sierra
+ * Copyright: 1996, Alejandro Aguilar Sierra
*
* Version: 0.8beta, Mathed & Lyx project.
*
#include <config.h>
#include FORMS_H_LOCATION
-#include <stdlib.h>
+#include <algorithm>
+#include <cstdlib>
#include "symbol_def.h"
#include "math_inset.h"
+#include "LColor.h"
+#include "Painter.h"
+
+using std::sort;
+using std::lower_bound;
+using std::endl;
/*
* Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
0.0
};
-static struct math_deco_struct {
- int code; float *data; int angle;
-} math_deco_table[] = {
+struct math_deco_struct {
+ int code;
+ float * data;
+ int angle;
+};
+
+static
+math_deco_struct math_deco_table[] = {
// Decorations
{ LM_widehat, &angle[0], 3 },
{ LM_ldots, &hline3[0], 0 },
{ LM_cdots, &hline3[0], 0 },
{ LM_vdots, &hline3[0], 1 },
- { LM_ddots, &dline3[0], 0 },
-
- { 0, 0, 0 }
+ { LM_ddots, &dline3[0], 0 }
};
-inline int odd(int x) { return ((x) & 1); }
+inline
+int odd(int x) { return ((x) & 1); }
typedef float matriz_data[2][2];
-const matriz_data MATIDEN={ {1,0}, {0,1}};
+const matriz_data MATIDEN= { {1, 0}, {0, 1}};
-extern void mathed_set_font(short type, int style);
extern int mathed_char_width(short type, int style, byte c);
-extern int mathed_char_height(short, int, byte, int&, int&);
+extern int mathed_char_height(short, int, byte, int &, int &);
-#define mateq(m1,m2) memcpy(m1,m2,sizeof(matriz_data))
+#define mateq(m1, m2) memcpy(m1, m2, sizeof(matriz_data))
class Matriz {
public:
- Matriz() { mateq(m,MATIDEN); }
+ Matriz() { mateq(m, MATIDEN); }
void rota(int);
void escala(float, float);
- void transf(float, float, float&, float&);
+ void transf(float, float, float &, float &);
protected:
matriz_data m;
- void matmat(matriz_data& a);
+ void matmat(matriz_data & a);
};
float cs, sn;
matriz_data r;
- mateq(r,MATIDEN);
+ mateq(r, MATIDEN);
cs = (odd(code)) ? 0: 1 - code;
sn = (odd(code)) ? 2 - code: 0;
r[0][0] = cs; r[0][1] = sn;
void Matriz::escala(float x, float y)
{
matriz_data s;
- mateq(s,MATIDEN);
+ mateq(s, MATIDEN);
s[0][0] = x; s[1][1] = y;
matmat(s);
}
-void Matriz::matmat(matriz_data& a)
+void Matriz::matmat(matriz_data & a)
{
- int i;
matriz_data c;
- for (i=0;i<2; i++) {
- c[0][i] = a[0][0]*m[0][i] + a[0][1]*m[1][i];
- c[1][i] = a[1][0]*m[0][i] + a[1][1]*m[1][i];
+ for (int i = 0;i < 2; ++i) {
+ c[0][i] = a[0][0] * m[0][i] + a[0][1] * m[1][i];
+ c[1][i] = a[1][0] * m[0][i] + a[1][1] * m[1][i];
}
mateq(m, c);
}
-void Matriz::transf(float xp, float yp, float &x, float &y)
+void Matriz::transf(float xp, float yp, float & x, float & y)
{
- x = m[0][0]*xp + m[0][1]*yp;
- y = m[1][0]*xp + m[1][1]*yp;
+ x = m[0][0] * xp + m[0][1] * yp;
+ y = m[1][0] * xp + m[1][1] * yp;
}
-extern GC latexGC, mathGC, mathLineGC, cursorGC;
-static int search_deco(int code)
+struct math_deco_compare {
+ /// for use by sort
+ inline
+ int operator()(math_deco_struct const & a,
+ math_deco_struct const & b) const {
+ return a.code < b.code;
+ }
+ /// for use by lower_bound
+ inline
+ int operator()(math_deco_struct const & a, int b) const {
+ return a.code < b;
+ }
+};
+
+
+static
+int const math_deco_table_size = sizeof(math_deco_table) /sizeof(math_deco_struct);
+
+class init_deco_table {
+public:
+ init_deco_table() {
+ if (!init) {
+ sort(math_deco_table,
+ math_deco_table + math_deco_table_size,
+ math_deco_compare());
+ init_deco_table::init = true;
+ }
+ }
+private:
+ static bool init;
+};
+
+bool init_deco_table::init = false;
+static init_deco_table idt;
+
+// If we had exceptions we could return a reference in stead and not
+// have to check for a null pointer in mathed_draw_deco
+
+#define USE_EXCEPTIONS 0
+#if USE_EXCEPTIONS
+struct deco_not_found {};
+
+static
+math_deco_struct const & search_deco(int code)
{
- int i=0;
-
- while (math_deco_table[i].code && math_deco_table[i].code!=code) i++;
- if (!math_deco_table[i].code) i = -1;
- return i;
+ math_deco_struct * res =
+ lower_bound(math_deco_table,
+ math_deco_table + math_deco_table_size,
+ code, math_deco_compare());
+ if (res != math_deco_table + math_deco_table_size &&
+ res->code == code)
+ return *res;
+ throw deco_not_found();
+}
+
+#else
+
+static
+math_deco_struct const * search_deco(int code)
+{
+ math_deco_struct * res =
+ lower_bound(math_deco_table,
+ math_deco_table + math_deco_table_size,
+ code, math_deco_compare());
+ if (res != math_deco_table + math_deco_table_size &&
+ res->code == code)
+ return res;
+ return 0;
}
-
-void mathed_draw_deco(Window win, int x, int y, int w, int h, int code)
+#endif
+
+void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
{
- Matriz mt, sqmt;
- XPoint p[32];
- float *d, xx, yy, x2, y2;
- int i=0,j, n, r;
-
- j = search_deco(code);
- if (j<0) return;
+ Matriz mt, sqmt;
+ float xx, yy, x2, y2;
+ int i = 0;
+
+#if USE_EXCEPTIONS
+ math_deco_struct mds;
+ try {
+ mds = search_deco(code);
+ }
+ catch (deco_not_found) {
+ // Should this ever happen?
+ lyxerr << "Deco was not found. Programming error?" << endl;
+ return;
+ }
- r = math_deco_table[j].angle;
- d = math_deco_table[j].data;
+ int r = mds.angle;
+ float * d = mds.data;
+
+ if (h > 70 && (mds.code == int('(')
+ || mds.code == int(')')))
+ d = parenthHigh;
+#else
+ math_deco_struct const * mds = search_deco(code);
+ if (!mds) {
+ // Should this ever happen?
+ lyxerr << "Deco was not found. Programming error?" << endl;
+ return;
+ }
+
- if (h > 70 && (math_deco_table[j].code == (int) '(' || math_deco_table[j].code == (int) ')'))
- d = parenthHigh;
-
- mt.rota(r);
- mt.escala(w, h);
+ int r = mds->angle;
+ float * d = mds->data;
+
+ if (h > 70 && (mds->code == int('(')
+ || mds->code == int(')')))
+ d = parenthHigh;
+#endif
+
+ mt.rota(r);
+ mt.escala(w, h);
- n = (w < h) ? w: h;
- sqmt.rota(r);
- sqmt.escala(n, n);
- if (r> 0 && r< 3) y += h;
- if (r>=2) x += w;
- do {
- code = (int)d[i++];
- switch (code) {
- case 0: break;
- case 1:
- case 3:
- {
- xx = d[i++]; yy = d[i++];
- x2 = d[i++]; y2 = d[i++];
- if (code==3)
- sqmt.transf(xx, yy, xx, yy);
- else
- mt.transf(xx, yy, xx, yy);
- mt.transf(x2, y2, x2, y2);
- XDrawLine(fl_display, win, mathGC, x+(int)xx, y+(int)yy,
- x+(int)x2, y+(int)y2);
- XFlush(fl_display);
- break;
- }
- case 2:
- case 4:
- {
- n = (int)d[i++];
- for (j=0; j<n; j++) {
- xx = d[i++]; yy = d[i++];
-// fprintf(stderr, " %g %g ", xx, yy);
- if (code==4)
- sqmt.transf(xx, yy, xx, yy);
- else
- mt.transf(xx, yy, xx, yy);
- p[j].x = x+(int)xx;
- p[j].y = y+(int)yy;
- // fprintf(stderr, "P[%d %g %g %d %d]", j, xx, yy, x, y);
- }
- XDrawLines(fl_display, win, mathLineGC, p, n, CoordModeOrigin);
- XFlush(fl_display);
- }
- }
- } while (code);
+ int n = (w < h) ? w: h;
+ sqmt.rota(r);
+ sqmt.escala(n, n);
+ if (r > 0 && r < 3) y += h;
+ if (r >= 2) x += w;
+ do {
+ code = int(d[i++]);
+ switch (code) {
+ case 0: break;
+ case 1:
+ case 3:
+ {
+ xx = d[i++]; yy = d[i++];
+ x2 = d[i++]; y2 = d[i++];
+ if (code == 3)
+ sqmt.transf(xx, yy, xx, yy);
+ else
+ mt.transf(xx, yy, xx, yy);
+ mt.transf(x2, y2, x2, y2);
+ pain.line(x + int(xx), y + int(yy),
+ x + int(x2), y + int(y2),
+ LColor::mathline);
+ break;
+ }
+ case 2:
+ case 4:
+ {
+ int xp[32], yp[32];
+ n = int(d[i++]);
+ for (int j = 0; j < n; ++j) {
+ xx = d[i++]; yy = d[i++];
+// lyxerr << " " << xx << " " << yy << " ";
+ if (code == 4)
+ sqmt.transf(xx, yy, xx, yy);
+ else
+ mt.transf(xx, yy, xx, yy);
+ xp[j] = x + int(xx);
+ yp[j] = y + int(yy);
+ // lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
+ }
+ pain.lines(xp, yp, n, LColor::mathline);
+ }
+ }
+ } while (code);
}
+
void
-MathDelimInset::Draw(int x, int y)
+MathDelimInset::draw(Painter & pain, int x, int y)
{
- xo = x; yo = y;
- MathParInset::Draw(x+dw+2, y-dh);
- //int h=Height(), hg=descent-1;
-
- if (left=='.') {
- XDrawLine(fl_display, pm, cursorGC, x+4, yo-ascent, x+4, yo+descent);
- XFlush(fl_display);
- }
- else
- mathed_draw_deco(pm, x, y-ascent, dw, Height(), left);
- x += Width()-dw-2;
- if (right=='.') {
- XDrawLine(fl_display, pm, cursorGC, x+4, yo-ascent, x+4, yo+descent);
- XFlush(fl_display);
- }
- else
- mathed_draw_deco(pm, x, y-ascent, dw, Height(), right);
+ xo = x; yo = y;
+ MathParInset::draw(pain, x + dw + 2, y - dh);
+
+ if (left == '.') {
+ pain.line(x + 4, yo - ascent,
+ x + 4, yo + descent,
+ LColor::mathcursor, Painter::line_onoffdash);
+ } else
+ mathed_draw_deco(pain, x, y - ascent, dw, Height(), left);
+ x += Width() - dw - 2;
+ if (right == '.') {
+ pain.line(x + 4, yo - ascent,
+ x + 4, yo + descent,
+ LColor::mathcursor, Painter::line_onoffdash);
+ } else
+ mathed_draw_deco(pain, x, y-ascent, dw, Height(), right);
}
+
void
MathDelimInset::Metrics()
{
void
-MathDecorationInset::Draw(int x, int y)
+MathDecorationInset::draw(Painter & pain, int x, int y)
{
- MathParInset::Draw(x+(width-dw)/2, y);
- mathed_draw_deco(pm, x, y+dy, width, dh, deco);
+ MathParInset::draw(pain, x + (width - dw) / 2, y);
+ mathed_draw_deco(pain, x, y + dy, width, dh, deco);
}
width = w;
}
+
void
-MathAccentInset::Draw(int x, int y)
+MathAccentInset::draw(Painter & pain, int x, int y)
{
- int dw = width-2;
-/* char s[8];
- mathed_set_font(fn, size);
- if (MathIsBinary(fn)) {
- s[0] = s[2] = ' ';
- s[1] = (char)c;
- ns = 3;
- dw = mathed_char_width(fn, size, c);
- } else
- s[0] = (char)c;
-*/
+ int dw = width - 2;
+
if (inset) {
- inset->Draw(x, y);
+ inset->draw(pain, x, y);
} else {
- drawStr(fn, size, x, y, &c, 1);
- XFlush(fl_display);
+ drawStr(pain, fn, size, x, y, &c, 1);
}
- x += (code==LM_not) ? (width-dw)/2: 2;
- mathed_draw_deco(pm, x, y-dy, dw, dh, code);
+ x += (code == LM_not) ? (width-dw) / 2 : 2;
+ mathed_draw_deco(pain, x, y - dy, dw, dh, code);
}
+
void
MathAccentInset::Metrics()
{
width = mathed_char_width(fn, size, c);
dh = (width-2)/2;
}
- if (code==LM_not) {
+ if (code == LM_not) {
ascent += dh;
descent += dh;
dh = Height();
void
-MathDotsInset::Draw(int x, int y)
+MathDotsInset::draw(Painter & pain, int x, int y)
{
- mathed_draw_deco(pm, x+2, y-dh, width-2, ascent, code);
- if (code==LM_vdots||code==LM_ddots) x++;
- if (code!=LM_vdots) y--;
- mathed_draw_deco(pm, x+2, y-dh, width-2, ascent, code);
-}
+ mathed_draw_deco(pain, x + 2, y - dh, width - 2, ascent, code);
+ if (code == LM_vdots || code == LM_ddots) ++x;
+ if (code != LM_vdots) --y;
+ mathed_draw_deco(pain, x + 2, y - dh, width - 2, ascent, code);
+}
+
void
MathDotsInset::Metrics()
switch (code) {
case LM_ldots: dh = 0; break;
case LM_cdots: dh = ascent/2; break;
- case LM_vdots: width /=2;
+ case LM_vdots: width /= 2;
case LM_ddots: dh = ascent; break;
}
}