]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_delim.C
Hopefully fix the problem with stateText() in lyxfont.C
[lyx.git] / src / mathed / math_delim.C
index a60dce8217b68d69436d2e27e8606b487c6bb39a..fc128941ea27199a34f4f706a859ac49ab53798d 100644 (file)
@@ -7,7 +7,7 @@
  *
  *  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 <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:
@@ -162,9 +169,14 @@ static float tilde[] = {
    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 },
@@ -217,21 +229,19 @@ static struct math_deco_struct {
   { 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}};
 
-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))
 
@@ -240,11 +250,11 @@ class Matriz {
    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);
 };
 
 
@@ -270,121 +280,206 @@ void Matriz::escala(float x, float y)
 }
 
 
-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++];
+       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);
-            p[j].x = x+(int)xx;
-            p[j].y = y+(int)yy;
-            //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
-         }
-         XDrawLines(fl_display, win, mathLineGC, p, n, CoordModeOrigin);
-         XFlush(fl_display);
-       }
-      }
-   } while (code);
+                               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()
 {
@@ -403,10 +498,10 @@ 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);
 }
 
 
@@ -431,30 +526,22 @@ MathDecorationInset::Metrics()
    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()
 {
@@ -484,13 +571,14 @@ MathAccentInset::Metrics()
 
 
 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()