]> 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 d6e7efa70a4ed87aed269212097df6c9ab7683f8..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:
  * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
@@ -164,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 },
@@ -219,20 +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 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))
 
@@ -241,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);
 };
 
 
@@ -271,48 +280,133 @@ void Matriz::escala(float x, float y)
 }
 
 
-void Matriz::matmat(matriz_data& a)
+void Matriz::matmat(matriz_data & a)
 {
    matriz_data c;   
    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];
+      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;
 }
 
 
+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
-int search_deco(int code)
+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;
+}
+#endif
 
 void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
 {
        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;
+       }
    
-       int j = search_deco(code);   
-       if (j < 0) return;
+       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;
+       }
+       
    
-       int r = math_deco_table[j].angle;
-       float * d = math_deco_table[j].data;
+       int r = mds->angle;
+       float * d = mds->data;
        
-       if (h > 70 && (math_deco_table[j].code == int('(') || math_deco_table[j].code == int(')')))
+       if (h > 70 && (mds->code == int('(')
+                      || mds->code == int(')')))
                d = parenthHigh;
+#endif
        
        mt.rota(r);
        mt.escala(w, h);
@@ -346,7 +440,7 @@ void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
                {
                        int xp[32], yp[32];
                        n = int(d[i++]);
-                       for (j = 0; j < n; ++j) {
+                       for (int j = 0; j < n; ++j) {
                                xx = d[i++]; yy = d[i++];
 //          lyxerr << " " << xx << " " << yy << " ";
                                if (code == 4) 
@@ -373,14 +467,14 @@ MathDelimInset::draw(Painter & pain, int x, int y)
        if (left == '.') {
                pain.line(x + 4, yo - ascent,
                          x + 4, yo + descent,
-                         LColor::mathcursor);
+                         LColor::mathcursor, Painter::line_onoffdash);
        } else
                mathed_draw_deco(pain, x, y - ascent, dw, Height(), left);
-       x += Width()-dw-2;
+       x += Width() - dw - 2;
        if (right == '.') {
                pain.line(x + 4, yo - ascent,
                          x + 4, yo + descent,
-                         LColor::mathcursor);
+                         LColor::mathcursor, Painter::line_onoffdash);
        } else
                mathed_draw_deco(pain, x, y-ascent, dw, Height(), right);
 }