]> git.lyx.org Git - lyx.git/commitdiff
first go at mathed file cleanup
authorLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 13 Feb 2001 13:28:32 +0000 (13:28 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Tue, 13 Feb 2001 13:28:32 +0000 (13:28 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@1495 a592a061-630c-0410-9148-cb99ea01b6c8

49 files changed:
src/mathed/ChangeLog
src/mathed/Makefile.am
src/mathed/array.C
src/mathed/array.h
src/mathed/formula.C
src/mathed/marh_sqrtinset.h [new file with mode: 0644]
src/mathed/math_accentinset.C [new file with mode: 0644]
src/mathed/math_accentinset.h [new file with mode: 0644]
src/mathed/math_bigopinset.C [new file with mode: 0644]
src/mathed/math_bigopinset.h [new file with mode: 0644]
src/mathed/math_cursor.C
src/mathed/math_cursor.h
src/mathed/math_decorationinset.C [new file with mode: 0644]
src/mathed/math_decorationinset.h [new file with mode: 0644]
src/mathed/math_defs.h
src/mathed/math_delim.C
src/mathed/math_deliminset.C [new file with mode: 0644]
src/mathed/math_deliminset.h [new file with mode: 0644]
src/mathed/math_dotsinset.C [new file with mode: 0644]
src/mathed/math_dotsinset.h [new file with mode: 0644]
src/mathed/math_draw.C
src/mathed/math_fracinset.C [new file with mode: 0644]
src/mathed/math_fracinset.h [new file with mode: 0644]
src/mathed/math_funcinset.C [new file with mode: 0644]
src/mathed/math_funcinset.h [new file with mode: 0644]
src/mathed/math_inset.C
src/mathed/math_inset.h
src/mathed/math_iter.C
src/mathed/math_iter.h
src/mathed/math_macro.C
src/mathed/math_macro.h
src/mathed/math_matrixinset.C [new file with mode: 0644]
src/mathed/math_matrixinset.h [new file with mode: 0644]
src/mathed/math_parinset.C [new file with mode: 0644]
src/mathed/math_parinset.h [new file with mode: 0644]
src/mathed/math_parser.C
src/mathed/math_root.h
src/mathed/math_rowst.h [new file with mode: 0644]
src/mathed/math_spaceinset.C [new file with mode: 0644]
src/mathed/math_spaceinset.h [new file with mode: 0644]
src/mathed/math_sqrtinset.C [new file with mode: 0644]
src/mathed/math_sqrtinset.h [new file with mode: 0644]
src/mathed/math_write.C
src/mathed/math_xiter.C [new file with mode: 0644]
src/mathed/math_xiter.h [new file with mode: 0644]
src/mathed/matriz.C [new file with mode: 0644]
src/mathed/matriz.h [new file with mode: 0644]
src/mathed/support.C [new file with mode: 0644]
src/mathed/support.h [new file with mode: 0644]

index c63589bf0b265937d2e3fb88a5139aa901a2bee4..72af1de76223503cadcf8402908bdace744d8246 100644 (file)
@@ -1,3 +1,10 @@
+2001-02-13  Lars Gullik Bjønnes  <larsbj@lyx.org>
+
+       * array.C (strange_copy): fix bug (hopefully) 
+       * many files: add a lot of new files and move methods to the class
+       files they belong to. Only first attempt at cleanup more will
+       follow.
+       
 2001-02-12  André Pönitz  <poenitz@htwm.de>
        
        * math_macro.[hC]: replace MathMacroArgument[] with
index d84ec6ca445935b51523ec14615c877b5ac83de4..32d34a8ef9743ea73e86f5f0ea539050d220cbe4 100644 (file)
@@ -14,13 +14,28 @@ libmathed_la_SOURCES = \
        formula.h \
        formulamacro.C \
        formulamacro.h \
+       math_sqrtinset.C \
+       math_sqrtinset.h \
+       math_accentinset.C \
+       math_accentinset.h \
+       math_bigopinset.C \
+       math_bibopinset.h \
        math_cursor.C \
        math_cursor.h \
+       math_decorationinset.C \
+       math_decorationinset.h \
        math_defs.h \
-       math_delim.C \
+       math_deliminset.C \
+       math_deliminset.h \
+       math_dotsinset.C \
+       math_dotsinset.h \
        math_draw.C \
        math_forms.C \
        math_forms.h \
+       math_fracinset.C \
+       math_fracinset.h \
+       math_funcinset.C \
+       math_funcinset.h \
        math_hash.C \
        math_inset.C \
        math_inset.h \
@@ -28,13 +43,28 @@ libmathed_la_SOURCES = \
        math_iter.h \
        math_macro.C \
        math_macro.h \
+       math_matrixinset.C \
+       math_matrixinset.h \
        math_panel.C \
        math_panel.h \
+       math_parinset.C \
+       math_parinset.h \
        math_parser.C \
        math_parser.h \
        math_root.C \
        math_root.h \
+       math_rowst.h \
+       math_spaceinset.C \
+       math_spaceinset.h \
+       math_sqrtinset.C \
+       math_sqrtinset.h \
        math_symbols.C \
        math_utils.C \
        math_write.C \
+       math_xiter.C \
+       math_xiter.h \
+       matriz.C \
+       matriz.h \
+       support.C \
+       support.h \
        symbol_def.h
index 2d08fc10e39a23915856563da2b43d01755e1e1a..41bf1f4e4ec9a8c19ff52dc41666b53520643782 100644 (file)
@@ -102,7 +102,7 @@ void MathedArray::raw_pointer_insert(void * p, int pos, int len)
 void MathedArray::strange_copy(MathedArray * dest, int dpos,
                                int spos, int len)
 {
-       my_memcpy(&dest[dpos], &bf_[spos], len);
+       my_memcpy(&dest->bf_[dpos], &bf_[spos], len);
 }
 
 
index 1ee0cd7289dfb2fbb668856e74f852af4415edb8..0f3257951aff0143ed476f0227ddc06139b90d32 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <vector>
 
+#include "math_defs.h"
 
 class MathedInset;
 
@@ -25,10 +26,6 @@ class MathedInset;
 #pragma interface
 #endif
 
-#ifndef byte
-#define byte unsigned char
-#endif
-
 /** \class MathedArray
     \brief A resizable array.
     
index 0e4b64c45dc70fcfa3bcbbe19ec585febdd60921..67363caa0c79af950aa495617fd1e062865befb7 100644 (file)
 #include "font.h"
 #include "support/lyxlib.h"
 #include "lyxrc.h"
+#include "math_defs.h"
+#include "math_inset.h"
+#include "math_parinset.h"
+#include "math_matrixinset.h"
+#include "math_rowst.h"
+#include "math_spaceinset.h"
+#include "math_deliminset.h"
+#include "support.h"
 
 using std::ostream;
 using std::istream;
@@ -72,11 +80,7 @@ static bool sel_flag;
 
 MathedCursor * InsetFormula::mathcursor = 0; 
 
-
-int MathedInset::df_asc;
-int MathedInset::df_des;
-int MathedInset::df_width;
-int MathedInset::workWidth;
+void mathed_init_fonts();
 
 
 static
@@ -85,70 +89,70 @@ void mathedValidate(LaTeXFeatures & features, MathParInset * par);
 
 LyXFont WhichFont(short type, int size)
 {
-    LyXFont f;
+       LyXFont f;
     
-      if (!Math_Fonts)
-       mathed_init_fonts();
-   
-   switch (type) {
-    case LM_TC_SYMB:        
-      f = Math_Fonts[2];
-      break;
-    case LM_TC_BSYM:        
-      f = Math_Fonts[2];
-      break;
-    case LM_TC_VAR:
-    case LM_TC_IT:
-      f = Math_Fonts[0];
-      break;
-    case LM_TC_BF:
-      f = Math_Fonts[3];
-      break;
-    case LM_TC_SF:
-      f = Math_Fonts[7];
-      break;
-    case LM_TC_CAL:
-      f = Math_Fonts[4];
-      break;
-    case LM_TC_TT:
-      f = Math_Fonts[5];
-      break;
-    case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
-    case LM_TC_TEXTRM:
-    case LM_TC_RM:    
-      f = Math_Fonts[6];
-      break;
-    default:
-      f = Math_Fonts[1];
-      break;   
-   }
-    
-    f.setSize(lfont_size);
-    
-    switch (size) {
-     case LM_ST_DISPLAY:     
-       if (type == LM_TC_BSYM) {
-           f.incSize();
-           f.incSize();
+       if (!Math_Fonts)
+               mathed_init_fonts();
+       
+       switch (type) {
+       case LM_TC_SYMB:             
+               f = Math_Fonts[2];
+               break;
+       case LM_TC_BSYM:             
+               f = Math_Fonts[2];
+               break;
+       case LM_TC_VAR:
+       case LM_TC_IT:
+               f = Math_Fonts[0];
+               break;
+       case LM_TC_BF:
+               f = Math_Fonts[3];
+               break;
+       case LM_TC_SF:
+               f = Math_Fonts[7];
+               break;
+       case LM_TC_CAL:
+               f = Math_Fonts[4];
+               break;
+       case LM_TC_TT:
+               f = Math_Fonts[5];
+               break;
+       case LM_TC_SPECIAL: //f = Math_Fonts[0]; break;
+       case LM_TC_TEXTRM:
+       case LM_TC_RM:    
+               f = Math_Fonts[6];
+               break;
+       default:
+               f = Math_Fonts[1];
+               break;   
        }
+       
+       f.setSize(lfont_size);
+       
+       switch (size) {
+       case LM_ST_DISPLAY:     
+               if (type == LM_TC_BSYM) {
+                       f.incSize();
+                       f.incSize();
+               }
        break;
-     case LM_ST_TEXT:
-       break;
-     case LM_ST_SCRIPT:
-       f.decSize();
-       break;
-     case LM_ST_SCRIPTSCRIPT:
-       f.decSize();
-       f.decSize();
-       break;
-     default:
-            lyxerr << "Mathed Error: wrong font size: " << size << endl;
+       case LM_ST_TEXT:
+               break;
+       case LM_ST_SCRIPT:
+               f.decSize();
+               break;
+       case LM_ST_SCRIPTSCRIPT:
+               f.decSize();
+               f.decSize();
        break;
-    }
-
-    if (type != LM_TC_TEXTRM) 
-      f.setColor(LColor::math);
-    return f;
+       default:
+               lyxerr << "Mathed Error: wrong font size: " << size << endl;
+               break;
+       }
+       
+       if (type != LM_TC_TEXTRM) 
+               f.setColor(LColor::math);
+       return f;
 }
 
 
@@ -188,95 +192,26 @@ void mathed_init_fonts() //removed 'static' because DEC cxx does not
 }
 
 
-LyXFont mathed_get_font(short type, int size)
-{
-       LyXFont f = WhichFont(type, size);
-       if (type == LM_TC_TEX) {
-               f.setLatex(LyXFont::ON);
-       }
-       return f;
-}
-
-
-int mathed_string_width(short type, int size, string const & s)
-{
-       string st;
-       if (MathIsBinary(type))
-               for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
-                       st += ' ';
-                       st += *it;
-                       st += ' ';
-               }
-       else
-               st = s;
 
-       LyXFont const f = WhichFont(type, size);
-       return lyxfont::width(st, f);
-}
 
-int mathed_char_width(short type, int size, byte c)
-{
-       if (MathIsBinary(type)) {
-               string s;
-               s += c;
-               return mathed_string_width(type, size, s);
-       }
-       else
-    return lyxfont::width(c, WhichFont(type, size));
-}
 
 
-int mathed_string_height(short type, int size, string const & s,
-                        int & asc, int & des)
-{
-       LyXFont font = WhichFont(type, size);
-       asc = des = 0;
-       for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
-               des = max(des, lyxfont::descent(*it, font));
-               asc = max(asc, lyxfont::ascent(*it, font));
-       }
-       return asc + des;
-}
 
 
-int mathed_char_height(short type, int size, byte c, int & asc, int & des)
-{
-   LyXFont font = WhichFont(type, size);
-   des = lyxfont::descent(c, font);
-   asc = lyxfont::ascent(c, font);
-   return asc + des;
-}
-
 
-// In a near future maybe we use a better fonts renderer
-void MathedInset::drawStr(Painter & pain, short type, int siz,
-                         int x, int y, string const & s)
-{
-       string st;
-       if (MathIsBinary(type))
-               for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
-                       st += ' ';
-                       st += *it;
-                       st += ' ';
-               }
-       else
-               st = s;
 
-       LyXFont const mf = mathed_get_font(type, siz);
-       pain.text(x, y, st, mf);
-}
 
 
 InsetFormula::InsetFormula(bool display)
 {
-  par = new MathParInset; // this leaks
-  //   mathcursor = 0;
-  disp_flag = display;
-  //label = 0;
-  if (disp_flag) {
-    par->SetType(LM_OT_PAR);
-    par->SetStyle(LM_ST_DISPLAY);
-  }
+       par = new MathParInset; // this leaks
+       //   mathcursor = 0;
+       disp_flag = display;
+       //label = 0;
+       if (disp_flag) {
+               par->SetType(LM_OT_PAR);
+               par->SetStyle(LM_ST_DISPLAY);
+       }
 }
 
 
@@ -1271,34 +1206,6 @@ InsetFormula::LocalDispatch(BufferView * bv,
 }
 
 
-void
-MathFuncInset::draw(Painter & pain, int x, int y)
-{ 
-       if (!name.empty() && name[0] > ' ') {
-               LyXFont font = WhichFont(LM_TC_TEXTRM, size);
-               font.setLatex(LyXFont::ON);
-               x += (lyxfont::width('I', font) + 3) / 4;
-               pain.text(x, y, name, font);
-       }
-}
-
-
-void MathFuncInset::Metrics() 
-{
-       //ln = (name) ? strlen(name): 0;
-       LyXFont  font = WhichFont(LM_TC_TEXTRM, size);
-       font.setLatex(LyXFont::ON);
-       if (name.empty()) {
-               width = df_width;
-               descent = df_des;
-               ascent = df_asc;
-       } else {
-               width = lyxfont::width(name, font)
-                       + lyxfont::width('I', font) / 2;
-               mathed_string_height(LM_TC_TEXTRM, size, name, ascent, descent);
-       }
-}
-
 
 static
 void mathedValidate(LaTeXFeatures & features, MathParInset * par)
diff --git a/src/mathed/marh_sqrtinset.h b/src/mathed/marh_sqrtinset.h
new file mode 100644 (file)
index 0000000..60a39b3
--- /dev/null
@@ -0,0 +1,26 @@
+
+#ifndef MATH_SQRTINSET_H
+#define MATH_SQRTINSET_H
+
+#include "math_parinset.h"
+
+///
+class MathSqrtInset: public MathParInset {
+public:
+       ///
+       MathSqrtInset(short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int x, int baseline);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       bool Inside(int, int);
+private:
+       ///
+       int hmax, wbody;
+};
+#endif
diff --git a/src/mathed/math_accentinset.C b/src/mathed/math_accentinset.C
new file mode 100644 (file)
index 0000000..ac0fd1a
--- /dev/null
@@ -0,0 +1,114 @@
+#include <config.h>
+
+#include "math_accentinset.h"
+#include "support.h"
+#include "math_parser.h"
+
+
+MathAccentInset::MathAccentInset(byte cx, MathedTextCodes f, int cd, short st)
+       : MathedInset("", LM_OT_ACCENT, st), c(cx), fn(f), code(cd)
+{
+       inset = 0;
+}
+
+
+MathAccentInset::MathAccentInset(MathedInset *ins, int cd, short st)
+       : MathedInset("", LM_OT_ACCENT, st),
+         c(0), fn(LM_TC_MIN), code(cd), inset(ins) {}
+
+
+MathAccentInset::~MathAccentInset()
+{
+       delete inset;
+}
+
+
+MathedInset * MathAccentInset::Clone()
+{   
+       MathAccentInset * p;
+       
+       if (inset) 
+               p = new MathAccentInset(inset->Clone(), code, GetStyle());
+       else
+               p = new MathAccentInset(c, fn, code, GetStyle());
+       
+       return p;
+}
+
+
+void
+MathAccentInset::draw(Painter & pain, int x, int y)
+{
+       int dw = width - 2;
+       
+       if (inset) 
+               inset->draw(pain, x, y);
+       else {
+               string s;
+               s += c;
+               drawStr(pain, fn, size, x, y, s);
+       }
+       x += (code == LM_not) ? (width-dw) / 2 : 2;
+       mathed_draw_deco(pain, x, y - dy, dw, dh, code);
+}
+
+
+void
+MathAccentInset::Metrics()
+{
+       if (inset) {
+               inset->Metrics();
+               ascent = inset->Ascent();
+               descent = inset->Descent();
+               width = inset->Width();
+               dh = ascent;
+       } else {
+               mathed_char_height(fn, size, c, ascent, descent);
+               width = mathed_char_width(fn, size, c);
+               dh = (width-2)/2; 
+       }
+       if (code == LM_not) {
+               ascent += dh;
+               descent += dh;
+               dh = Height();
+       } else 
+               ascent += dh+2;
+       
+       dy = ascent;
+//    if (MathIsBinary(fn))
+//     width += 2*mathed_char_width(fn, size, ' ');    
+}
+
+
+void MathAccentInset::Write(ostream & os, bool fragile)
+{
+       latexkeys * l = lm_get_key_by_id(code, LM_TK_ACCENT);
+       os << '\\' << l->name;
+       if (code!= LM_not)
+               os << '{';
+       else
+               os << ' ';
+       
+       if (inset) {
+               inset->Write(os, fragile);
+       } else {
+               if (fn>= LM_TC_RM && fn <= LM_TC_TEXTRM) {
+                       os << '\\'
+                          << math_font_name[fn - LM_TC_RM]
+                          << '{';
+               }
+               if (MathIsSymbol(fn)) {
+                       latexkeys * l = lm_get_key_by_id(c, LM_TK_SYM);
+                       if (l) {
+                               os << '\\' << l->name << ' ';
+                       }
+               } else
+                       os << char(c);
+               
+               if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM)
+                       os << '}';
+       }
+       
+       if (code!= LM_not)
+               os << '}';
+}
diff --git a/src/mathed/math_accentinset.h b/src/mathed/math_accentinset.h
new file mode 100644 (file)
index 0000000..b6d29b4
--- /dev/null
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+#ifndef MATH_ACCENTINSET_H
+#define MATH_ACCENTINSET_H
+
+#include "math_inset.h"
+
+/// Accents
+class MathAccentInset: public MathedInset {
+public:
+       ///
+       MathAccentInset(byte, MathedTextCodes, int, short st = LM_ST_TEXT);
+       ///
+       MathAccentInset(MathedInset *, int, short st = LM_ST_TEXT);
+       ///
+       ~MathAccentInset();
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       int getAccentCode() const { return code; }
+       
+protected:
+       ///
+       byte c;
+       ///
+       MathedTextCodes fn;
+       ///
+       int code;
+       ///
+       MathedInset * inset;
+       ///
+       int dh, dy;
+};
+#endif
diff --git a/src/mathed/math_bigopinset.C b/src/mathed/math_bigopinset.C
new file mode 100644 (file)
index 0000000..5e5823d
--- /dev/null
@@ -0,0 +1,97 @@
+#include <config.h>
+
+#include "math_bigopinset.h"
+#include "LColor.h"
+#include "Painter.h"
+#include "mathed/support.h"
+
+bool MathBigopInset::GetLimits() const 
+{  
+       // Default case
+       if (lims < 0) {
+               return sym != LM_int && sym != LM_oint && GetStyle() == LM_ST_DISPLAY;
+       } 
+       
+       // Custom 
+       return lims > 0;
+} 
+
+
+void MathBigopInset::SetLimits(bool ls) 
+{  
+       lims = ls ? 1 : 0; 
+}
+
+
+MathBigopInset::MathBigopInset(string const & nam, int id, short st)
+       : MathedInset(nam, LM_OT_BIGOP, st), sym(id)
+{
+       lims = -1;
+}
+
+
+MathedInset * MathBigopInset::Clone()
+{
+       return new MathBigopInset(name, sym, GetStyle());
+}
+
+
+void
+MathBigopInset::draw(Painter & pain, int x, int y)
+{
+       string s;
+       short t;
+       
+       if (sym < 256 || sym == LM_oint) {
+               s += (sym == LM_oint) ? LM_int : sym;
+               t = LM_TC_BSYM;
+       } else {
+               s = name;
+               t = LM_TC_TEXTRM;
+       }
+       if (sym == LM_oint) {
+               pain.arc(x, y - 5 * width / 4, width, width, 0, 360*64,
+                        LColor::mathline);
+               ++x;
+       }
+       pain.text(x, y, s, mathed_get_font(t, size));
+}
+
+
+void
+MathBigopInset::Metrics()
+{
+       //char c;
+       string s;
+       short t;
+       
+       if (sym < 256 || sym == LM_oint) {
+               char c = (sym == LM_oint) ? LM_int: sym;
+               s += c;
+               t = LM_TC_BSYM;
+       } else {
+               s = name;
+               t = LM_TC_TEXTRM;
+       }
+       mathed_string_height(t, size, s, ascent, descent);
+       width = mathed_string_width(t, size, s);
+       if (sym == LM_oint) width += 2;
+}
+
+
+void MathBigopInset::Write(ostream & os, bool /* fragile */)
+{
+       bool limp = GetLimits();
+       
+       os << '\\' << name;
+       
+       if (limp && !(sym != LM_int && sym != LM_oint
+                     && (GetStyle() == LM_ST_DISPLAY)))
+               os << "\\limits ";
+       else 
+               if (!limp && (sym != LM_int && sym != LM_oint
+                             && (GetStyle() == LM_ST_DISPLAY)))
+                       os << "\\nolimits ";
+               else 
+                       os << ' ';
+}
diff --git a/src/mathed/math_bigopinset.h b/src/mathed/math_bigopinset.h
new file mode 100644 (file)
index 0000000..92816f8
--- /dev/null
@@ -0,0 +1,30 @@
+// -*- C++ -*-
+#ifndef MATH_BIGOPINSET_H
+#define MATH_BIGOPINSET_H
+
+#include "math_inset.h"
+
+/// big operators
+class MathBigopInset: public MathedInset {
+public:
+       ///
+       MathBigopInset(string const &, int, short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       inline bool GetLimits() const;
+       ///
+       inline void SetLimits(bool);
+protected:
+       ///
+       int lims;
+       ///
+       int sym;   
+};
+#endif
index f05d9eb291c3b75d031cec01c7bc83333fd1d56b..bd8cd8e5097e10b1add78e99ed17fc8515a4ba78 100644 (file)
 #include "debug.h"
 #include "LColor.h"
 #include "Painter.h"
+#include "math_matrixinset.h"
+#include "math_rowst.h"
+#include "math_spaceinset.h"
+#include "math_funcinset.h"
+#include "math_bigopinset.h"
+#include "math_fracinset.h"
+#include "math_decorationinset.h"
+#include "math_dotsinset.h"
+#include "math_accentinset.h"
 
 static MathedArray * selarray = 0;
 
index 0ca9ffdf14574198dae025e2b06b0492b96135e8..5f6721553df29d2dcd4706600660d1b36c947253 100644 (file)
 #endif
 
 #include "math_iter.h" 
-#include "math_inset.h"
+//#include "math_inset.h"
+#include "math_xiter.h"
+
+class MathFuncInset;
 
 
 /// This is the external interface of Mathed's subkernel
 class MathedCursor {
- public:
-    ///
-    explicit
-    MathedCursor(MathParInset * p);
-    ///
-    void Insert(byte, MathedTextCodes t = LM_TC_MIN);
-    ///
-    void Insert(MathedInset *, int t = LM_TC_INSET);
-    ///
-    void Home();
-    ///
-    void End();
-    ///
-    bool Right(bool sel = false);
-    ///
-    bool Left(bool sel = false);
-    ///
-    bool Up(bool sel = false);
-    ///
-    bool Down(bool sel = false);
-    ///
-    bool Pop();
-    ///
-    bool Push();
-    /// Pull out an argument from its container inset
-    bool pullArg();
-    ///
-    void draw(Painter &, int x, int y);
-    ///
-    void Redraw(Painter &);
-    ///
-    void Delete();
-    ///
-    void DelLine();
-    ///
-    void SetPos(int, int);
-    ///
-    void GetPos(int & x, int & y) { cursor->GetPos(x, y); }
-    ///
-    short GetFCode() { return cursor->FCode(); }
-    ///
-    MathParInset * GetPar() { return par; }
-    ///
-    MathParInset * getCurrentPar() const { return cursor->p; }
-    ///
-    void SetPar(MathParInset *);
-    ///
-    void Interpret(string const &);
-    ///
-    void SetSize(short);
-    ///
-    void setNumbered();
-    ///
-    void setLabel(string const &);
-    ///
-    string const & getLabel() const {
-           return cursor->getLabel();
-    }
-    ///
-    bool Limits();
-    /// Set accent: if argument = 0 it's considered consumed 
-    void setAccent(int ac = 0);
-    /// Returns last accent
-    int getAccent() const;
-    ///
-    bool IsEnd() const { return !cursor->OK(); }
-    // Macro mode methods
-    ///
-    void MacroModeOpen();
-    ///
-    void MacroModeClose();
-    ///
-    bool InMacroMode() { return macro_mode; }
-    
-    // Local selection methods
-    ///
-    bool Selection() { return selection; }
-    ///
-    void SelCopy();
-    ///
-    void SelCut();
-    ///
-    void SelDel();
-    ///
-    void SelPaste();
-    ///
-    void SelStart();
-    ///
-    void SelClear();
-    ///
-    void SelBalance();
-    ///
-    void SelGetArea(int ** xp, int ** yp, int & n);
-    ///
-    void clearLastCode() { lastcode = LM_TC_MIN; }
-    ///
-    void setLastCode(MathedTextCodes t) { lastcode = t; }
-    ///
-    void toggleLastCode(MathedTextCodes t);
-    ///
-    MathedTextCodes getLastCode() const { return lastcode; }
-    
- protected:
-    ///
-    bool macro_mode;
-    ///
-    void MacroModeBack();
-    ///
-    void MacroModeInsert(char);
-    
-    // Selection stuff
-    ///
-    bool selection;
-    ///
-    int  selpos;
-    ///
-    MathedXIter cursel, * anchor;
-    ///
+public:
+       ///
+       explicit
+       MathedCursor(MathParInset * p);
+       ///
+       void Insert(byte, MathedTextCodes t = LM_TC_MIN);
+       ///
+       void Insert(MathedInset *, int t = LM_TC_INSET);
+       ///
+       void Home();
+       ///
+       void End();
+       ///
+       bool Right(bool sel = false);
+       ///
+       bool Left(bool sel = false);
+       ///
+       bool Up(bool sel = false);
+       ///
+       bool Down(bool sel = false);
+       ///
+       bool Pop();
+       ///
+       bool Push();
+       /// Pull out an argument from its container inset
+       bool pullArg();
+       ///
+       void draw(Painter &, int x, int y);
+       ///
+       void Redraw(Painter &);
+       ///
+       void Delete();
+       ///
+       void DelLine();
+       ///
+       void SetPos(int, int);
+       ///
+       void GetPos(int & x, int & y) { cursor->GetPos(x, y); }
+       ///
+       short GetFCode() { return cursor->FCode(); }
+       ///
+       MathParInset * GetPar() { return par; }
+       ///
+       MathParInset * getCurrentPar() const { return cursor->p; }
+       ///
+       void SetPar(MathParInset *);
+       ///
+       void Interpret(string const &);
+       ///
+       void SetSize(short);
+       ///
+       void setNumbered();
+       ///
+       void setLabel(string const &);
+       ///
+       string const & getLabel() const {
+               return cursor->getLabel();
+       }
+       ///
+       bool Limits();
+       /// Set accent: if argument = 0 it's considered consumed 
+       void setAccent(int ac = 0);
+       /// Returns last accent
+       int getAccent() const;
+       ///
+       bool IsEnd() const { return !cursor->OK(); }
+       // Macro mode methods
+       ///
+       void MacroModeOpen();
+       ///
+       void MacroModeClose();
+       ///
+       bool InMacroMode() { return macro_mode; }
+       
+       // Local selection methods
+       ///
+       bool Selection() { return selection; }
+       ///
+       void SelCopy();
+       ///
+       void SelCut();
+       ///
+       void SelDel();
+       ///
+       void SelPaste();
+       ///
+       void SelStart();
+       ///
+       void SelClear();
+       ///
+       void SelBalance();
+       ///
+       void SelGetArea(int ** xp, int ** yp, int & n);
+       ///
+       void clearLastCode() { lastcode = LM_TC_MIN; }
+       ///
+       void setLastCode(MathedTextCodes t) { lastcode = t; }
+       ///
+       void toggleLastCode(MathedTextCodes t);
+       ///
+       MathedTextCodes getLastCode() const { return lastcode; }
+       
+protected:
+       ///
+       bool macro_mode;
+       ///
+       void MacroModeBack();
+       ///
+       void MacroModeInsert(char);
+       
+       // Selection stuff
+       ///
+       bool selection;
+       ///
+       int  selpos;
+       ///
+       MathedXIter cursel;
+       ///
+       MathedXIter * anchor;
+       ///
 //    MathedArray *selarray; 
-    ///
-    bool is_visible;
-    ///
-    long unsigned win;
-    ///
-    MathParInset * par;
-    ///
-    MathedXIter * cursor;
-    ///
-    int xc, yc;
-    ///
-    void doAccent(byte c, MathedTextCodes t);
-    ///
-    void doAccent(MathedInset * p);
-    ///
-    int accent;
-       ///
-    int nestaccent[8];
-       ///
-    MathedTextCodes lastcode;
-
- private:
-    ///
-    MathFuncInset * imacro;
+       ///
+       bool is_visible;
+       ///
+       long unsigned win;
+       ///
+       MathParInset * par;
+       ///
+       MathedXIter * cursor;
+       ///
+       int xc;
+       ///
+       int yc;
+       ///
+       void doAccent(byte c, MathedTextCodes t);
+       ///
+       void doAccent(MathedInset * p);
+       ///
+       int accent;
+       ///
+       int nestaccent[8];
+       ///
+       MathedTextCodes lastcode;
+       
+private:
+       ///
+       MathFuncInset * imacro;
 };
 
-
-//--------------------   Inline Functions  -------------------------// 
-
-
 #endif
diff --git a/src/mathed/math_decorationinset.C b/src/mathed/math_decorationinset.C
new file mode 100644 (file)
index 0000000..6e38a1c
--- /dev/null
@@ -0,0 +1,73 @@
+#include <config.h>
+
+#include "math_decorationinset.h"
+#include "math_iter.h"
+#include "mathed/support.h"
+#include "math_parser.h"
+
+
+bool MathDecorationInset::GetLimits() const
+{ 
+       return deco == LM_underbrace || deco == LM_overbrace;
+}    
+
+
+MathDecorationInset::MathDecorationInset(int d, short st)
+       : MathParInset(st, "", LM_OT_DECO), deco(d)
+{
+   upper = (deco!= LM_underline && deco!= LM_underbrace);
+}
+
+
+MathedInset * MathDecorationInset::Clone()
+{   
+   MathDecorationInset * p = new MathDecorationInset(deco, GetStyle());
+   MathedIter it(array);
+   p->SetData(it.Copy());
+   return p;
+}
+
+
+void
+MathDecorationInset::draw(Painter & pain, int x, int y)
+{ 
+       MathParInset::draw(pain, x + (width - dw) / 2, y);
+       mathed_draw_deco(pain, x, y + dy, width, dh, deco);
+}
+
+
+void
+MathDecorationInset::Metrics()
+{
+       int h = 2*mathed_char_height(LM_TC_VAR, size, 'I', ascent, descent);  
+       MathParInset::Metrics();
+       int w = Width()+4;
+       if (w<16) w = 16;
+       dh = w/5;
+       if (dh>h) dh = h;
+       
+       if (upper) {
+               ascent += dh+2;
+               dy = -ascent;
+       } else {
+               dy = descent+2;
+               descent += dh+4;
+       }
+       dw = width;
+       width = w;
+}
+
+
+void MathDecorationInset::Write(ostream & os, bool fragile)
+{
+       latexkeys * l = lm_get_key_by_id(deco, LM_TK_WIDE);
+       if (fragile &&
+           (strcmp(l->name, "overbrace") == 0 ||
+            strcmp(l->name, "underbrace") == 0 ||
+            strcmp(l->name, "overleftarrow") == 0 ||
+            strcmp(l->name, "overrightarrow") == 0))
+               os << "\\protect";
+       os << '\\' << l->name << '{';
+       MathParInset::Write(os, fragile);  
+       os << '}';
+}
diff --git a/src/mathed/math_decorationinset.h b/src/mathed/math_decorationinset.h
new file mode 100644 (file)
index 0000000..ea8c709
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MATH_DECORATIONINSET_H
+#define MATH_DECORATIONINSET_H
+
+#include "math_parinset.h"
+
+/// Decorations over (below) a math object
+class MathDecorationInset: public MathParInset {
+public:
+       ///
+       MathDecorationInset(int, short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       inline bool GetLimits() const;
+protected:
+       ///
+       int deco;
+       ///
+       bool upper;
+       ///
+       int dw, dh, dy;
+};
+#endif
index 6819ea540d6e20e8e7045211212366bfc60c3b33..549159418342088ad663a64e256dca8d2294e58f 100644 (file)
 #include "LString.h"
 #include "debug.h"
 
-#include "array.h"
+//#include "array.h"
 
+class MathedArray;
 class Painter;
 
+#ifndef byte
+#define byte unsigned char
+#endif
+
 ///
 enum math_align {
        ///
@@ -209,91 +214,6 @@ enum MathedBinaryTypes {
 
 class MathParInset;
 
-/** Abstract base class for all math objects.
-    A math insets is for use of the math editor only, it isn't a
-    general LyX inset. It's used to represent all the math objects.
-    The formulaInset (a LyX inset) encapsulates a math inset.
- */
-class MathedInset  {
- public: 
-    /// A math inset has a name (usually its LaTeX name), type and font-size
-    MathedInset(string const & nm, short ot, short st);
-    ///
-    explicit
-    MathedInset(MathedInset *);
-    ///
-    virtual ~MathedInset() {}
-
-    /// Draw the object
-    virtual void draw(Painter &, int x, int baseline) = 0;     
-
-    /// Write LaTeX and Lyx code
-    virtual void Write(std::ostream &, bool fragile) = 0;
-
-    /// Reproduces itself
-    virtual MathedInset * Clone() = 0;
-   
-    /// Compute the size of the object
-    virtual void Metrics() = 0; 
-    /// 
-    virtual int Ascent() const { return ascent; }
-    ///
-    virtual int Descent() const { return descent; }
-    ///
-    virtual int Width() const { return width; }
-    ///
-    virtual int Height() const { return ascent + descent; }
-    
-    ///
-    virtual bool GetLimits() const { return false; }
-    ///
-    virtual void SetLimits(bool) {}   
-   
-    ///
-    string const & GetName() const { return name; }
-    ///
-    short GetType() const { return objtype; }
-    ///
-    short GetStyle() const { return size; }
-          
-    //Man:  Avoid to use these functions if it's not strictly necessary 
-    ///
-    virtual void  SetType(short t) { objtype = t; }
-    ///
-    virtual void  SetStyle(short st) { size = st; } // Metrics();
-    ///
-    virtual void  SetName(string const & n) { name = n; }
-    ///
-    static int workWidth;
- protected:
-    ///
-    string name;
-    ///
-    short objtype;
-    ///
-    int width;
-    ///
-    int ascent;
-    ///
-    int descent;
-    ///
-    short size;
-    /// Default metrics
-    static int df_asc;
-    ///
-    static int df_des;
-    ///
-    static int df_width;
-    /// In a near future maybe we use a better fonts renderer than X
-    void drawStr(Painter &, short, int, int, int, string const &);
-    ///
-    friend class MathedCursor;
-    ///
-    friend void mathed_init_fonts();
-};
-
-struct MathedRowSt;
-
 
 /// Paragraph permissions
 enum MathedParFlag {
@@ -313,211 +233,6 @@ enum MathedParFlag {
 };
 
 
-/** The math paragraph base class, base to all editable math objects */
-class MathParInset: public MathedInset  {
- public: 
-    ///
-    MathParInset(short st = LM_ST_TEXT, string const & nm = string(),
-                short ot = LM_OT_MIN);
-    ///
-    explicit
-    MathParInset(MathParInset *);
-    ///
-    virtual ~MathParInset();
-    ///
-    virtual MathedInset * Clone();
-
-    /// Draw the object on a drawable
-    virtual void draw(Painter &, int x, int baseline);
-
-    /// Write LaTeX code
-    virtual void Write(std::ostream &, bool fragile);
-
-    ///
-    virtual void Metrics();
-    ///
-    virtual void UserSetSize(short);
-    /// Data is stored in a LyXArray
-    virtual void SetData(MathedArray *);
-    ///
-    virtual MathedArray * GetData() { return array; }
-
-    /// Paragraph position
-    virtual void GetXY(int &, int &) const;
-    ///
-    virtual void setXY(int x, int y) { xo = x;  yo = y; }
-    ///
-    virtual void SetFocus(int, int) {}
-    ///
-    virtual bool Inside(int, int);   
-   
-    // Tab stuff used by Matrix.
-    ///
-    virtual void SetAlign(char, string const &) {}
-    ///
-    virtual int GetColumns() const { return 1; }
-    ///
-    virtual int GetRows() const { return 1; }
-    ///
-    virtual bool isMatrix() const { return false; }
-    // Vertical switching
-    ///
-    virtual bool setArgumentIdx(int i) { return (i == 0); }
-    ///
-    virtual bool setNextArgIdx() { return false; }
-    ///
-    virtual int getArgumentIdx() const { return 0; }
-    ///
-    virtual int getMaxArgumentIdx() const { return 0; }
-    ///
-    virtual void SetStyle(short);
-    ///
-    virtual MathedRowSt * getRowSt() const { return 0; }
-    ///
-    virtual void setRowSt(MathedRowSt *) {}
-    ///
-    virtual bool Permit(short f) const { return bool(f & flag); }
-    
- protected:
-    /// Paragraph data is stored here
-    MathedArray * array;
-    /// Cursor start position
-    int xo;
-    ///
-    int yo;
-    /// 
-    short flag;
-
- private:
-    ///
-    virtual void setFlag(MathedParFlag f) { flag |= f; }
-    ///
-    friend class InsetFormula;
-    ///
-    friend class MathedXIter;
-    ///
-    friend class MathedCursor;
-    ///
-    friend MathedArray * mathed_parse(unsigned flags = 0,
-                                      MathedArray * a = 0,
-                                      MathParInset ** p = 0);
-};
-
-
-/** The physical structure of a row and aditional information is stored here.
-    It allows to manage the extra info independently of the paragraph data.  
-    Only used for multiline paragraphs.
- */
-struct MathedRowSt
-{
-       ///
-       typedef vector<int> Widths;
-       
-       ///
-       explicit
-       MathedRowSt(int n)
-               : asc_(0), desc_(0), y_(0), widths_(n + 1, 0),
-                 numbered_(true), next_(0)
-               {}
-       /// Should be const but...
-       MathedRowSt * getNext() const  { return next_; }
-       /// ...we couldn't use this.
-       void setNext(MathedRowSt * n) { next_ = n; }
-       ///
-       string const & getLabel() const { return label_; }
-       ///
-       bool isNumbered() const { return numbered_; }
-       ///
-       int  getBaseline() const { return y_; }
-       ///
-       void setBaseline(int b) { y_ = b; }
-       ///
-       int ascent() const { return asc_; }
-       ///
-       int descent() const { return desc_; }
-       ///
-       void ascent(int a) { asc_ = a; }
-       ///
-       void descent(int d) { desc_ = d; }
-       ///
-       int  getTab(int i) const { return widths_[i]; }
-       /// 
-       void setLabel(string const & l) { label_ = l; }
-       ///
-       void setNumbered(bool nf) { numbered_ = nf; }
-       ///
-       void setTab(int i, int t) { widths_[i] = t; }
-private:
-       /// Vericals 
-       int asc_;
-       int desc_;
-       int y_;
-       /// widths 
-       Widths widths_;
-       /// 
-       string label_;
-       ///
-       bool numbered_;
-       ///
-       MathedRowSt * next_;
-};
-
-
-/** Multiline math paragraph base class.
-    This is the base to all multiline editable math objects
-    like array and eqnarray. 
- */
-class MathMatrixInset: public MathParInset {
- public: 
-    ///
-    explicit
-    MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
-    ///
-    explicit
-    MathMatrixInset(MathMatrixInset *);
-    ///
-    MathedInset * Clone();
-    ///
-    virtual ~MathMatrixInset();
-    ///
-    void draw(Painter &, int, int);
-    ///
-    void Write(std::ostream &, bool fragile);
-    ///
-    void Metrics();
-    ///
-    void SetData(MathedArray *);
-    ///
-    void SetAlign(char, string const &);
-    ///
-    int GetColumns() const { return nc; }
-    ///
-    int GetRows() const { return nr; }
-    ///
-    virtual bool isMatrix() const { return true; }
-
-    /// Use this to manage the extra information independently of paragraph
-    MathedRowSt * getRowSt() const { return row; }
-    ///
-    void setRowSt(MathedRowSt * r) { row = r; }
-    
- protected:
-    ///  Number of columns & rows
-    int nc;
-    ///
-    int nr;
-    /// tab sizes
-    std::vector<int> ws_;   
-    /// 
-    char v_align; // add approp. type
-    ///
-       //std::vector<char> h_align;
-       string h_align; // a vector would perhaps be more correct
-    /// Vertical structure
-    MathedRowSt * row;
-
-};
 
 
 
@@ -608,51 +323,6 @@ bool MathIsSymbol(short x) {
 }
      
 
-inline
-MathedInset::MathedInset(string const & nm, short ot, short st):
-  name(nm), objtype(ot), size(st) 
-{
-   width = ascent = descent = 0;
-}
-
-
-inline
-bool MathParInset::Inside(int x, int y) 
-{
-  return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
-}
-
-
-inline
-void MathParInset::GetXY(int & x, int & y) const
-{
-   x = xo; y = yo;
-}
-
-
-inline
-void MathParInset::UserSetSize(short sz)
-{
-   if (sz >= 0) {
-       size = sz;      
-       flag = flag & ~LMPF_FIXED_SIZE;
-   }
-}
-
-
-inline
-void MathParInset::SetStyle(short sz) 
-{
-    if (Permit(LMPF_FIXED_SIZE)) {
-       if (Permit(LMPF_SCRIPT)) 
-         sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
-       if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
-           ++sz;
-       } 
-       MathedInset::SetStyle(sz);
-    }
-}
-
 inline
 bool is_eqn_type(short int type)
 {
index 55bd9dbeb16439b0be774eaa8c2bbde7946267d7..adb70fdd1f0d418a5533677196a8656e35ba8330 100644 (file)
@@ -24,6 +24,8 @@
 #include "math_inset.h"
 #include "LColor.h"
 #include "Painter.h"
+#include "math_deliminset.h"
+#include "mathed/support.h"
 
 using std::sort;
 using std::lower_bound;
@@ -34,561 +36,30 @@ using std::endl;
  * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4= square polyline
  */
 
-static float parenth[] = {
-  2.0, 13.0,
-  0.9930, 0.0071,  0.7324, 0.0578,  0.5141, 0.1126,  0.3380, 0.1714,
-  0.2183, 0.2333,  0.0634, 0.3621,  0.0141, 0.5000,  0.0563, 0.6369,
-  0.2113, 0.7647,  0.3310, 0.8276,  0.5070, 0.8864,  0.7254, 0.9412,
-  0.9930, 0.9919,
-  0.0   
-};
 
-static float parenthHigh[] = {
-    2.0, 13.0, 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772, 0.2540, 
-    0.1278, 0.1746, 0.1966, 0.0952, 0.3300, 0.0950, 0.5000, 0.0952, 0.6700, 
-    0.1746, 0.8034, 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677, 0.9840, 
-    0.9986, 0.0 
-};
 
-static float brace[] = {
-  2.0, 21.0,
-  0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243, 0.5819, 0.0527,
-  0.4859, 0.0892, 0.4463, 0.1278, 0.4463, 0.3732, 0.4011, 0.4199,
-  0.2712, 0.4615, 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
-  0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268, 0.4463, 0.8722,
-  0.4859, 0.9108, 0.5819, 0.9473, 0.7458, 0.9757, 0.9379, 0.9980,
-  0.9492, 0.9980,
-  0.0
-};
+//inline
+//int odd(int x) { return ((x) & 1); }
 
-static float arrow[] = {
-   4, 7,
-   0.015, 0.7500,  0.2, 0.6,  0.35, 0.35,  0.5, 0.05,
-   0.65, 0.35,  0.8, 0.6,  0.95, 0.7500,
-   3, 0.5, 0.15,  0.5, 0.95,
-   0.0 
-};
+//typedef float matriz_data[2][2];
 
-static float Arrow[] = {
-   4, 7,
-   0.015, 0.7500,  0.2, 0.6,  0.35, 0.35,  0.5, 0.05,
-   0.65, 0.35,  0.8, 0.6,  0.95, 0.7500,
-   3, 0.35, 0.5, 0.35, 0.95,
-   3, 0.65, 0.5, 0.65, 0.95,
-   0.0
-};
+//const matriz_data MATIDEN= { {1, 0}, {0, 1}};
 
-static float udarrow[] = {
-   2, 3,
-   0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
-   2, 3,
-   0.015, 0.75,  0.5, 0.95, 0.95, 0.75,  
-   1, 0.5, 0.2,  0.5, 0.8,
-   0.0 
-};
+//extern int mathed_char_width(short type, int style, byte c);
+//extern int mathed_char_height(short, int, byte, int &, int &);
 
-static float Udarrow[] = {
-   2, 3,
-   0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
-   2, 3,
-   0.015, 0.75,  0.5, 0.95, 0.95, 0.75,  
-   1, 0.35, 0.2, 0.35, 0.8,
-   1, 0.65, 0.2, 0.65, 0.8,
-   0.0 
-};
+//#define mateq(m1, m2)  memcpy(m1, m2, sizeof(matriz_data))
 
-static float brack[] = {
-   2.0, 4,
-   0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
-   0.0
-};
 
-static float corner[] = {
-   2.0, 3,
-   0.95, 0.05,  0.05, 0.05,  0.05, 0.95,
-   0.0
-};
 
-static float angle[] = {
-   2.0, 3,
-   1, 0,  0.05, 0.5,  1, 1,
-   0.0
-};
 
-static float slash[] = {
-   1, 0.95, 0.05,  0.05, 0.95, 
-   0.0
-};
 
-static float hline[] = {
-   1, 0.05, 0.5,  0.95, 0.5, 
-   0.0
-};
 
 
-static float hline2[] = {
-   1, 0.1, 0.5,  0.3, 0.5,
-   1, 0.7, 0.5,  0.9, 0.5,
-   0.0
-}; 
 
-static float hline3[] = {
-   1, 0.1, 0,  0.15, 0,
-   1, 0.475, 0,  0.525, 0,
-   1, 0.85, 0,  0.9, 0,  
-   0.0
-};
 
 
-static float dline3[] = {
-   1, 0.1, 0.1,  0.15, 0.15,
-   1, 0.475, 0.475,  0.525, 0.525,
-   1, 0.85, 0.85,  0.9, 0.9,
-   0.0
-};     
-
-static float hlinesmall[] = {
-   1, 0.4, 0.5,  0.6, 0.5, 
-   0.0
-};
-
-static float vert[] = {
-   1, 0.5, 0.05,  0.5, 0.95, 
-   0.0
-};
-
-static float Vert[] = {
-   1, 0.3, 0.05,  0.3, 0.95, 
-   1, 0.7, 0.05,  0.7, 0.95,
-   0.0
-};
-
-static float tilde[] = {
-   2.0, 4,
-   0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
-   0.0
-};
-
-struct math_deco_struct {
-       int code;
-       float * data;
-       int angle;
-};
-
-static
-math_deco_struct math_deco_table[] = {   
-
-   // Decorations
-  { LM_widehat, &angle[0], 3 },
-  { LM_widetilde, &tilde[0], 0 },
-  { LM_underline, &hline[0], 0 },
-  { LM_overline, &hline[0], 0 },
-  { LM_underbrace, &brace[0], 1 },
-  { LM_overbrace,  &brace[0], 3 },
-  { LM_overleftarrow, &arrow[0], 1 },
-  { LM_overightarrow, &arrow[0], 3 },
-     
-  // Delimiters
-  { '(', &parenth[0], 0 },
-  { ')', &parenth[0], 2 },
-  { '{', &brace[0], 0 },
-  { '}', &brace[0], 2 },
-  { '[', &brack[0], 0 },
-  { ']', &brack[0], 2 },
-  { '|', &vert[0], 0 },
-  { '/', &slash[0], 0 },
-  { LM_Vert, &Vert[0], 0 },
-  { LM_backslash, &slash[0], 1 },
-  { LM_langle, &angle[0], 0 },
-  { LM_lceil, &corner[0], 0 }, 
-  { LM_lfloor, &corner[0], 1 },  
-  { LM_rangle, &angle[0], 2 }, 
-  { LM_rceil, &corner[0], 3 }, 
-  { LM_rfloor, &corner[0], 2 },
-  { LM_downarrow, &arrow[0], 2 },
-  { LM_Downarrow, &Arrow[0], 2 }, 
-  { LM_uparrow, &arrow[0], 0 },
-  { LM_Uparrow, &Arrow[0], 0 },
-  { LM_updownarrow, &udarrow[0], 0 },
-  { LM_Updownarrow, &Udarrow[0], 0 },   
-
-  // Accents   
-  { LM_ddot, &hline2[0], 0 },
-  { LM_hat, &angle[0], 3 },
-  { LM_grave, &slash[0], 1 },
-  { LM_acute, &slash[0], 0 },
-  { LM_tilde, &tilde[0], 0 },
-  { LM_bar, &hline[0], 0 },
-  { LM_dot, &hlinesmall[0], 0 },
-  { LM_check, &angle[0], 1 },
-  { LM_breve, &parenth[0], 1 },
-  { LM_vec, &arrow[0], 3 },
-  { LM_not, &slash[0], 0 },  
-
-  // Dots
-  { LM_ldots, &hline3[0], 0 }, 
-  { LM_cdots, &hline3[0], 0 },
-  { LM_vdots, &hline3[0], 1 },
-  { LM_ddots, &dline3[0], 0 }
-};
-
-
-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 &);
-
-#define mateq(m1, m2)  memcpy(m1, m2, sizeof(matriz_data))
-
-class Matriz {
- public: 
-   Matriz() { mateq(m, MATIDEN); }
-   void rota(int);
-   void escala(float, float);
-   void transf(float, float, float &, float &);
-   
- protected:
-   matriz_data m;
-   void matmat(matriz_data & a);
-};
-
-
-void Matriz::rota(int code)
-{
-   float cs, sn;
-   
-   matriz_data r;
-   mateq(r, MATIDEN);
-   cs = (odd(code)) ? 0: 1 - code;
-   sn = (odd(code)) ? 2 - code: 0;
-   r[0][0] = cs;         r[0][1] = sn;
-   r[1][0] = -r[0][1];   r[1][1] = r[0][0];
-   matmat(r);
-}
-
-void Matriz::escala(float x, float y)
-{
-   matriz_data s;
-   mateq(s, MATIDEN);
-   s[0][0] = x;  s[1][1] = y;
-   matmat(s);
-}
-
-
-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];
-   }
-   mateq(m, c);
-}
-
-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;
-}
-
-
-struct math_deco_compare {
-       /// for use by sort and lower_bound
-       inline
-       int operator()(math_deco_struct const & a,
-                      math_deco_struct const & b) const {
-               return a.code < b.code;
-       }
-};
-
-
-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)
-{
-       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 search_elem = { code, 0, 0 };
-       
-       math_deco_struct * res =
-               lower_bound(math_deco_table,
-                           math_deco_table + math_deco_table_size,
-                           search_elem, 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 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 = 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);
-   
-       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(Painter & pain, int x, int y)
-{ 
-       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()
-{
-   MathParInset::Metrics();
-   int d;
-   
-   mathed_char_height(LM_TC_CONST, size, 'I', d, dh);
-   dh /= 2;
-   ascent += 2 + dh;
-   descent += 2 - dh;
-   dw = Height()/5;
-   if (dw > 15) dw = 15;
-   if (dw<6) dw = 6;
-   width += 2*dw+4;
-}
-
-
-void
-MathDecorationInset::draw(Painter & pain, int x, int y)
-{ 
-   MathParInset::draw(pain, x + (width - dw) / 2, y);
-   mathed_draw_deco(pain, x, y + dy, width, dh, deco);
-}
-
-
-void
-MathDecorationInset::Metrics()
-{
-   int h = 2*mathed_char_height(LM_TC_VAR, size, 'I', ascent, descent);  
-   MathParInset::Metrics();
-   int w = Width()+4;
-   if (w<16) w = 16;
-   dh = w/5;
-   if (dh>h) dh = h;
-
-   if (upper) {
-      ascent += dh+2;
-      dy = -ascent;
-   } else {
-      dy = descent+2;
-      descent += dh+4;
-   }
-   dw = width;
-   width = w;
-}
-
-
-void
-MathAccentInset::draw(Painter & pain, int x, int y)
-{
-       int dw = width - 2;
-
-       if (inset) 
-               inset->draw(pain, x, y);
-       else {
-               string s;
-               s += c;
-               drawStr(pain, fn, size, x, y, s);
-       }
-       x += (code == LM_not) ? (width-dw) / 2 : 2;
-       mathed_draw_deco(pain, x, y - dy, dw, dh, code);
-}
-
-
-void
-MathAccentInset::Metrics()
-{
-    
-    if (inset) {
-       inset->Metrics();
-       ascent = inset->Ascent();
-       descent = inset->Descent();
-       width = inset->Width();
-       dh = ascent;
-    } else {
-       mathed_char_height(fn, size, c, ascent, descent);
-       width = mathed_char_width(fn, size, c);
-       dh = (width-2)/2; 
-    }
-    if (code == LM_not) {
-       ascent += dh;
-       descent += dh;
-       dh = Height();
-    } else 
-      ascent += dh+2;
-           
-    dy = ascent;
-//    if (MathIsBinary(fn))
-//     width += 2*mathed_char_width(fn, size, ' ');    
-}
-
-
-void
-MathDotsInset::draw(Painter & pain, int x, int y)
-{
-   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()
-{
-   mathed_char_height(LM_TC_VAR, size, 'M', ascent, descent);
-   width = mathed_char_width(LM_TC_VAR, size, 'M');   
-   switch (code) {
-    case LM_ldots: dh = 0; break;
-    case LM_cdots: dh = ascent/2; break;
-    case LM_vdots: width /= 2;
-    case LM_ddots: dh = ascent; break;
-   }
-} 
 
diff --git a/src/mathed/math_deliminset.C b/src/mathed/math_deliminset.C
new file mode 100644 (file)
index 0000000..9e4bbca
--- /dev/null
@@ -0,0 +1,90 @@
+#include <config.h>
+
+#include "math_deliminset.h"
+#include "math_iter.h"
+#include "math_parser.h"
+#include "LColor.h"
+#include "Painter.h"
+#include "mathed/support.h"
+
+
+MathDelimInset::MathDelimInset(int l, int r, short st)
+       : MathParInset(st, "", LM_OT_DELIM), left(l), right(r) {}
+
+
+MathedInset * MathDelimInset::Clone()
+{   
+       MathDelimInset * p = new MathDelimInset(left, right, GetStyle());
+       MathedIter it(array);
+       p->SetData(it.Copy());
+       return p;
+}
+
+
+
+void MathDelimInset::Write(ostream & os, bool fragile)
+{
+       latexkeys * l = (left != '|') ? lm_get_key_by_id(left, LM_TK_SYM): 0;
+       latexkeys * r = (right != '|') ? lm_get_key_by_id(right, LM_TK_SYM): 0;
+       os << "\\left";
+       if (l) {
+               os << '\\' << l->name << ' ';
+       } else {
+               if (left == '{' || left == '}') {
+                       os << '\\' << char(left) << ' ';
+               } else {
+                       os << char(left) << ' ';
+               }
+       }
+       MathParInset::Write(os, fragile);
+       os << "\\right";
+       if (r) {
+               os << '\\' << r->name << ' ';
+       } else {
+               if (right == '{' || right == '}') {
+                       os << '\\' << char(right) << ' ';
+               } else {
+                       os << char(right) << ' ';
+               }
+       }
+}
+
+
+
+void
+MathDelimInset::draw(Painter & pain, int x, int y)
+{ 
+       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()
+{
+   MathParInset::Metrics();
+   int d;
+   
+   mathed_char_height(LM_TC_CONST, size, 'I', d, dh);
+   dh /= 2;
+   ascent += 2 + dh;
+   descent += 2 - dh;
+   dw = Height()/5;
+   if (dw > 15) dw = 15;
+   if (dw<6) dw = 6;
+   width += 2*dw+4;
+}
diff --git a/src/mathed/math_deliminset.h b/src/mathed/math_deliminset.h
new file mode 100644 (file)
index 0000000..b2336a0
--- /dev/null
@@ -0,0 +1,30 @@
+// -*- C++ -*-
+#ifndef MATH_DELIMINSET_H
+#define MATH_DELIMINSET_H
+
+#include "math_parinset.h"
+
+/// A delimiter
+class MathDelimInset: public MathParInset {
+public:
+       ///
+       MathDelimInset(int, int, short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+protected:
+       ///
+       int left;
+       ///
+       int right;
+       ///
+       int dw;
+       ///
+       int dh;
+};
+#endif
diff --git a/src/mathed/math_dotsinset.C b/src/mathed/math_dotsinset.C
new file mode 100644 (file)
index 0000000..fc4b37f
--- /dev/null
@@ -0,0 +1,45 @@
+#include <config.h>
+
+#include "math_dotsinset.h"
+#include "mathed/support.h"
+
+
+MathDotsInset::MathDotsInset(string const & nam, int id, short st)
+       : MathedInset(nam, LM_OT_DOTS, st), code(id) {}
+
+
+MathedInset * MathDotsInset::Clone()
+{
+       return new MathDotsInset(name, code, GetStyle());
+}     
+
+
+void
+MathDotsInset::draw(Painter & pain, int x, int y)
+{
+       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()
+{
+       mathed_char_height(LM_TC_VAR, size, 'M', ascent, descent);
+       width = mathed_char_width(LM_TC_VAR, size, 'M');   
+       switch (code) {
+       case LM_ldots: dh = 0; break;
+       case LM_cdots: dh = ascent/2; break;
+       case LM_vdots: width /= 2;
+       case LM_ddots: dh = ascent; break;
+       }
+} 
+
+
+void
+MathDotsInset::Write(ostream & os, bool /* fragile */)
+{
+       os << '\\' << name << ' ';
+}
diff --git a/src/mathed/math_dotsinset.h b/src/mathed/math_dotsinset.h
new file mode 100644 (file)
index 0000000..0e84808
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef MATH_DOTSINSET_H
+#define MATH_DOTSINSET_H
+
+#include "math_inset.h"
+
+///
+class MathDotsInset: public MathedInset {
+public:
+       ///
+       MathDotsInset(string const &, int, short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+protected:
+       ///
+       int dh, code;
+};   
+#endif
index 8aab09c1e707899c78fa23366ae8ab6c6076e791..1ec03491f55a6ade02f41bea55f19dfff77644a0 100644 (file)
@@ -31,335 +31,8 @@ extern int mathed_string_width(short type, int style, string const &);
 extern int mathed_string_height(short, int, string const &, int &, int &);
 extern int mathed_char_height(short, int, byte, int &, int &);
 
-void
-MathSpaceInset::draw(Painter & pain, int x, int y)
-{ 
 
-// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
 
-// Sadly, HP-UX CC can't handle that kind of initialization.
 
-   int xp[4];
-   int yp[4];
-   
-   xp[0] = ++x;            yp[0] = y - 3;
-   xp[1] = x;             yp[1] = y;
-   xp[2] = x + width - 2;  yp[2] = y;
-   xp[3] = x + width - 2;  yp[3] = y - 3;
 
-   pain.lines(xp, yp, 4, (space) ? LColor::latex : LColor::math);
-}
 
-
-void 
-MathParInset::draw(Painter & pain, int x, int y)
-{
-       byte cxp = 0;
-       int xp = 0;
-       int asc = df_asc, des = 0;
-       bool limits = false;
-
-       xo = x;  yo = y; 
-       if (!array || array->empty()) {
-               if (array) {
-                       MathedXIter data(this);
-                       data.GetPos(x, y);
-               }
-               pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
-               return;
-       }  
-       MathedXIter data(this);
-       data.GoBegin();
-       while (data.OK()) {
-               data.GetPos(x, y);
-               byte cx = data.GetChar();
-               if (cx >= ' ') {
-                       string s = data.GetString();
-                       drawStr(pain, data.FCode(), size, x, y, s);
-                       mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
-                       limits = false;
-               }
-               else {
-                       if (cx == 0)
-                               break;
-                       if (MathIsInset(cx)) {
-                               int yy = y;
-                               MathedInset * p = data.GetInset();
-                               if (cx == LM_TC_UP) {
-                                       if (limits) {
-                                               x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;  
-                                               yy -= (asc + p->Descent()+4);
-                                       }       
-                                       else
-                                               yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
-                               }
-                               else if (cx == LM_TC_DOWN) {
-                                       if (limits) {
-                                               x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
-                                               yy += des + p->Ascent() + 2;
-                                       } else
-                                               yy += des + p->Ascent()/2;
-                               }
-                               else {
-                                       asc = p->Ascent();
-                                       des = p->Descent();
-                               }
-                               p->draw(pain, x, yy);
-                               if (cx!= LM_TC_UP && cx!= LM_TC_DOWN) {
-                                       limits = p->GetLimits();
-                                       if (limits)
-                                               xp = p->Width();
-                               }
-                               data.Next();
-                       }
-                       else if (cx == LM_TC_TAB) {
-                               if (cxp == cx || cxp == LM_TC_CR || data.IsFirst()) {
-                                       pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
-                               }
-                               data.Next();
-                               limits = false;
-                       }
-                       else if (cx == LM_TC_CR) {
-                               if (cxp == LM_TC_TAB || cxp == LM_TC_CR || data.IsFirst()) {
-                                       pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
-                               }
-                               data.Next();
-                               limits = false;
-                       }
-                       else {   
-                               lyxerr << "GMathed Error: Unrecognized code[" << cx << "]" << endl;
-                               break;
-                       }
-               }
-               cxp = cx;
-       }
-       if (cxp == LM_TC_TAB || cxp == LM_TC_CR) { 
-               data.GetPos(x, y);
-               pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
-       }
-}
-
-
-void 
-MathParInset::Metrics()
-{
-    byte cx;
-    byte cxp = 0;
-    int ls;
-    int asc = df_asc;
-    int des = 0;
-    int tb = 0;
-    int tab = 0;
-
-    bool limits = false;
-    
-    ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des); 
-    width = df_width;
-    descent = 0;
-    if (!array) return;
-    if (array->empty()) return;
-    
-    ascent = 0;
-    MathedXIter data(this);
-    data.GoBegin();
-    while (data.OK()) {
-       cx = data.GetChar();      
-       if (cx >= ' ') {
-           string s = data.GetString();
-           mathed_string_height(data.FCode(), size, s, asc, des);
-           if (asc > ascent) ascent = asc;
-           if (des > descent) descent = des;
-           limits = false;
-           mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
-       } else
-         if (MathIsInset(cx)) {
-             MathedInset * p = data.GetInset();
-             p->SetStyle(size);   
-             p->Metrics();
-             if (cx == LM_TC_UP) {
-                 asc += (limits) ? p->Height() + 4: p->Ascent() + 
-                   ((p->Descent()>asc) ? p->Descent() - asc + 4: 0);
-             } else
-               if (cx == LM_TC_DOWN) {
-                   des += ((limits) ? p->Height() + 4: p->Height() - p->Ascent() / 2);
-               } else {
-                   asc = p->Ascent();
-                   des = p->Descent();
-               }
-             if (asc > ascent) ascent = asc;
-             if (des > descent) descent = des;
-             if (cx!= LM_TC_UP && cx!= LM_TC_DOWN)
-               limits = p->GetLimits();
-             data.Next();
-         } else 
-         if (cx == LM_TC_TAB) {
-             int x, y;
-             data.GetIncPos(x, y);
-             if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
-                 if (ascent<df_asc) ascent = df_asc;
-                 tb = x;
-             }
-             data.setTab(x-tb, tab);
-             tb = x;
-             ++tab;
-             limits = false;                   
-             data.Next();
-         } else
-         if (cx == LM_TC_CR) {
-             if (tb > 0) {
-                 int x, y;
-                 data.GetIncPos(x, y);
-                 if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
-                     if (ascent<df_asc) ascent = df_asc;
-                     tb = x;
-                 } 
-                 data.setTab(x - tb, tab);
-             } else //if (GetColumns() == 1) 
-                   {
-                 int x, y;
-                 data.GetIncPos(x, y);
-                 data.setTab(x, tab);
-                 if (ascent<df_asc) ascent = df_asc;
-             } 
-             tb = tab = 0;
-             data.subMetrics(ascent, descent);
-             ascent = df_asc;   
-             descent = 0;
-             data.Next();
-         } else {
-               lyxerr << "Mathed Error: Unrecognized code[" << cx
-                      << "]" << endl;
-           break;
-       }       
-       cxp = cx;
-    }
-    data.GetIncPos(width, ls);
-    
-    // No matter how simple is a matrix, it is NOT a subparagraph
-    if (isMatrix()) {
-       if (cxp == LM_TC_TAB) {
-           if (ascent<df_asc) ascent = df_asc;
-           data.setTab(0, tab);
-       } else {
-         data.setTab(width - tb, tab);
-       }
-    }
-         
-    data.subMetrics(ascent, descent);
-}
-
-
-void
-MathSqrtInset::draw(Painter & pain, int x, int y)
-{ 
-   MathParInset::draw(pain, x + hmax + 2, y); 
-   int h = ascent;
-   int d = descent;
-   int h2 = Height() / 2;
-   int w2 = (Height() > 4 * hmax) ? hmax : hmax / 2; 
-   int xp[4], yp[4];
-   xp[0] = x + hmax + wbody; yp[0] = y - h;
-   xp[1] = x + hmax;         yp[1] = y - h;
-   xp[2] = x + w2;           yp[2] = y + d;
-   xp[3] = x;                yp[3] = y + d - h2;
-   pain.lines(xp, yp, 4, LColor::mathline);
-}
-
-
-void
-MathSqrtInset::Metrics()
-{
-   MathParInset::Metrics();
-   ascent += 4;
-   descent += 2;
-   int a, b;
-   hmax = mathed_char_height(LM_TC_VAR, size, 'I', a, b);
-   if (hmax < 10) hmax = 10;
-   wbody = width + 4;
-   width += hmax + 4;
-}
-
-
-void
-MathFracInset::draw(Painter & pain, int x, int y)
-{ 
-    short idxp = idx;
-    short sizex = size;
-    
-    idx = 0;
-    if (size == LM_ST_DISPLAY) ++size;
-    MathParInset::draw(pain, x + (width - w0) / 2, y - des0);
-    den->draw(pain, x + (width - w1) / 2, y + den->Ascent() + 2 - dh);
-    size = sizex;
-    if (objtype == LM_OT_FRAC)
-           pain.line(x + 2, y - dh, x + width - 4, y - dh, LColor::mathline);
-    idx = idxp;
-}
-
-
-void
-MathFracInset::Metrics()
-{
-    if (!dh) {
-       int a, b;
-       dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
-    }
-    short idxp = idx;
-    short sizex = size; 
-    idx = 0;
-    if (size == LM_ST_DISPLAY) ++size; 
-    MathParInset::Metrics();
-    size = sizex;
-    w0 = width;
-    int as = Height() + 2 + dh;
-    des0 = Descent() + 2 + dh;
-    den->Metrics();  
-    w1 = den->Width();   
-    width = ((w0 > w1) ? w0: w1) + 12;
-    ascent = as; 
-    descent = den->Height()+ 2 - dh;
-    idx = idxp;
-}
-
-
-void
-MathBigopInset::draw(Painter & pain, int x, int y)
-{
-   string s;
-   short t;
-   
-   if (sym < 256 || sym == LM_oint) {
-      s += (sym == LM_oint) ? LM_int : sym;
-      t = LM_TC_BSYM;
-   } else {
-      s = name;
-      t = LM_TC_TEXTRM;
-   }
-   if (sym == LM_oint) {
-          pain.arc(x, y - 5 * width / 4, width, width, 0, 360*64,
-                   LColor::mathline);
-          ++x;
-   }
-   pain.text(x, y, s, mathed_get_font(t, size));
-}
-
-
-void
-MathBigopInset::Metrics()
-{   
-       char c;
-       string s;
-       short t;
-       
-       if (sym < 256 || sym == LM_oint) {
-               c = (sym == LM_oint) ? LM_int: sym;
-               s += c;
-               t = LM_TC_BSYM;
-       } else {
-               s = name;
-               t = LM_TC_TEXTRM;
-       }
-       mathed_string_height(t, size, s, ascent, descent);
-       width = mathed_string_width(t, size, s);
-       if (sym == LM_oint) width += 2;
-}
diff --git a/src/mathed/math_fracinset.C b/src/mathed/math_fracinset.C
new file mode 100644 (file)
index 0000000..73be7a8
--- /dev/null
@@ -0,0 +1,161 @@
+#include <config.h>
+
+#include "math_fracinset.h"
+#include "math_iter.h"
+#include "LColor.h"
+#include "Painter.h"
+#include "mathed/support.h"
+
+
+MathFracInset::MathFracInset(short ot)
+       : MathParInset(LM_ST_TEXT, "frac", ot)
+{
+       
+       den = new MathParInset(LM_ST_TEXT); // this leaks
+       dh = 0;
+       idx = 0;
+       if (objtype == LM_OT_STACKREL) {
+               flag |= LMPF_SCRIPT;
+               SetName("stackrel");
+       }
+}
+
+
+MathFracInset::~MathFracInset()
+{
+       delete den;
+}
+
+
+MathedInset * MathFracInset::Clone()
+{   
+       MathFracInset * p = new MathFracInset(GetType());
+       MathedIter itn(array);
+       MathedIter itd(den->GetData());
+       p->SetData(itn.Copy(), itd.Copy());
+       p->idx = idx;
+       p->dh = dh;
+       return p;
+}
+
+
+bool MathFracInset::setArgumentIdx(int i)
+{
+       if (i == 0 || i == 1) {
+               idx = i;
+               return true;
+       } else 
+               return false;
+}
+
+
+void MathFracInset::SetStyle(short st)
+{
+       MathParInset::SetStyle(st);
+       dh = 0;
+       den->SetStyle((size == LM_ST_DISPLAY) ?
+                     static_cast<short>(LM_ST_TEXT)
+                     : size);
+}
+
+
+void MathFracInset::SetData(MathedArray * n, MathedArray * d)
+{
+       den->SetData(d);
+       MathParInset::SetData(n);
+}
+
+
+void MathFracInset::SetData(MathedArray * d)
+{
+       if (idx == 0)
+               MathParInset::SetData(d);
+       else {
+               den->SetData(d);
+       }
+}
+
+
+void MathFracInset::GetXY(int & x, int & y) const
+{  
+       if (idx == 0)
+               MathParInset::GetXY(x, y);
+       else
+               den->GetXY(x, y);
+}
+
+
+MathedArray * MathFracInset::GetData()
+{
+       if (idx == 0)
+               return array;
+       else
+               return den->GetData();
+}
+
+
+bool MathFracInset::Inside(int x, int y) 
+{
+       int xx = xo - (width - w0) / 2;
+       
+       return x >= xx && x <= xx + width && y <= yo + descent && y >= yo - ascent;
+}
+
+
+void MathFracInset::SetFocus(int /*x*/, int y)
+{  
+//    lyxerr << "y " << y << " " << yo << " " << den->yo << " ";
+       idx = (y > yo) ? 1: 0;
+}
+
+
+void
+MathFracInset::draw(Painter & pain, int x, int y)
+{ 
+       short idxp = idx;
+       short sizex = size;
+       
+       idx = 0;
+       if (size == LM_ST_DISPLAY) ++size;
+       MathParInset::draw(pain, x + (width - w0) / 2, y - des0);
+       den->draw(pain, x + (width - w1) / 2, y + den->Ascent() + 2 - dh);
+       size = sizex;
+       if (objtype == LM_OT_FRAC)
+               pain.line(x + 2, y - dh, x + width - 4, y - dh, LColor::mathline);
+       idx = idxp;
+}
+
+
+void
+MathFracInset::Metrics()
+{
+       if (!dh) {
+               int a, b;
+               dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
+       }
+       short idxp = idx;
+       short sizex = size; 
+       idx = 0;
+       if (size == LM_ST_DISPLAY) ++size; 
+       MathParInset::Metrics();
+       size = sizex;
+       w0 = width;
+       int as = Height() + 2 + dh;
+       des0 = Descent() + 2 + dh;
+       den->Metrics();  
+       w1 = den->Width();   
+       width = ((w0 > w1) ? w0: w1) + 12;
+       ascent = as; 
+       descent = den->Height()+ 2 - dh;
+       idx = idxp;
+}
+
+
+void MathFracInset::Write(ostream & os, bool fragile)
+{
+       os << '\\' << name << '{';
+       MathParInset::Write(os, fragile);
+       os << "}{";
+       den->Write(os, fragile);
+       os << '}';
+}
diff --git a/src/mathed/math_fracinset.h b/src/mathed/math_fracinset.h
new file mode 100644 (file)
index 0000000..409703d
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef MATH_FRACINSET_H
+#define MATH_FRACINSET_H
+
+#include "math_parinset.h"
+
+/// Fraction like objects (frac, stackrel, binom) 
+class MathFracInset: public MathParInset {
+public:
+       ///
+       MathFracInset(short ot = LM_OT_FRAC);
+       ///
+       ~MathFracInset();
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int x, int baseline);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       
+       /** This does the same that SetData(MathedArray*) but for both
+           numerator and denominator at once.
+       */
+       void SetData(MathedArray *, MathedArray *);
+       ///
+       void SetData(MathedArray *);
+       ///
+       void GetXY(int & x, int & y) const;
+       ///
+       void SetFocus(int, int);
+       ///
+       bool Inside(int, int);
+       ///
+       MathedArray * GetData();
+       ///
+       bool setArgumentIdx(int i); // was bool Up/down(void);
+       ///
+       int getArgumentIdx() const { return idx; }
+       ///
+       int getMaxArgumentIdx() const { return 1; }
+       ///
+       void  SetStyle(short);
+protected:
+       ///
+       int idx;
+       ///
+       MathParInset * den;
+       ///
+       int w0, w1, des0, dh;
+};
+#endif
diff --git a/src/mathed/math_funcinset.C b/src/mathed/math_funcinset.C
new file mode 100644 (file)
index 0000000..4a5c4d7
--- /dev/null
@@ -0,0 +1,77 @@
+#include <config.h>
+
+#include "math_funcinset.h"
+#include "lyxfont.h"
+#include "font.h"
+#include "Painter.h"
+#include "mathed/support.h"
+
+
+extern LyXFont WhichFont(short type, int size);
+
+MathFuncInset::~MathFuncInset()
+{}
+
+
+bool MathFuncInset::GetLimits() const 
+{  
+   return bool(lims && (GetStyle() == LM_ST_DISPLAY)); 
+} 
+
+
+void MathFuncInset::Write(std::ostream & os, bool /* fragile */)
+{
+       os << "\\" << name << ' ';
+}
+
+
+MathFuncInset::MathFuncInset(string const & nm, short ot, short st)
+       : MathedInset("", ot, st)
+{
+       ln = 0;
+       lims = (GetType() == LM_OT_FUNCLIM);
+       if (GetType() == LM_OT_UNDEF) {
+               fname = nm;
+               SetName(fname);
+       } else {
+               //fname = 0;
+               SetName(nm);
+       }
+}
+
+
+MathedInset * MathFuncInset::Clone()
+{
+       return new MathFuncInset(name, GetType(), GetStyle());
+}
+
+
+
+void
+MathFuncInset::draw(Painter & pain, int x, int y)
+{ 
+       if (!name.empty() && name[0] > ' ') {
+               LyXFont font = WhichFont(LM_TC_TEXTRM, size);
+               font.setLatex(LyXFont::ON);
+               x += (lyxfont::width('I', font) + 3) / 4;
+               pain.text(x, y, name, font);
+       }
+}
+
+
+
+void MathFuncInset::Metrics() 
+{
+       //ln = (name) ? strlen(name): 0;
+       LyXFont  font = WhichFont(LM_TC_TEXTRM, size);
+       font.setLatex(LyXFont::ON);
+       if (name.empty()) {
+               width = df_width;
+               descent = df_des;
+               ascent = df_asc;
+       } else {
+               width = lyxfont::width(name, font)
+                       + lyxfont::width('I', font) / 2;
+               mathed_string_height(LM_TC_TEXTRM, size, name, ascent, descent);
+       }
+}
diff --git a/src/mathed/math_funcinset.h b/src/mathed/math_funcinset.h
new file mode 100644 (file)
index 0000000..bbc78d9
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef MATH_FUNCINSET_H
+#define MATH_FUNCINSET_H
+
+#include "math_inset.h"
+
+/**
+ Functions or LaTeX names for objects that I don't know how to draw.
+ */
+class MathFuncInset: public MathedInset  {
+public:
+       ///
+       explicit
+       MathFuncInset(string const & nm,
+                     short ot = LM_OT_FUNC, short st = LM_ST_TEXT);
+       ///
+       ~MathFuncInset();
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       inline bool GetLimits() const;
+protected:
+       ///
+       int ln;
+       ///
+       bool lims;
+       ///
+       string fname;
+};
+#endif
index 0882396fc187899dc7b6b274e427185cd5535709..2e57a7fbe5e8c5cfae685f348e0e9d09b61a66ca 100644 (file)
 #include <config.h>
 
 #ifdef __GNUG__
-#pragma implementation "math_inset.h"
+#pragma implementation
 #endif
 
 #include "math_iter.h"
 #include "math_inset.h"
 #include "symbol_def.h"
+#include "lyxfont.h"
+#include "mathed/support.h"
+#include "Painter.h"
+
+int MathedInset::df_asc;
+int MathedInset::df_des;
+int MathedInset::df_width;
+int MathedInset::workWidth;
 
 
 MathedInset::MathedInset(MathedInset * inset) 
@@ -44,520 +52,28 @@ MathedInset::MathedInset(MathedInset * inset)
 }
 
 
-MathFuncInset::MathFuncInset(string const & nm, short ot, short st)
-       : MathedInset("", ot, st)
-{
-   ln = 0;
-   lims = (GetType() == LM_OT_FUNCLIM);
-    if (GetType() == LM_OT_UNDEF) {
-       fname = nm;
-       SetName(fname);
-    } else {
-       //fname = 0;
-       SetName(nm);
-    }
-}
-
-
-MathedInset * MathFuncInset::Clone()
-{
-   return new MathFuncInset(name, GetType(), GetStyle());
-}
-
-
-MathSpaceInset::MathSpaceInset(int sp, short ot, short st)
-       : MathedInset("", ot, st), space(sp)
-{}
-
-
-MathedInset * MathSpaceInset::Clone()
-{
-   return new MathSpaceInset(space, GetType(), GetStyle());
-}
-
-
-MathParInset::MathParInset(short st, string const & nm, short ot)
-       : MathedInset(nm, ot, st)
-{
-    array = 0;
-    ascent = 8;
-    width = 4;
-    descent = 0;
-    flag = 1;
-    if (objtype == LM_OT_SCRIPT)
-      flag |= LMPF_SCRIPT;
-}
-
-
-MathParInset::MathParInset(MathParInset * p)
-       : MathedInset(p)
-{
-    flag = p->flag;
-    p->setArgumentIdx(0);
-    MathedIter it(p->GetData());
-    SetData(it.Copy());
-}
-
-
-MathParInset::~MathParInset()
-{
-   if (array) {
-      MathedIter it(array);
-      it.Clear();
-      delete array;
-   }
-}
-
-
-MathedInset * MathParInset::Clone()
-{
-   return new MathParInset(this);
-}
-
-
-void MathParInset::SetData(MathedArray * a)
-{
-    array = a;
-   
-    // A standard paragraph shouldn't have any tabs nor CRs.
-    if (array) {
-       MathedIter it(array);
-       while (it.OK()) {
-           char c = it.GetChar();
-           if (c == LM_TC_TAB || c == LM_TC_CR) 
-             it.Delete();
-           else
-             it.Next();
-       }
-   }
-}
-
-
-MathSqrtInset::MathSqrtInset(short st)
-       : MathParInset(st, "sqrt", LM_OT_SQRT) {}
-
-
-MathedInset * MathSqrtInset::Clone()
-{   
-   MathSqrtInset * p = new MathSqrtInset(GetStyle());
-   MathedIter it(array);
-   p->SetData(it.Copy());
-   return p;
-}
-
-
-bool MathSqrtInset::Inside(int x, int y) 
-{
-       return x >= xo - hmax
-               && x <= xo + width - hmax
-               && y <= yo + descent
-               && y >= yo - ascent;
-}
-
-
-MathDelimInset::MathDelimInset(int l, int r, short st)
-       : MathParInset(st, "", LM_OT_DELIM), left(l), right(r) {}
-
-
-MathedInset * MathDelimInset::Clone()
-{   
-   MathDelimInset * p = new MathDelimInset(left, right, GetStyle());
-   MathedIter it(array);
-   p->SetData(it.Copy());
-   return p;
-}
-
-
-MathDecorationInset::MathDecorationInset(int d, short st)
-       : MathParInset(st, "", LM_OT_DECO), deco(d)
-{
-   upper = (deco!= LM_underline && deco!= LM_underbrace);
-}
-
-
-MathedInset * MathDecorationInset::Clone()
-{   
-   MathDecorationInset * p = new MathDecorationInset(deco, GetStyle());
-   MathedIter it(array);
-   p->SetData(it.Copy());
-   return p;
-}
-
-
-MathFracInset::MathFracInset(short ot)
-       : MathParInset(LM_ST_TEXT, "frac", ot)
-{
-       
-    den = new MathParInset(LM_ST_TEXT); // this leaks
-    dh = 0;
-    idx = 0;
-    if (objtype == LM_OT_STACKREL) {
-       flag |= LMPF_SCRIPT;
-       SetName("stackrel");
-    }
-}
-
-
-MathFracInset::~MathFracInset()
-{
-    delete den;
-}
-
-
-MathedInset * MathFracInset::Clone()
-{   
-    MathFracInset * p = new MathFracInset(GetType());
-    MathedIter itn(array);
-    MathedIter itd(den->GetData());
-    p->SetData(itn.Copy(), itd.Copy());
-    p->idx = idx;
-    p->dh = dh;
-   return p;
-}
-
-
-bool MathFracInset::setArgumentIdx(int i)
-{
-   if (i == 0 || i == 1) {
-       idx = i;
-       return true;
-   } else 
-      return false;
-}
-
-
-void MathFracInset::SetStyle(short st)
-{
-    MathParInset::SetStyle(st);
-    dh = 0;
-    den->SetStyle((size == LM_ST_DISPLAY) ?
-                 static_cast<short>(LM_ST_TEXT)
-                 : size);
-}
-
-
-void MathFracInset::SetData(MathedArray * n, MathedArray * d)
-{
-   den->SetData(d);
-   MathParInset::SetData(n);
-}
-
-
-void MathFracInset::SetData(MathedArray * d)
-{
-   if (idx == 0)
-     MathParInset::SetData(d);
-   else {
-      den->SetData(d);
-   }
-}
-
-
-void MathFracInset::GetXY(int & x, int & y) const
-{  
-   if (idx == 0)
-     MathParInset::GetXY(x, y);
-   else
-     den->GetXY(x, y);
-}
-
-
-MathedArray * MathFracInset::GetData()
-{
-   if (idx == 0)
-     return array;
-   else
-     return den->GetData();
-}
-
-
-bool MathFracInset::Inside(int x, int y) 
-{
-    int xx = xo - (width - w0) / 2;
-    
-    return x >= xx && x <= xx + width && y <= yo + descent && y >= yo - ascent;
-}
-
-
-void MathFracInset::SetFocus(int /*x*/, int y)
-{  
-//    lyxerr << "y " << y << " " << yo << " " << den->yo << " ";
-    idx = (y > yo) ? 1: 0;
-}
-
-
-MathMatrixInset::MathMatrixInset(int m, int n, short st)
-       : MathParInset(st, "array", LM_OT_MATRIX), nc(m), nr(0), ws_(m),
-       v_align(0), h_align(nc, 'c')
-{
-    row = 0;
-    flag = 15;
-    if (n > 0) {
-           row = new MathedRowSt(nc+1);
-       MathedXIter it(this);
-       for (int j = 1; j < n; ++j) it.addRow();
-       nr = n;
-       if (nr == 1 && nc > 1) {
-           for (int j = 0; j < nc - 1; ++j) 
-             it.Insert('T', LM_TC_TAB);
-       }
-    } else if (n < 0) {
-           row = new MathedRowSt(nc + 1);
-       nr = 1;
-    }
-}
-
-
-MathMatrixInset::MathMatrixInset(MathMatrixInset * mt)
-       : MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType()),
-         nc(mt->nc), nr(0), ws_(mt->nc), v_align(mt->v_align), h_align(mt->h_align)
-{
-    MathedIter it;
-    it.SetData(mt->GetData());
-    array = it.Copy();
-    if (mt->row != 0) {
-       MathedRowSt * r, * ro= 0, * mrow = mt->row;
-       //mrow = mt->row; // This must be redundant...
-       while (mrow) {
-           r = new MathedRowSt(nc + 1);
-           r->setNumbered(mrow->isNumbered());
-           //if (mrow->label) 
-             r->setLabel(mrow->getLabel());
-           if (!ro) 
-             row = r;
-           else
-             ro->setNext(r);
-           mrow = mrow->getNext();
-           ro = r;
-           ++nr;
-       } 
-    } else         
-      row = 0;
-    flag = mt->flag;
-}
-
-
-MathMatrixInset::~MathMatrixInset()
-{
-    MathedRowSt * r = row;
-    while (r) {
-       MathedRowSt * q = r->getNext();
-       delete r;
-       r = q;
-    }
-}
-
-
-MathedInset * MathMatrixInset::Clone()
-{
-    return new MathMatrixInset(this);
-}
-
-
-void MathMatrixInset::SetAlign(char vv, string const & hh)
-{
-   v_align = vv;
-   h_align = hh.substr(0, nc); // usr just h_align = hh; perhaps
-}
-
-
-// Check the number of tabs and crs
-void MathMatrixInset::SetData(MathedArray * a)
-{
-    if (!a) return;
-    MathedIter it(a);
-    int nn = nc - 1;
-    nr = 1;
-    // count tabs per row
-    while (it.OK()) {
-       if (it.IsTab()) {
-           if (nn < 0) { 
-               it.Delete();
-               continue;
-           } else {
-//           it.Next();
-               --nn;
-           }
-       }
-       if (it.IsCR()) {
-           while (nn > 0) {
-               it.Insert(' ', LM_TC_TAB);
-               --nn;
-           }
-           nn = nc - 1;
-           ++nr;
-       }
-       it.Next();
-    }
-    it.Reset();
-
-    // Automatically inserts tabs around bops
-    // DISABLED because it's very easy to insert tabs 
-    array = a;
-}
-
-
-void MathMatrixInset::draw(Painter & pain, int x, int baseline)
-{
-    MathParInset::draw(pain, x, baseline);
-}
-
-
-void MathMatrixInset::Metrics()
-{
-    int i, hl, h = 0;
-    MathedRowSt * cprow= 0;
-
-    if (!row) {
-//     lyxerr << " MIDA ";
-       MathedXIter it(this);
-       row = it.adjustVerticalSt();
-    } 
-    
-    // Clean the arrays      
-    MathedRowSt * cxrow = row;
-    while (cxrow) {   
-       for (i = 0; i <= nc; ++i) cxrow->setTab(i, 0);
-       cxrow = cxrow->getNext();
-    }
-    
-    // Basic metrics
-    MathParInset::Metrics();
-           
-    if (nc <= 1 && !row->getNext()) {
-       row->ascent(ascent);
-       row->descent(descent);
-    }
-    
-    // Vertical positions of each row
-    cxrow = row;     
-    while (cxrow) {
-       for (i = 0; i < nc; ++i) {
-           if (cxrow == row || ws_[i] < cxrow->getTab(i))
-                   ws_[i] = cxrow->getTab(i);
-           if (cxrow->getNext() == 0 && ws_[i] == 0) ws_[i] = df_width;
-       }
-       
-       cxrow->setBaseline((cxrow == row) ?
-                          cxrow->ascent() :
-                  cxrow->ascent() + cprow->descent()
-                          + MATH_ROWSEP + cprow->getBaseline());
-       h += cxrow->ascent() + cxrow->descent() + MATH_ROWSEP;  
-       cprow = cxrow;
-       cxrow = cxrow->getNext();
-    }
-    
-    hl = Descent();
-    h -= MATH_ROWSEP;
-
-    //  Compute vertical align
-    switch (v_align) {
-     case 't': ascent = row->getBaseline(); break;
-     case 'b': ascent = h - hl; break;
-     default:  ascent = (row->getNext()) ? h / 2: h - hl; break;
-    }
-    descent = h - ascent + 2;
-    
-    // Increase ws_[i] for 'R' columns (except the first one)
-    for (i = 1; i < nc; ++i)
-       if (h_align[i] == 'R')
-           ws_[i] += 10*df_width;
-    // Increase ws_[i] for 'C' column
-    if (h_align[0] == 'C')
-       if (ws_[0] < 7*workWidth/8)
-           ws_[0] = 7*workWidth/8;
-
-   // Adjust local tabs
-    cxrow = row;
-    width = MATH_COLSEP;
-    while (cxrow) {   
-           int rg = MATH_COLSEP, ww, lf = 0; //, * w = cxrow->w;
-       for (i = 0; i < nc; ++i) {
-           bool isvoid = false;
-           if (cxrow->getTab(i) <= 0) {
-               cxrow->setTab(i, df_width);
-               isvoid = true;
-           }
-           switch (h_align[i]) {
-           case 'l':
-               lf = 0;
-               break;
-           case 'c':
-               lf = (ws_[i] - cxrow->getTab(i))/2; 
-               break;
-           case 'r':
-           case 'R':
-               lf = ws_[i] - cxrow->getTab(i);
-               break;
-           case 'C':
-               if (cxrow == row)
-                   lf = 0;
-               else if (!cxrow->getNext())
-                    lf = ws_[i] - cxrow->getTab(i);
-               else
-                   lf = (ws_[i] - cxrow->getTab(i))/2; 
-               break;
-           }
-           ww = (isvoid) ? lf : lf + cxrow->getTab(i);
-           cxrow->setTab(i, lf + rg);
-           rg = ws_[i] - ww + MATH_COLSEP;
-           if (cxrow == row) width += ws_[i] + MATH_COLSEP;
-       }
-       cxrow->setBaseline(cxrow->getBaseline() - ascent);
-       cxrow = cxrow->getNext();
-    }
-}
-
-
-MathAccentInset::MathAccentInset(byte cx, MathedTextCodes f, int cd, short st)
-       : MathedInset("", LM_OT_ACCENT, st), c(cx), fn(f), code(cd)
+MathedInset::MathedInset(string const & nm, short ot, short st):
+  name(nm), objtype(ot), size(st) 
 {
-    inset = 0;
+   width = ascent = descent = 0;
 }
 
 
-MathAccentInset::MathAccentInset(MathedInset *ins, int cd, short st)
-       : MathedInset("", LM_OT_ACCENT, st),
-         c(0), fn(LM_TC_MIN), code(cd), inset(ins) {}
-
-
-MathAccentInset::~MathAccentInset()
+// In a near future maybe we use a better fonts renderer
+void MathedInset::drawStr(Painter & pain, short type, int siz,
+                         int x, int y, string const & s)
 {
-       delete inset;
-}
-
+       string st;
+       if (MathIsBinary(type))
+               for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
+                       st += ' ';
+                       st += *it;
+                       st += ' ';
+               }
+       else
+               st = s;
 
-MathedInset * MathAccentInset::Clone()
-{   
-    MathAccentInset * p;
-    
-    if (inset) 
-      p = new MathAccentInset(inset->Clone(), code, GetStyle());
-    else
-      p = new MathAccentInset(c, fn, code, GetStyle());
-    
-    return p;
+       LyXFont const mf = mathed_get_font(type, siz);
+       pain.text(x, y, st, mf);
 }
 
-
-MathBigopInset::MathBigopInset(string const & nam, int id, short st)
-       : MathedInset(nam, LM_OT_BIGOP, st), sym(id)
-{
-   lims = -1;
-}
-
-
-MathedInset * MathBigopInset::Clone()
-{
-   return new MathBigopInset(name, sym, GetStyle());
-}
-
-
-MathDotsInset::MathDotsInset(string const & nam, int id, short st)
-       : MathedInset(nam, LM_OT_DOTS, st), code(id) {}
-
-
-MathedInset * MathDotsInset::Clone()
-{
-   return new MathDotsInset(name, code, GetStyle());
-}     
index 618c42601ce7a63e3388c3c2493686325098c684..fa759c5af6c196dc1f492926f53f9363ee88b70f 100644 (file)
 #include "math_defs.h"
 #include "symbol_def.h"
 
-/**
- Functions or LaTeX names for objects that I don't know how to draw.
+/** Abstract base class for all math objects.
+    A math insets is for use of the math editor only, it isn't a
+    general LyX inset. It's used to represent all the math objects.
+    The formulaInset (a LyX inset) encapsulates a math inset.
  */
-class MathFuncInset: public MathedInset  {
-public:
-       ///
-       explicit
-       MathFuncInset(string const & nm,
-                     short ot = LM_OT_FUNC, short st = LM_ST_TEXT);
-       ///
-       ~MathFuncInset();
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       ///
-       inline bool GetLimits() const;
-protected:
-       ///
-       int ln;
-       ///
-       bool lims;
-       ///
-       string fname;
+class MathedInset  {
+ public: 
+    /// A math inset has a name (usually its LaTeX name), type and font-size
+    MathedInset(string const & nm, short ot, short st);
+    ///
+    explicit
+    MathedInset(MathedInset *);
+    ///
+    virtual ~MathedInset() {}
+    /// Draw the object
+    virtual void draw(Painter &, int x, int baseline) = 0;     
+    /// Write LaTeX and Lyx code
+    virtual void Write(std::ostream &, bool fragile) = 0;
+    /// Reproduces itself
+    virtual MathedInset * Clone() = 0;
+    /// Compute the size of the object
+    virtual void Metrics() = 0; 
+    /// 
+    virtual int Ascent() const { return ascent; }
+    ///
+    virtual int Descent() const { return descent; }
+    ///
+    virtual int Width() const { return width; }
+    ///
+    virtual int Height() const { return ascent + descent; }
+    ///
+    virtual bool GetLimits() const { return false; }
+    ///
+    virtual void SetLimits(bool) {}   
+    ///
+    string const & GetName() const { return name; }
+    ///
+    short GetType() const { return objtype; }
+    ///
+    short GetStyle() const { return size; }
+    //Man:  Avoid to use these functions if it's not strictly necessary 
+    ///
+    virtual void  SetType(short t) { objtype = t; }
+    ///
+    virtual void  SetStyle(short st) { size = st; } // Metrics();
+    ///
+    virtual void  SetName(string const & n) { name = n; }
+    ///
+    static int workWidth;
+        protected:
+    ///
+    string name;
+    ///
+    short objtype;
+    ///
+    int width;
+    ///
+    int ascent;
+    ///
+    int descent;
+    ///
+    short size;
+    /// Default metrics
+    static int df_asc;
+    ///
+    static int df_des;
+    ///
+    static int df_width;
+    /// In a near future maybe we use a better fonts renderer than X
+    void drawStr(Painter &, short, int, int, int, string const &);
+    ///
+    friend class MathedCursor;
+    ///
+    friend void mathed_init_fonts();
 };
-
-
-/// Accents
-class MathAccentInset: public MathedInset {
-public:
-       ///
-       MathAccentInset(byte, MathedTextCodes, int, short st = LM_ST_TEXT);
-       ///
-       MathAccentInset(MathedInset *, int, short st = LM_ST_TEXT);
-       ///
-       ~MathAccentInset();
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       ///
-       int getAccentCode() const { return code; }
-       
-protected:
-       ///
-       byte c;
-       ///
-       MathedTextCodes fn;
-       ///
-       int code;
-       ///
-       MathedInset * inset;
-       ///
-       int dh, dy;
-};
-
-
-///
-class MathDotsInset: public MathedInset {
-public:
-       ///
-       MathDotsInset(string const &, int, short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-protected:
-       ///
-       int dh, code;
-};   
-
-
-/// Smart spaces
-class MathSpaceInset: public MathedInset  {
-public:
-       ///
-       MathSpaceInset(int sp, short ot = LM_OT_SPACE, short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       inline void Metrics();
-       ///
-       inline void SetSpace(int sp);
-       ///
-       int GetSpace() { return space; }
-protected:
-       ///
-       int space;
-};
-
-
-/// big operators
-class MathBigopInset: public MathedInset {
-public:
-       ///
-       MathBigopInset(string const &, int, short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       ///
-       inline bool GetLimits() const;
-       ///
-       inline void SetLimits(bool);
-protected:
-       ///
-       int lims;
-       ///
-       int sym;   
-};
-
-//------- All editable insets must be derived from MathParInset.
-
-///
-class MathSqrtInset: public MathParInset {
-public:
-       ///
-       MathSqrtInset(short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int x, int baseline);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       ///
-       bool Inside(int, int);
-private:
-       ///
-       int hmax, wbody;
-};
-
-
-/// Fraction like objects (frac, stackrel, binom) 
-class MathFracInset: public MathParInset {
-public:
-       ///
-       MathFracInset(short ot = LM_OT_FRAC);
-       ///
-       ~MathFracInset();
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int x, int baseline);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       
-       /** This does the same that SetData(MathedArray*) but for both
-           numerator and denominator at once.
-       */
-       void SetData(MathedArray *, MathedArray *);
-       ///
-       void SetData(MathedArray *);
-       ///
-       void GetXY(int & x, int & y) const;
-       ///
-       void SetFocus(int, int);
-       ///
-       bool Inside(int, int);
-       ///
-       MathedArray * GetData();
-       ///
-       bool setArgumentIdx(int i); // was bool Up/down(void);
-       ///
-       int getArgumentIdx() const { return idx; }
-       ///
-       int getMaxArgumentIdx() const { return 1; }
-       ///
-       void  SetStyle(short);
-protected:
-       ///
-       int idx;
-       ///
-       MathParInset * den;
-       ///
-       int w0, w1, des0, dh;
-};
-
-
-/// A delimiter
-class MathDelimInset: public MathParInset {
-public:
-       ///
-       MathDelimInset(int, int, short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-protected:
-       ///
-       int left, right;
-       ///
-       int dw, dh;
-};
-
-
-/// Decorations over (below) a math object
-class MathDecorationInset: public MathParInset {
-public:
-       ///
-       MathDecorationInset(int, short st = LM_ST_TEXT);
-       ///
-       MathedInset * Clone();
-       ///
-       void draw(Painter &, int, int);
-       ///
-       void Write(std::ostream &, bool fragile);
-       ///
-       void Metrics();
-       ///
-       inline bool GetLimits() const;
-protected:
-       ///
-       int deco;
-       ///
-       bool upper;
-       ///
-       int dw, dh, dy;
-};
-
-
-// --------------------  Inline functions ---------------------
-
-inline
-MathFuncInset::~MathFuncInset()
-{}
-
-
-inline
-bool MathFuncInset::GetLimits() const 
-{  
-   return bool(lims && (GetStyle() == LM_ST_DISPLAY)); 
-} 
-
-
-inline
-void MathFuncInset::Write(std::ostream & os, bool /* fragile */)
-{
-       os << "\\" << name << ' ';
-}
-
-
-inline
-void MathSpaceInset::Metrics()
-{
-   width = space ? space * 2 : 2;
-   if (space > 3) width *= 2;
-   if (space == 5) width *= 2;
-   width += 4;
-   ascent = 4; descent = 0;
-}
-
-
-inline
-void MathSpaceInset::SetSpace(int sp)
-{ 
-   space = sp;
-   Metrics();
-}    
-
-
-inline
-bool MathBigopInset::GetLimits() const 
-{  
-    // Default case
-    if (lims < 0) {
-       return sym != LM_int && sym != LM_oint && GetStyle() == LM_ST_DISPLAY;
-    } 
-    
-    // Custom 
-    return lims > 0;
-} 
-
-
-inline
-void MathBigopInset::SetLimits(bool ls) 
-{  
-    lims = ls ? 1 : 0; 
-} 
-
-
-inline
-bool MathDecorationInset::GetLimits() const
-{ 
-   return deco == LM_underbrace || deco == LM_overbrace;
-}    
-
 #endif
index eb6458945916e93abe645edc7b7de7a2e79d8848..a9cb0b006cc509e9bc1e4ac813d11c1576f0e4d9 100644 (file)
 #include <config.h>
 
 #ifdef __GNUG__
-#pragma implementation "math_iter.h"
+#pragma implementation
 #endif
 
 #include "math_iter.h"
+#include "array.h"
 #include "math_inset.h"
 #include "symbol_def.h"
 #include "support/lstrings.h"
@@ -35,6 +36,30 @@ extern int mathed_char_width(short type, int style, byte c);
 extern int mathed_string_width(short type, int style, string const & s);
 extern int mathed_char_height(short, int, byte, int &, int &);
 
+void MathedIter::SetData(MathedArray * a)
+{
+       array = a; Reset();
+}
+
+
+MathedArray * MathedIter::GetData() const
+{
+       return array;
+}
+
+int MathedIter::Empty() const
+{
+       return array->last() <= 1;
+}
+
+
+int MathedIter::OK() const
+{
+       return array && (pos < array->last());
+}
+
 
 void MathedIter::Reset()
 {
@@ -92,7 +117,7 @@ MathedInset * MathedIter::GetInset() const
 MathParInset * MathedIter::GetActiveInset() const
 {
     if (IsActive()) {
-       return static_cast<MathParInset*>(GetInset());
+       return reinterpret_cast<MathParInset*>(GetInset());
     } 
     
     lyxerr << "Math Error: This is not an active inset" << endl;
@@ -417,551 +442,67 @@ void MathedIter::checkTabs()
 //   - If tehre are not a relation operator, put everything in the
 //     3rd column.
 void MathedIter::adjustTabs()
-{
-
-}         
+{}         
 
 
-void MathedXIter::Clean(int pos2)
+bool MathedIter::IsInset() const
 {
-    if (!array) {
-           lyxerr << "Math error: Attempting to clean a void array." << endl;
-       return;
-    } 
-    
-    int pos1 = pos;
-    
-    if (pos2 < pos1) {
-       GoBegin();
-       while (pos < pos2 && OK()) {
-               Next();
-       }
-       pos2 = pos1;
-       pos1 = pos;
-    }
-
-    ipush();
-    while (OK() && pos < pos2) {
-       if (IsInset()) {
-           MathedInset * inset = GetInset();
-           Next();
-           if (inset->GetType()!= LM_OT_MACRO_ARG)
-             delete inset;
-           continue;
-       } 
-       if (IsCR()) {
-           if (crow) {
-               MathedRowSt * r = crow->getNext();
-               if (r) {
-                   crow->setNext(r->getNext());
-                   delete r;
-               }          
-           }
-       }
-       Next();
-    }    
-    ipop();
-    
-    if (pos2 <= array->last()) {
-       pos = pos1;
-       join(pos2);
-       checkTabs();
-    } 
+    return MathIsInset((*array)[pos]);
 }
 
-
-void MathedXIter::Merge(MathedArray * a0)
+bool MathedIter::IsActive() const
 {
-    if (!a0) {
-           lyxerr[Debug::MATHED]
-                   << "Math error: Attempting to merge a void array." << endl;
-
-       return;
-    }
-    // All insets must be clonned
-    MathedIter it(a0);
-    MathedArray * a = it.Copy();
-    
-    // make room for the data 
-    split(a->last());
-    array->mergeF(a, pos, a->last());
-
-    int pos1 = pos;
-    int pos2 = pos + a->last();
-
-    goPosAbs(pos1);
-    
-    // Complete rows
-    while (pos < pos2 && OK()) {
-       if (IsCR()) {
-           if (p && p->Permit(LMPF_ALLOW_CR)) {
-               MathedRowSt * r = new MathedRowSt(ncols+1);
-               if (crow) {
-                   r->setNext(crow->getNext());
-                   crow->setNext(r);
-                 } else {
-                     r->setNext(0);
-                 }
-               crow = r;
-           } else {
-               Delete();
-               --pos2;
-           }
-       }
-        Next();    
-    }
-    pos2 = getPos();
-    goPosAbs(pos1);
-    checkTabs();
-    goPosAbs(pos2);
-    
-    delete a;
-}
-
-
-//-----------  XIter
-
-
-MathedXIter::MathedXIter(MathParInset * pp)
-       : p(pp) 
-{ 
-    x = y = 0;
-    sx = sw = 0;   
-    limits = false;
-    s_type = 0;  
-    if (p) 
-      SetData(p);
-    else {
-       crow = 0;
-       size = 0;
-    }
+    return MathIsActive((*array)[pos]);
 }
 
 
-void MathedXIter::SetData(MathParInset * pp)
+bool MathedIter::IsFont() const
 {
-    p = pp;
-    x = y = 0;
-    array = p->GetData();
-    ncols = p->GetColumns();
-    crow = p->getRowSt();
-    if (p->Permit(LMPF_ALLOW_CR))
-      flags |= MthIF_CR;
-    if (p->Permit(LMPF_ALLOW_TAB))
-      flags |= MthIF_Tabs;
-    
-    if (crow) {
-       x = crow->getTab(0);
-       y = crow->getBaseline();
-    } 
-    if (!array) {
-           array = new MathedArray; // this leaks
-       p->SetData(array);
-    }
-    size = p->GetStyle();
-    Reset();
+    return MathIsFont((*array)[pos]);
 }
 
 
-string const MathedXIter::GetString() const
+bool MathedIter::IsScript() const
 {
-       string s = MathedIter::GetString();
-       x += mathed_string_width(fcode, size, s);
-       return s;
-}
-
-
-bool MathedXIter::Next()
-{  
-//    lyxerr << "Ne[" << pos << "]";
-   if (!OK()) return false;
-   int w = 0;
-//   lyxerr << "xt ";
-   if (IsInset()) {
-      MathedInset * px = GetInset();
-      w = px->Width();
-      if (px->GetType() == LM_OT_SCRIPT) {
-        if (w > sw) sw = w;
-        w = 0;
-      } else
-       sx = (px->GetLimits()) ? w : 0;
-   } else {  
-      byte c = GetChar();
-      if (c >= ' ') {
-//       lyxerr << "WD[" << fcode << " " << size << " " << c << endl;
-         w = mathed_char_width(fcode, size, c);
-      } else
-      if (c == LM_TC_TAB && p) {
-//      w = p->GetTab(col + 1);
-         w = (crow) ? crow->getTab(col + 1) : 0;
-        //lyxerr << "WW[" << w << "]";
-      } else
-      if (c == LM_TC_CR && p) {
-         x = 0;
-         if (crow && crow->getNext()) {
-             crow = crow->getNext();
-             y = crow->getBaseline();
-             w = crow->getTab(0);
-         }
-//       lyxerr << "WW[" << col " " << row << "|" << w << "]";
-      } else 
-             lyxerr << "No hubo w[" << c << "]!";
-   }
-   if (MathedIter::Next()) {
-//       lyxerr <<"LNX " << pos << endl;
-//       if (sw>0 && GetChar()!= LM_TC_UP && GetChar()!= LM_TC_DOWN) {
-//        w = (sx>sw) ? 0: sw-sx;
-      if ((sw > 0 || sx > 0)
-         && GetChar() != LM_TC_UP && GetChar() != LM_TC_DOWN) {
-         if (sw > 0)
-           w = (sx > sw) ? 0 : sw - sx;
-         sx = sw = 0;
-      }
-      x += w;
-      return true;
-   } else
-     return false;
-}
+    return MathIsScript((*array)[pos]);
+}   
 
 
-void MathedXIter::GoBegin()
+bool MathedIter::IsTab() const
 {
-   Reset();
-   x = y = 0;   
-   sw = sx = 0;
-   if (p) {
-       crow = p->getRowSt();
-       if (crow) {
-          x = crow->getTab(0);
-          y = crow->getBaseline();
-       }
-   }
-}
+    return ((*array)[pos] == LM_TC_TAB);
+}  
 
 
-void MathedXIter::GoLast()
+bool MathedIter::IsCR() const
 {
-   while (Next());
-}
+    return ((*array)[pos] == LM_TC_CR);
+}  
 
 
-void MathedXIter::Adjust()
+MathedIter::MathedIter(MathedArray * d)
+       : array(d)
 {
-   int posx = pos;
-   GoBegin();
-   while (posx > pos && OK()) Next();  
-}
-
-
-bool MathedXIter::Prev()
-{  
-    if (pos == 0 || (pos == 1 && GetChar() >= ' '))
-      return false;
-    
-    int pos2 = pos; // pos1
-    GoBegin();
-    do {
-       ipush();
-       Next();
-    } while (pos<pos2);
-    ipop();
-    
-    return (!IsCR());
+    pos = 0;
+    row = col = 0;
+    fcode = (array && IsFont()) ? (*array)[0]: 0;
 }
 
 
-bool MathedXIter::goNextColumn()
-{  
-    int rowp = row;
-    int colp = col;
-    while (Next() && col == colp);
-    
-    return (col != colp + 1 || rowp != row);
-}
-
-
-bool MathedXIter::Up()
-{
-    if (row == 0) return false;
-    int xp = x;
-    int rowp = row;
-    int colp = col;
-    GoBegin();
-    while (row < rowp - 1) Next();
-    while (x < xp && OK() && !IsCR()) {
-       ipush();
-       Next();
-    }
-    if (col > colp) // || (stck.col == colp && stck.x<= xp && x>xp))
-      ipop();
-    
-    return true;
-}
-
-
-bool MathedXIter::Down()
-{
-    int xp = x;
-    int colp= col;
-    // int rowp = row
-    
-    bool res = (IsCR()) ? true : goNextCode(LM_TC_CR);
-    if (res) {
-        Next();
-       ipush();
-       while (x < xp && OK()) {
-           ipush();
-           Next();
-       }
-       if (col > colp || (stck.col == colp && stck.x <= xp && x > xp))
-         ipop();
-        return true;
-    }
-    return false;
-}
-
-
-void MathedXIter::addRow()
-{
-    if (!crow) {
-       lyxerr[Debug::MATHED] << "MathErr: Attempt to insert new"
-               " line in a subparagraph. " << this << endl;
-
-       return;
-    }
-    // Create new item for the structure    
-    MathedRowSt * r = new MathedRowSt(ncols + 1);
-    if (crow) {
-       r->setNext(crow->getNext());
-       crow->setNext(r);
-    } else {
-       crow = r;
-       r->setNext(0);
-    }    
-    // Fill missed tabs in current row
-    while (col < ncols - 1) 
-      Insert('T', LM_TC_TAB); 
-    //newline
-    Insert('K', LM_TC_CR);
-    
-    ipush();
-    if (!IsCR())
-      goNextCode(LM_TC_CR);
-    
-    // Fill missed tabs in new row
-    while (col < ncols - 1) 
-      Insert('T', LM_TC_TAB);
-    ipop();
-}
-
-
-void MathedXIter::delRow()
-{
-    if (!crow) {
-           lyxerr[Debug::MATHED] << "MathErr: Attempt to delete a line in a subparagraph." << endl;
-       return;
-    }
-    bool line_empty = true;
-    ipush();
-//    while (Next()) {
-    do {
-       if (IsCR()) {
-           break;
-       } else if (!IsTab()) {
-           line_empty = false;
-       }
-    } while (Next());
-    int const p1 = getPos();
-    ipop();
-    
-    if (line_empty) {
-       
-       MathedRowSt * r = crow->getNext();
-       if (r) {
-           crow->setNext(r->getNext());
-           delete r;
-       }
-       join(p1);
-       Delete();
-    } else
-      Clean(p1);
-    
-    checkTabs();    
-}
-
-
-void MathedXIter::ipush()
+void MathedIter::ipush()
 { 
-    MathedIter::ipush();
-    stck.x = x;
-    stck.y = y;
+    stck.fcode = fcode;
+    stck.pos = pos;
+    stck.row = row;
+    stck.col = col; 
 }
 
 
-void MathedXIter::ipop()
+void MathedIter::ipop()
 { 
-    MathedIter::ipop();
-    x = stck.x;
-    y = stck.y;
-    if (p) {
-       crow = p->getRowSt();
-       if (crow)
-         for (int i = 0; i < row; ++i)
-           crow = crow->getNext();
-    }
+    fcode = stck.fcode;
+    pos = stck.pos;
+    row = stck.row;
+    col = stck.col;  
 }
-
-
-void MathedXIter::fitCoord(int /*xx*/, int yy)
-{
-    int xo = 0;
-    int yo = 0;
-    
-    GoBegin();
-    if (p)
-      p->GetXY(xo, yo);
-    // first fit vertically
-    while (crow && OK()) {
-       if (yy >= yo + y - crow->ascent() && yy <= yo + y + crow->descent()) 
-         break;
-       goNextCode(LM_TC_CR);
-       Next();
-    }
-    // now horizontally
-//    while (x<xx && Next());
-}
-
-
-void MathedXIter::setTab(int tx, int tab)
-{
-       if (crow && tab <= ncols) {
-               crow->setTab(tab, tx);
-       } else
-               lyxerr << "MathErr: No tabs allowed here" << endl;
-}
-
-
-void MathedXIter::subMetrics(int a, int d)
-{
-    if (!crow) {
-           lyxerr[Debug::MATHED]
-                   << "MathErr: Attempt to submetric a subparagraph." << endl;
-       return;
-    }
-    crow->ascent(a);
-    crow->descent(d);
-}
-
-
-// This function is not recursive, as MathPar::Metrics is
-void MathedXIter::IMetrics(int pos2, int & width, int & ascent, int & descent)
-{  
-    byte cx;
-    int x1; // ls;
-    int asc = 0;
-    int des = 0;
-    bool limit = false;
-  
-    descent = ascent = width = 0;
-    if (!array) return;
-    if (array->empty()) return;
-//    if  (pos2 > array->last) return;
-    x1 = x; 
-    while (pos < pos2) {
-       cx = GetChar();
-       if (cx >= ' ') {
-           mathed_char_height(FCode(), size, cx, asc, des);
-           if (asc > ascent) ascent = asc;
-           if (des > descent) descent = des;
-           limit = false;
-       } else
-       if (MathIsInset(cx)) {
-           MathedInset * pp = GetInset();
-           if (cx == LM_TC_UP) {
-               if (!asc && p) {
-                   int xx;
-                   int yy;
-                   p->GetXY(xx, yy);
-                   static_cast<MathParInset*>(pp)->GetXY(xx, asc);
-                   asc = yy - asc;
-               }
-               asc += ((limits) ? pp->Height() + 4 : pp->Ascent());
-           } else if (cx == LM_TC_DOWN) {
-                 if (!des && p) {
-                     int xx;
-                     int yy;
-                     p->GetXY(xx, yy);
-                     static_cast<MathParInset*>(pp)->GetXY(xx, des);
-                     if (des - pp->Height() < yy && !asc)
-                       asc = yy - (des - pp->Height());
-                     des -= yy;
-                 }
-                 des += (limit ? pp->Height()+4: pp->Height()-pp->Ascent()/2);
-           } else {
-               asc = pp->Ascent();
-               des = pp->Descent();
-           }
-           if (asc > ascent) ascent = asc;
-           if (des > descent) descent = des;
-           if (cx != LM_TC_UP && cx != LM_TC_DOWN)
-             limit = pp->GetLimits();
-       } else if (cx == LM_TC_TAB) {
-           limit = false;                   
-       } else {
-           lyxerr[Debug::MATHED]
-               << "Mathed Sel-Error: Unrecognized code["
-               << cx << ']' << endl;
-           break;
-       }
-       if (pos < pos2)  Next();
-   }
-    width = x - x1;
-}
-
-
-bool MathedXIter::setNumbered(bool numb)
-{  
-    if (crow) {
-       crow->setNumbered(numb);
-       return true;
-    }
-    
-    return false;
-}
-
-
-bool MathedXIter::setLabel(string const & label)
-{  
-    if (crow) {
-       crow->setLabel(label);
-       return true;
-    }
-    
-    return false;
-}
-
-
-MathedRowSt * MathedXIter::adjustVerticalSt()
-{
-    GoBegin();
-    if (!crow) {
-//     lyxerr << " CRW" << ncols << " ";
-           crow = new MathedRowSt(ncols + 1); // this leaks
-    }
-//    lyxerr<< " CRW[" << crow << "] ";
-    MathedRowSt * mrow = crow;
-    while (OK()) {
-       if (IsCR()) {
-           if (col >= ncols) ncols = col + 1; 
-           MathedRowSt * r = new MathedRowSt(ncols + 1); // this leaks
-//         r->next = crow->next;
-           crow->setNext(r);
-           crow = r;
-//         lyxerr << " CX[" << crow << "]";
-       }   
-       Next(); 
-    }
-    return mrow;
-}
-
-string MathedXIter::error_label = "$mathed-error$";
index f790f667ef633598256233424951b66d13e434f4..29bf9297c1a7f1c2cae3c6e45e4eed8a88ea8599 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "math_defs.h"
 
+class MathedInset;
+
 ///
 enum mathIterFlags {
     /// Allow newlines
@@ -39,117 +41,114 @@ enum mathIterFlags {
     Used for storing and querying data operations
 */
 class MathedIter {
- public:
-    ///
-    MathedIter() {
-       pos = 0;
-       fcode = 0;
-       array = 0;
-       flags = 0;
-       ncols = row = col = 0;
-    }
-    ///
-    explicit
-    MathedIter(MathedArray *);
-    ///
-    virtual ~MathedIter() {}
-    ///
-    bool goNextCode(MathedTextCodes);
-    ///
-    void goPosRel(int);
-    ///
-    void goPosAbs(int);
-    ///
-    int Empty() const { return array->last() <= 1; }
-    ///
-    int OK() const { return array && (pos < array->last()); }
-    ///
-    int IsFirst() const { return (pos == 0); }
-    ///
-    byte GetChar() const;
-    ///
-    string const GetString() const;
-    ///
-    MathedInset * GetInset() const;
-    ///
-    MathParInset * GetActiveInset() const;
-    ///
-    bool IsInset() const;
-    ///
-    bool IsActive() const;
-    ///
-    bool IsFont() const;
-    ///
-    bool IsScript() const;
-    ///
-    bool IsTab() const;
-    ///
-    bool IsCR() const;
-    ///
-    virtual void Reset();
-    ///
-    virtual void Insert(byte, MathedTextCodes c = LM_TC_CONST);
-    ///
-    virtual void Insert(MathedInset *, int t = LM_TC_INSET);
-    ///
-    virtual bool Delete();
-    ///
-    virtual bool Next();
-    /// Check consistency of tabs and newlines
-    void checkTabs();
-    /// Try to adjust tabs in the expected place, as in eqnarrays
-    void adjustTabs();
-    ///
-    short FCode() const { return fcode; }
-    ///
-    int getPos() const { return pos; }
-    ///
-    int getRow() const { return row; }
-    ///
-    int getCol() const { return col; }
-    ///
-    void setNumCols(int n) { ncols = n; }
-    ///
-    void SetData(MathedArray * a) { array = a; Reset(); }
-    ///
-    MathedArray * GetData() const { return array; }
-    
-    /// Copy every object from position p1 to p2
-    MathedArray * Copy(int p1 = 0, int p2 = 10000);
-   
-    /// Delete every object from position p1 to p2
-    void Clear();
-    
- protected:
-    ///
-    void split(int);
-    ///
-    void join(int);
-    ///
-    int flags;
-    ///
-    mutable short fcode;
-    ///
-    mutable int pos;
-    ///
-    int row, col, ncols;
-    ///
-    MathedArray * array;
-    // one element stack
-    struct MIState {
-       ///
-       short fcode;
-       ///
-       int x, y;
-       ///
-       int pos, row, col;
-    };
-    ///
-    MIState stck;
-    /// Saves the current state of the iterator
-    virtual void ipush();
-    /// Recover previous state
-    virtual void ipop();
+public:
+       ///
+       MathedIter() {
+               pos = 0;
+               fcode = 0;
+               array = 0;
+               flags = 0;
+               ncols = row = col = 0;
+       }
+       ///
+       explicit
+       MathedIter(MathedArray *);
+       ///
+       virtual ~MathedIter() {}
+       ///
+       bool goNextCode(MathedTextCodes);
+       ///
+       void goPosRel(int);
+       ///
+       void goPosAbs(int);
+       ///
+       int Empty() const;
+       ///
+       int OK() const;
+       ///
+       int IsFirst() const { return (pos == 0); }
+       ///
+       byte GetChar() const;
+       ///
+       string const GetString() const;
+       ///
+       MathedInset * GetInset() const;
+       ///
+       MathParInset * GetActiveInset() const;
+       ///
+       bool IsInset() const;
+       ///
+       bool IsActive() const;
+       ///
+       bool IsFont() const;
+       ///
+       bool IsScript() const;
+       ///
+       bool IsTab() const;
+       ///
+       bool IsCR() const;
+       ///
+       virtual void Reset();
+       ///
+       virtual void Insert(byte, MathedTextCodes c = LM_TC_CONST);
+       ///
+       virtual void Insert(MathedInset *, int t = LM_TC_INSET);
+       ///
+       virtual bool Delete();
+       ///
+       virtual bool Next();
+       /// Check consistency of tabs and newlines
+       void checkTabs();
+       /// Try to adjust tabs in the expected place, as in eqnarrays
+       void adjustTabs();
+       ///
+       short FCode() const { return fcode; }
+       ///
+       int getPos() const { return pos; }
+       ///
+       int getRow() const { return row; }
+       ///
+       int getCol() const { return col; }
+       ///
+       void setNumCols(int n) { ncols = n; }
+       ///
+       void SetData(MathedArray * a);
+       ///
+       MathedArray * GetData() const;
+       /// Copy every object from position p1 to p2
+       MathedArray * Copy(int p1 = 0, int p2 = 10000);
+       /// Delete every object from position p1 to p2
+       void Clear();
+protected:
+       ///
+       void split(int);
+       ///
+       void join(int);
+       ///
+       int flags;
+       ///
+       mutable short fcode;
+       ///
+       mutable int pos;
+       ///
+       int row, col, ncols;
+       ///
+       MathedArray * array;
+       // one element stack
+       struct MIState {
+               ///
+               short fcode;
+               ///
+               int x, y;
+               ///
+               int pos, row, col;
+       };
+       ///
+       MIState stck;
+       /// Saves the current state of the iterator
+       virtual void ipush();
+       /// Recover previous state
+       virtual void ipop();
 };
 
 ///
@@ -157,246 +156,4 @@ class MathedIter {
 ///
 #define MX_WAS_SUPER 2
 
-
-/**
- A graphic iterator (updates position.) Used for
- metrics and updating cursor position
- */
-class MathedXIter: public MathedIter {
- public:
-    ///
-    MathedXIter()
-           : MathedIter(), sx(0), sw(0) {
-           x = y = size = 0;  p = 0; crow = 0;
-    }
-    //
-    MathedXIter(MathParInset *);
-    ///
-    void SetData(MathParInset *);
-    ///
-    MathParInset * getPar() const { return p; }
-    ///
-    bool Next();
-    ///
-    bool Prev();
-    ///
-    bool Up();
-    ///
-    bool Down();
-    ///
-    bool goNextColumn();
-    ///
-    void GoLast();
-    ///
-    void GoBegin();
-    ///
-    void Adjust();
-    ///
-    inline
-    void GetPos(int &, int &) const;
-    ///
-    inline
-    void GetIncPos(int &, int &) const;
-    ///
-    string const GetString() const;
-    ///
-    int GetX() const;
-    ///
-    int GetY() const;
-    ///
-    void subMetrics(int, int);
-    ///
-    void fitCoord(int, int);
-    /// 
-    void getAD(int & a, int & d) const;
-    
-    /// Create a new row and insert #ncols# tabs.
-    void addRow();
-    ///
-    void delRow();
-    
-    ///
-    bool setLabel(string const & label);
-    ///
-    static string error_label;
-    ///
-    string const & getLabel() const {
-           return crow ? crow->getLabel() : error_label;
-    }
-    ///
-    bool setNumbered(bool);
-       
-    ///
-    void setTab(int, int);
-    /// Merge the array at current position
-    void Merge(MathedArray *);
-    /// Delete every object from current position to pos2
-    void Clean(int pos2);
-    ///
-    MathedRowSt * adjustVerticalSt();
-    
-private:
-    /// This function is not recursive, as MathPar::Metrics is
-    void IMetrics(int, int &, int &, int &);
-    /// Font size (display, text, script, script2) 
-    int size;
-    /// current position
-    mutable int x;
-    ///
-    int y;
-    ///
-    MathParInset * p;
-    
-    // Limits auxiliary variables
-    /// Position and max width of a script
-    int sx, sw;
-    /// true= center, false= left align (default)
-    bool limits;
-    /// Type of previous script
-    short s_type;  
-    ///
-    void ipush();
-    ///
-    void ipop();
-
-protected:
-    /// 
-    MathedRowSt * crow;
-    
-private:
-    ///
-    friend class MathedCursor;
-};
-
-
-//--------------------   Inline functions   --------------------------//
-
-
-inline
-bool MathedIter::IsInset() const
-{
-    return MathIsInset((*array)[pos]);
-}
-inline
-bool MathedIter::IsActive() const
-{
-    return MathIsActive((*array)[pos]);
-}
-
-inline
-bool MathedIter::IsFont() const
-{
-    return MathIsFont((*array)[pos]);
-}
-
-
-inline
-bool MathedIter::IsScript() const
-{
-    return MathIsScript((*array)[pos]);
-}   
-
-inline
-bool MathedIter::IsTab() const
-{
-    return ((*array)[pos] == LM_TC_TAB);
-}  
-
-
-inline
-bool MathedIter::IsCR() const
-{
-    return ((*array)[pos] == LM_TC_CR);
-}  
-
-
-inline
-MathedIter::MathedIter(MathedArray * d)
-       : array(d)
-{
-    pos = 0;
-    row = col = 0;
-    fcode = (array && IsFont()) ? (*array)[0]: 0;
-}
-
-
-inline
-void MathedIter::ipush()
-{ 
-    stck.fcode = fcode;
-    stck.pos = pos;
-    stck.row = row;
-    stck.col = col; 
-}
-
-
-inline
-void MathedIter::ipop()
-{ 
-    fcode = stck.fcode;
-    pos = stck.pos;
-    row = stck.row;
-    col = stck.col;  
-}
-
-
-inline
-void MathedXIter::GetPos(int & xx, int & yy) const
-{ 
-    if (p) 
-      p->GetXY(xx, yy);
-    else {
-           xx = 0;
-           yy = 0;
-    }        
-    xx += x;  yy += y;
-}
-
-
-inline 
-int MathedXIter::GetX() const
-{ 
-    int xx;
-    int dummy_y;
-    GetPos(xx, dummy_y);
-    return xx; 
-}
-
-
-inline 
-int MathedXIter::GetY() const
-{ 
-    int dummy_x;
-    int yy;
-    GetPos(dummy_x, yy);
-    return yy; 
-}
-
-
-inline
-void MathedXIter::GetIncPos(int & xx, int & yy) const
-{ 
-    xx = x;
-    yy = y; 
-}
-
-
-inline
-void MathedXIter::getAD(int & a, int & d) const
-{ 
-    if (crow) {
-       a = crow->ascent();
-       d = crow->descent();
-    } else 
-      if (p) {
-         a = p->Ascent();
-         d = p->Descent();
-      } else {
-         a = d = 0;
-      }
-}
-
-
 #endif
-
index 6acc87bd1a52f9178ebbefab26fe8ba9926e1564..22562489f4b701b57e9e34fc4eba99dea9952b28 100644 (file)
 #include FORMS_H_LOCATION
 
 #ifdef __GNUG__
-#pragma implementation "math_macro.h"
-#pragma implementation "math_defs.h"
+#pragma implementation
 #endif
 
 #include "LString.h"
 #include "math_macro.h"
+#include "array.h"
 #include "math_iter.h"
 #include "math_inset.h"
+#include "math_accentinset.h"
+#include "math_deliminset.h"
+#include "math_fracinset.h"
+#include "math_rowst.h"
 #include "support/lstrings.h"
 #include "debug.h"
 
@@ -484,7 +488,7 @@ void MathMacroTable::builtinMacros()
     iter.Insert(inset, LM_TC_ACTIVE_INSET);
     array = new MathedArray; 
     iter.SetData(array);
-    MathFracInset *frac = new MathFracInset(LM_OT_ATOP);
+    MathFracInset * frac = new MathFracInset(LM_OT_ATOP);
     iter.Insert(frac, LM_TC_ACTIVE_INSET);
     inset->SetData(array);
     array = new MathedArray;
index 6269857f4c468e9ec6cb61769f81fbd9f4946963..cc8ea80f2dde914736dc56807c6379b2ed177247 100644 (file)
 #pragma interface
 #endif
 
-#include "math_defs.h"
-#include "debug.h"
+#include <vector>
 
-///
-typedef MathParInset * MathParInsetP;
-///
-typedef MathedArray * MathedArrayP;
+#include "math_parinset.h"
+#include "debug.h"
 
 class MathMacroTemplate;
 
diff --git a/src/mathed/math_matrixinset.C b/src/mathed/math_matrixinset.C
new file mode 100644 (file)
index 0000000..8c05eb7
--- /dev/null
@@ -0,0 +1,261 @@
+#include <config.h>
+
+#include "math_matrixinset.h"
+#include "math_rowst.h"
+#include "math_xiter.h"
+
+extern int number_of_newlines;
+
+MathMatrixInset::MathMatrixInset(int m, int n, short st)
+       : MathParInset(st, "array", LM_OT_MATRIX), nc(m), nr(0), ws_(m),
+       v_align(0), h_align(nc, 'c')
+{
+    row = 0;
+    flag = 15;
+    if (n > 0) {
+           row = new MathedRowSt(nc+1);
+       MathedXIter it(this);
+       for (int j = 1; j < n; ++j) it.addRow();
+       nr = n;
+       if (nr == 1 && nc > 1) {
+           for (int j = 0; j < nc - 1; ++j) 
+             it.Insert('T', LM_TC_TAB);
+       }
+    } else if (n < 0) {
+           row = new MathedRowSt(nc + 1);
+       nr = 1;
+    }
+}
+
+
+MathMatrixInset::MathMatrixInset(MathMatrixInset * mt)
+       : MathParInset(mt->GetStyle(), mt->GetName(), mt->GetType()),
+         nc(mt->nc), nr(0), ws_(mt->nc), v_align(mt->v_align), h_align(mt->h_align)
+{
+    MathedIter it;
+    it.SetData(mt->GetData());
+    array = it.Copy();
+    if (mt->row != 0) {
+       MathedRowSt * r, * ro= 0, * mrow = mt->row;
+       //mrow = mt->row; // This must be redundant...
+       while (mrow) {
+           r = new MathedRowSt(nc + 1);
+           r->setNumbered(mrow->isNumbered());
+           //if (mrow->label) 
+             r->setLabel(mrow->getLabel());
+           if (!ro) 
+             row = r;
+           else
+             ro->setNext(r);
+           mrow = mrow->getNext();
+           ro = r;
+           ++nr;
+       } 
+    } else         
+      row = 0;
+    flag = mt->flag;
+}
+
+
+MathMatrixInset::~MathMatrixInset()
+{
+    MathedRowSt * r = row;
+    while (r) {
+       MathedRowSt * q = r->getNext();
+       delete r;
+       r = q;
+    }
+}
+
+
+MathedInset * MathMatrixInset::Clone()
+{
+    return new MathMatrixInset(this);
+}
+
+
+void MathMatrixInset::SetAlign(char vv, string const & hh)
+{
+   v_align = vv;
+   h_align = hh.substr(0, nc); // usr just h_align = hh; perhaps
+}
+
+
+// Check the number of tabs and crs
+void MathMatrixInset::SetData(MathedArray * a)
+{
+    if (!a) return;
+    MathedIter it(a);
+    int nn = nc - 1;
+    nr = 1;
+    // count tabs per row
+    while (it.OK()) {
+       if (it.IsTab()) {
+           if (nn < 0) { 
+               it.Delete();
+               continue;
+           } else {
+//           it.Next();
+               --nn;
+           }
+       }
+       if (it.IsCR()) {
+           while (nn > 0) {
+               it.Insert(' ', LM_TC_TAB);
+               --nn;
+           }
+           nn = nc - 1;
+           ++nr;
+       }
+       it.Next();
+    }
+    it.Reset();
+
+    // Automatically inserts tabs around bops
+    // DISABLED because it's very easy to insert tabs 
+    array = a;
+}
+
+
+void MathMatrixInset::draw(Painter & pain, int x, int baseline)
+{
+    MathParInset::draw(pain, x, baseline);
+}
+
+
+
+void MathMatrixInset::Metrics()
+{
+    int i, hl, h = 0;
+    MathedRowSt * cprow= 0;
+
+    if (!row) {
+//     lyxerr << " MIDA ";
+       MathedXIter it(this);
+       row = it.adjustVerticalSt();
+    } 
+    
+    // Clean the arrays      
+    MathedRowSt * cxrow = row;
+    while (cxrow) {   
+       for (i = 0; i <= nc; ++i) cxrow->setTab(i, 0);
+       cxrow = cxrow->getNext();
+    }
+    
+    // Basic metrics
+    MathParInset::Metrics();
+           
+    if (nc <= 1 && !row->getNext()) {
+       row->ascent(ascent);
+       row->descent(descent);
+    }
+    
+    // Vertical positions of each row
+    cxrow = row;     
+    while (cxrow) {
+       for (i = 0; i < nc; ++i) {
+           if (cxrow == row || ws_[i] < cxrow->getTab(i))
+                   ws_[i] = cxrow->getTab(i);
+           if (cxrow->getNext() == 0 && ws_[i] == 0) ws_[i] = df_width;
+       }
+       
+       cxrow->setBaseline((cxrow == row) ?
+                          cxrow->ascent() :
+                  cxrow->ascent() + cprow->descent()
+                          + MATH_ROWSEP + cprow->getBaseline());
+       h += cxrow->ascent() + cxrow->descent() + MATH_ROWSEP;  
+       cprow = cxrow;
+       cxrow = cxrow->getNext();
+    }
+    
+    hl = Descent();
+    h -= MATH_ROWSEP;
+
+    //  Compute vertical align
+    switch (v_align) {
+     case 't': ascent = row->getBaseline(); break;
+     case 'b': ascent = h - hl; break;
+     default:  ascent = (row->getNext()) ? h / 2: h - hl; break;
+    }
+    descent = h - ascent + 2;
+    
+    // Increase ws_[i] for 'R' columns (except the first one)
+    for (i = 1; i < nc; ++i)
+       if (h_align[i] == 'R')
+           ws_[i] += 10*df_width;
+    // Increase ws_[i] for 'C' column
+    if (h_align[0] == 'C')
+       if (ws_[0] < 7*workWidth/8)
+           ws_[0] = 7*workWidth/8;
+
+   // Adjust local tabs
+    cxrow = row;
+    width = MATH_COLSEP;
+    while (cxrow) {   
+           int rg = MATH_COLSEP, ww, lf = 0; //, * w = cxrow->w;
+       for (i = 0; i < nc; ++i) {
+           bool isvoid = false;
+           if (cxrow->getTab(i) <= 0) {
+               cxrow->setTab(i, df_width);
+               isvoid = true;
+           }
+           switch (h_align[i]) {
+           case 'l':
+               lf = 0;
+               break;
+           case 'c':
+               lf = (ws_[i] - cxrow->getTab(i))/2; 
+               break;
+           case 'r':
+           case 'R':
+               lf = ws_[i] - cxrow->getTab(i);
+               break;
+           case 'C':
+               if (cxrow == row)
+                   lf = 0;
+               else if (!cxrow->getNext())
+                    lf = ws_[i] - cxrow->getTab(i);
+               else
+                   lf = (ws_[i] - cxrow->getTab(i))/2; 
+               break;
+           }
+           ww = (isvoid) ? lf : lf + cxrow->getTab(i);
+           cxrow->setTab(i, lf + rg);
+           rg = ws_[i] - ww + MATH_COLSEP;
+           if (cxrow == row) width += ws_[i] + MATH_COLSEP;
+       }
+       cxrow->setBaseline(cxrow->getBaseline() - ascent);
+       cxrow = cxrow->getNext();
+    }
+}
+
+
+void MathMatrixInset::Write(ostream & os, bool fragile)
+{
+       if (GetType() == LM_OT_MATRIX){
+               if (fragile)
+                       os << "\\protect";
+               os << "\\begin{"
+                  << name
+                  << '}';
+               if (v_align == 't' || v_align == 'b') {
+                       os << '['
+                          << char(v_align)
+                          << ']';
+               }
+               os << '{'
+                  << h_align
+                  << "}\n";
+               ++number_of_newlines;
+       }
+       MathParInset::Write(os, fragile);
+       if (GetType() == LM_OT_MATRIX){
+               os << "\n";
+               if (fragile)
+                       os << "\\protect";
+               os << "\\end{"
+                  << name
+                  << '}';
+               ++number_of_newlines;
+       }
+}
diff --git a/src/mathed/math_matrixinset.h b/src/mathed/math_matrixinset.h
new file mode 100644 (file)
index 0000000..38af58f
--- /dev/null
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+#ifndef MATH_MATRIXINSET_H
+#define MATH_MATRIXINSET_H
+
+#include <vector>
+
+#include "math_parinset.h"
+
+/** Multiline math paragraph base class.
+    This is the base to all multiline editable math objects
+    like array and eqnarray. 
+ */
+class MathMatrixInset: public MathParInset {
+ public: 
+    ///
+    explicit
+    MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
+    ///
+    explicit
+    MathMatrixInset(MathMatrixInset *);
+    ///
+    MathedInset * Clone();
+    ///
+    virtual ~MathMatrixInset();
+    ///
+    void draw(Painter &, int, int);
+    ///
+    void Write(std::ostream &, bool fragile);
+    ///
+    void Metrics();
+    ///
+    void SetData(MathedArray *);
+    ///
+    void SetAlign(char, string const &);
+    ///
+    int GetColumns() const { return nc; }
+    ///
+    int GetRows() const { return nr; }
+    ///
+    virtual bool isMatrix() const { return true; }
+
+    /// Use this to manage the extra information independently of paragraph
+    MathedRowSt * getRowSt() const { return row; }
+    ///
+    void setRowSt(MathedRowSt * r) { row = r; }
+    
+ protected:
+    ///  Number of columns & rows
+    int nc;
+    ///
+    int nr;
+    /// tab sizes
+    std::vector<int> ws_;   
+    /// 
+    char v_align; // add approp. type
+    ///
+       //std::vector<char> h_align;
+       string h_align; // a vector would perhaps be more correct
+    /// Vertical structure
+    MathedRowSt * row;
+
+};
+#endif
diff --git a/src/mathed/math_parinset.C b/src/mathed/math_parinset.C
new file mode 100644 (file)
index 0000000..c832dad
--- /dev/null
@@ -0,0 +1,392 @@
+#include <config.h>
+
+#include "math_parinset.h"
+#include "math_iter.h"
+#include "array.h"
+#include "math_xiter.h"
+#include "LColor.h"
+#include "mathed/support.h"
+#include "Painter.h"
+#include "math_parser.h"
+#include "math_rowst.h"
+#include "math_parinset.h"
+
+extern int number_of_newlines;
+
+
+MathedRowSt * MathParInset::getRowSt() const
+{
+       return 0;
+}
+
+
+MathParInset::MathParInset(short st, string const & nm, short ot)
+       : MathedInset(nm, ot, st)
+{
+       array = 0;
+       ascent = 8;
+       width = 4;
+       descent = 0;
+       flag = 1;
+       if (objtype == LM_OT_SCRIPT)
+               flag |= LMPF_SCRIPT;
+}
+
+
+MathParInset::MathParInset(MathParInset * p)
+       : MathedInset(p)
+{
+       flag = p->flag;
+       p->setArgumentIdx(0);
+       MathedIter it(p->GetData());
+       SetData(it.Copy());
+}
+
+
+MathParInset::~MathParInset()
+{
+       if (array) {
+               MathedIter it(array);
+               it.Clear();
+               delete array;
+       }
+}
+
+
+MathedInset * MathParInset::Clone()
+{
+       return new MathParInset(this);
+}
+
+
+void MathParInset::SetData(MathedArray * a)
+{
+       array = a;
+       
+       // A standard paragraph shouldn't have any tabs nor CRs.
+       if (array) {
+               MathedIter it(array);
+               while (it.OK()) {
+                       char c = it.GetChar();
+                       if (c == LM_TC_TAB || c == LM_TC_CR) 
+                               it.Delete();
+                       else
+                               it.Next();
+               }
+       }
+}
+
+
+void 
+MathParInset::draw(Painter & pain, int x, int y)
+{
+       byte cxp = 0;
+       int xp = 0;
+       int asc = df_asc, des = 0;
+       bool limits = false;
+       
+       xo = x;  yo = y; 
+       if (!array || array->empty()) {
+               if (array) {
+                       MathedXIter data(this);
+                       data.GetPos(x, y);
+               }
+               pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+               return;
+       }  
+       MathedXIter data(this);
+       data.GoBegin();
+       while (data.OK()) {
+               data.GetPos(x, y);
+               byte cx = data.GetChar();
+               if (cx >= ' ') {
+                       string s = data.GetString();
+                       drawStr(pain, data.FCode(), size, x, y, s);
+                       mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
+                       limits = false;
+               }
+               else {
+                       if (cx == 0)
+                               break;
+                       if (MathIsInset(cx)) {
+                               int yy = y;
+                               MathedInset * p = data.GetInset();
+                               if (cx == LM_TC_UP) {
+                                       if (limits) {
+                                               x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;  
+                                               yy -= (asc + p->Descent()+4);
+                                       }       
+                                       else
+                                               yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
+                               }
+                               else if (cx == LM_TC_DOWN) {
+                                       if (limits) {
+                                               x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
+                                               yy += des + p->Ascent() + 2;
+                                       } else
+                                               yy += des + p->Ascent()/2;
+                               }
+                               else {
+                                       asc = p->Ascent();
+                                       des = p->Descent();
+                               }
+                               p->draw(pain, x, yy);
+                               if (cx!= LM_TC_UP && cx!= LM_TC_DOWN) {
+                                       limits = p->GetLimits();
+                                       if (limits)
+                                               xp = p->Width();
+                               }
+                               data.Next();
+                       }
+                       else if (cx == LM_TC_TAB) {
+                               if (cxp == cx || cxp == LM_TC_CR || data.IsFirst()) {
+                                       pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+                               }
+                               data.Next();
+                               limits = false;
+                       }
+                       else if (cx == LM_TC_CR) {
+                               if (cxp == LM_TC_TAB || cxp == LM_TC_CR || data.IsFirst()) {
+                                       pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+                               }
+                               data.Next();
+                               limits = false;
+                       }
+                       else {   
+                               lyxerr << "GMathed Error: Unrecognized code[" << cx << "]" << endl;
+                               break;
+                       }
+               }
+               cxp = cx;
+       }
+       if (cxp == LM_TC_TAB || cxp == LM_TC_CR) { 
+               data.GetPos(x, y);
+               pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
+       }
+}
+
+
+void 
+MathParInset::Metrics()
+{
+       byte cx;
+       byte cxp = 0;
+       int ls;
+       int asc = df_asc;
+       int des = 0;
+       int tb = 0;
+       int tab = 0;
+       
+       bool limits = false;
+       
+       ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des); 
+       width = df_width;
+       descent = 0;
+       if (!array) return;
+       if (array->empty()) return;
+       
+       ascent = 0;
+       MathedXIter data(this);
+       data.GoBegin();
+       while (data.OK()) {
+               cx = data.GetChar();      
+               if (cx >= ' ') {
+                       string s = data.GetString();
+                       mathed_string_height(data.FCode(), size, s, asc, des);
+                       if (asc > ascent) ascent = asc;
+                       if (des > descent) descent = des;
+                       limits = false;
+                       mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
+               } else
+                       if (MathIsInset(cx)) {
+                               MathedInset * p = data.GetInset();
+                               p->SetStyle(size);   
+                               p->Metrics();
+                               if (cx == LM_TC_UP) {
+                                       asc += (limits) ? p->Height() + 4: p->Ascent() + 
+                                               ((p->Descent()>asc) ? p->Descent() - asc + 4: 0);
+                               } else
+                                       if (cx == LM_TC_DOWN) {
+                                               des += ((limits) ? p->Height() + 4: p->Height() - p->Ascent() / 2);
+                                       } else {
+                                               asc = p->Ascent();
+                                               des = p->Descent();
+                                       }
+                               if (asc > ascent) ascent = asc;
+                               if (des > descent) descent = des;
+                               if (cx!= LM_TC_UP && cx!= LM_TC_DOWN)
+                                       limits = p->GetLimits();
+                               data.Next();
+                       } else 
+                               if (cx == LM_TC_TAB) {
+                                       int x, y;
+                                       data.GetIncPos(x, y);
+                                       if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
+                                               if (ascent<df_asc) ascent = df_asc;
+                                               tb = x;
+                                       }
+                                       data.setTab(x-tb, tab);
+                                       tb = x;
+                                       ++tab;
+                                       limits = false;                   
+                                       data.Next();
+                               } else
+                                       if (cx == LM_TC_CR) {
+                                               if (tb > 0) {
+                                                       int x, y;
+                                                       data.GetIncPos(x, y);
+                                                       if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
+                                                               if (ascent<df_asc) ascent = df_asc;
+                                                               tb = x;
+                                                       } 
+                                                       data.setTab(x - tb, tab);
+                                               } else //if (GetColumns() == 1) 
+                                                       {
+                                                               int x, y;
+                                                               data.GetIncPos(x, y);
+                                                               data.setTab(x, tab);
+                                                               if (ascent<df_asc) ascent = df_asc;
+                                                       } 
+                                               tb = tab = 0;
+                                               data.subMetrics(ascent, descent);
+                                               ascent = df_asc;   
+                                               descent = 0;
+                                               data.Next();
+                                       } else {
+                                               lyxerr << "Mathed Error: Unrecognized code[" << cx
+                                                      << "]" << endl;
+                                               break;
+                                       }       
+               cxp = cx;
+       }
+       data.GetIncPos(width, ls);
+       
+       // No matter how simple is a matrix, it is NOT a subparagraph
+       if (isMatrix()) {
+               if (cxp == LM_TC_TAB) {
+                       if (ascent<df_asc) ascent = df_asc;
+                       data.setTab(0, tab);
+               } else {
+                       data.setTab(width - tb, tab);
+               }
+       }
+       
+       data.subMetrics(ascent, descent);
+}
+
+
+
+void MathParInset::Write(ostream & os, bool fragile)
+{
+       if (!array) return;
+       int brace = 0;
+       latexkeys * l;
+       MathedIter data(array);
+       // hack
+       MathedRowSt const * crow = getRowSt();   
+       data.Reset();
+       
+       if (!Permit(LMPF_FIXED_SIZE)) { 
+               l = lm_get_key_by_id(size, LM_TK_STY);
+               if (l) {
+                       os << '\\' << l->name << ' ';
+               }
+       }
+       while (data.OK()) {
+               byte cx = data.GetChar();
+               if (cx >= ' ') {
+                       string str = data.GetString();
+                       
+                       if (data.FCode() >= LM_TC_RM && data.FCode() <= LM_TC_TEXTRM) {
+                               os << '\\' << math_font_name[data.FCode()-LM_TC_RM] << '{';
+                       }
+                       for (string::const_iterator s = str.begin();
+                            s != str.end(); ++s) {
+                               byte c = *s;
+                               if (MathIsSymbol(data.FCode())) {
+                                       l = lm_get_key_by_id(c, (data.FCode() == LM_TC_BSYM) ?
+                                                            LM_TK_BIGSYM : LM_TK_SYM);
+                                       if (l) {
+                                               os << '\\' << l->name << ' ';
+                                       } else {
+#warning this does not compile on gcc 2.97
+                                               //lyxerr << "Illegal symbol code[" << c
+                                               //   << " " << str.end() - s << " " << data.FCode() << "]";
+                                       }
+                               } else {
+                                       // Is there a standard logical XOR?
+                                       if ((data.FCode() == LM_TC_TEX && c != '{' && c != '}') ||
+                                           (data.FCode() == LM_TC_SPECIAL))
+                                               os << '\\';
+                                       else {
+                                               if (c == '{') ++brace;
+                                               if (c == '}') --brace;
+                                       }
+                                       if (c == '}' && data.FCode() == LM_TC_TEX && brace < 0) 
+                                               lyxerr <<"Math warning: Unexpected closing brace."
+                                                      << endl;
+                                       else           
+                                               os << char(c);
+                               }
+                       }
+                       if (data.FCode()>= LM_TC_RM && data.FCode()<= LM_TC_TEXTRM)
+                               os << '}';
+               } else     
+                       if (MathIsInset(cx)) {
+                               MathedInset * p = data.GetInset();
+                               if (cx == LM_TC_UP)
+                                       os << "^{";
+                               if (cx == LM_TC_DOWN)
+                                       os << "_{";
+                               p->Write(os, fragile);
+                               if (cx == LM_TC_UP || cx == LM_TC_DOWN)
+                                       os << '}';
+                               data.Next();
+                       } else
+                               switch (cx) {
+                               case LM_TC_TAB:
+                               {
+                                       os << " & ";
+                                       data.Next();
+                                       break;
+                               }
+                               case LM_TC_CR:
+                               {
+                                       if (crow) {
+                                               if (!crow->isNumbered()) {  
+                                                       os << "\\nonumber ";
+                                               }
+                                               if (!crow->getLabel().empty()) {
+                                                       os << "\\label{"
+                                                          << crow->getLabel()
+                                                          << "} ";
+                                               }
+                                               crow = crow->getNext();
+                                       }
+                                       if (fragile)
+                                               os << "\\protect";
+                                       os << "\\\\\n";
+                                       ++number_of_newlines;
+                                       data.Next();
+                                       break;
+                               }
+                               default:
+                                       lyxerr << "WMath Error: unrecognized code[" << cx << "]";
+                                       return;
+                               }     
+       }
+       
+       if (crow) {
+               if (!crow->isNumbered()) {
+                       os << "\\nonumber ";
+               }
+               if (!crow->getLabel().empty()) {
+                       os << "\\label{"
+                          << crow->getLabel()
+                          << "} ";
+               }
+       }
+
+       if (brace > 0)
+               os << string(brace, '}');
+}
diff --git a/src/mathed/math_parinset.h b/src/mathed/math_parinset.h
new file mode 100644 (file)
index 0000000..0493894
--- /dev/null
@@ -0,0 +1,130 @@
+// -*- C++ -*-
+#ifndef MATH_PARINSET_H
+#define MATH_PARINSET_H
+
+#include "math_inset.h"
+
+struct MathedRowSt;
+
+
+/** The math paragraph base class, base to all editable math objects */
+class MathParInset: public MathedInset  {
+ public: 
+    ///
+    MathParInset(short st = LM_ST_TEXT, string const & nm = string(),
+                short ot = LM_OT_MIN);
+    ///
+    explicit
+    MathParInset(MathParInset *);
+    ///
+    virtual ~MathParInset();
+    ///
+    virtual MathedInset * Clone();
+    /// Draw the object on a drawable
+    virtual void draw(Painter &, int x, int baseline);
+    /// Write LaTeX code
+    virtual void Write(std::ostream &, bool fragile);
+    ///
+    virtual void Metrics();
+    ///
+    virtual void UserSetSize(short);
+    /// Data is stored in a LyXArray
+    virtual void SetData(MathedArray *);
+    ///
+    virtual MathedArray * GetData() { return array; }
+    /// Paragraph position
+    virtual void GetXY(int &, int &) const;
+    ///
+    virtual void setXY(int x, int y) { xo = x;  yo = y; }
+    ///
+    virtual void SetFocus(int, int) {}
+    ///
+    virtual bool Inside(int, int);   
+    // Tab stuff used by Matrix.
+    ///
+    virtual void SetAlign(char, string const &) {}
+    ///
+    virtual int GetColumns() const { return 1; }
+    ///
+    virtual int GetRows() const { return 1; }
+    ///
+    virtual bool isMatrix() const { return false; }
+    // Vertical switching
+    ///
+    virtual bool setArgumentIdx(int i) { return (i == 0); }
+    ///
+    virtual bool setNextArgIdx() { return false; }
+    ///
+    virtual int getArgumentIdx() const { return 0; }
+    ///
+    virtual int getMaxArgumentIdx() const { return 0; }
+    ///
+    virtual void SetStyle(short);
+    ///
+    virtual MathedRowSt * getRowSt() const;
+    ///
+    virtual void setRowSt(MathedRowSt *) {}
+    ///
+    virtual bool Permit(short f) const { return bool(f & flag); }
+ protected:
+    /// Paragraph data is stored here
+    MathedArray * array;
+    /// Cursor start position
+    int xo;
+    ///
+    int yo;
+    /// 
+    short flag;
+ private:
+    ///
+    virtual void setFlag(MathedParFlag f) { flag |= f; }
+    ///
+    friend class InsetFormula;
+    ///
+    friend class MathedXIter;
+    ///
+    friend class MathedCursor;
+    ///
+    friend MathedArray * mathed_parse(unsigned flags = 0,
+                                      MathedArray * a = 0,
+                                      MathParInset ** p = 0);
+};
+
+
+inline
+bool MathParInset::Inside(int x, int y) 
+{
+  return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
+}
+
+
+inline
+void MathParInset::GetXY(int & x, int & y) const
+{
+   x = xo; y = yo;
+}
+
+
+inline
+void MathParInset::UserSetSize(short sz)
+{
+   if (sz >= 0) {
+       size = sz;      
+       flag = flag & ~LMPF_FIXED_SIZE;
+   }
+}
+
+
+inline
+void MathParInset::SetStyle(short sz) 
+{
+    if (Permit(LMPF_FIXED_SIZE)) {
+       if (Permit(LMPF_SCRIPT)) 
+         sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
+       if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
+           ++sz;
+       } 
+       MathedInset::SetStyle(sz);
+    }
+}
+#endif
index e495782eb74bad1e3bb90fc2b4708b655fc41046..e0ca1a79b0d808ea7836135706eb5e7e0d47e4b7 100644 (file)
 #include <cctype>
 
 #ifdef __GNUG__
-#pragma implementation "math_parser.h"
+#pragma implementation
 #endif
 
 #include "math_parser.h"
+#include "array.h"
+#include "math_rowst.h"
 #include "math_iter.h"
 #include "math_inset.h"
 #include "math_macro.h"
 #include "math_root.h"
+#include "math_matrixinset.h"
+#include "math_accentinset.h"
+#include "math_bigopinset.h"
+#include "math_funcinset.h"
+#include "math_spaceinset.h"
+#include "math_dotsinset.h"
+#include "math_fracinset.h"
+#include "math_deliminset.h"
+#include "math_decorationinset.h"
 #include "debug.h"
 #include "support/lyxlib.h"
+#include "mathed/support.h"
 
 using std::istream;
 using std::endl;
@@ -82,9 +94,6 @@ char const * latex_mathenv[latex_mathenv_num] = {
 };
 
 
-char const * latex_mathspace[] = {
-   "!", ",", ":", ";", "quad", "qquad"
-};
 
 
 char const * latex_special_chars = "#$%&_{}";
index fff7d1f547b34bf95047f4172fa888d33d800201..155e6e8a28cea2fa366845643115cf5bf5419236 100644 (file)
@@ -19,8 +19,7 @@
 #pragma interface
 #endif
 
-#include "math_defs.h"
-#include "math_inset.h"
+#include "math_sqrtinset.h"
 #include "symbol_def.h"
 #include "LString.h"
 
diff --git a/src/mathed/math_rowst.h b/src/mathed/math_rowst.h
new file mode 100644 (file)
index 0000000..891f765
--- /dev/null
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+#ifndef MATH_ROWST_H
+#define MATH_ROWST_H
+
+#include <vector>
+
+/** The physical structure of a row and aditional information is stored here.
+    It allows to manage the extra info independently of the paragraph data.  
+    Only used for multiline paragraphs.
+ */
+struct MathedRowSt
+{
+       ///
+       typedef std::vector<int> Widths;
+       
+       ///
+       explicit
+       MathedRowSt(int n)
+               : asc_(0), desc_(0), y_(0), widths_(n + 1, 0),
+                 numbered_(true), next_(0)
+               {}
+       /// Should be const but...
+       MathedRowSt * getNext() const  { return next_; }
+       /// ...we couldn't use this.
+       void setNext(MathedRowSt * n) { next_ = n; }
+       ///
+       string const & getLabel() const { return label_; }
+       ///
+       bool isNumbered() const { return numbered_; }
+       ///
+       int  getBaseline() const { return y_; }
+       ///
+       void setBaseline(int b) { y_ = b; }
+       ///
+       int ascent() const { return asc_; }
+       ///
+       int descent() const { return desc_; }
+       ///
+       void ascent(int a) { asc_ = a; }
+       ///
+       void descent(int d) { desc_ = d; }
+       ///
+       int  getTab(int i) const { return widths_[i]; }
+       /// 
+       void setLabel(string const & l) { label_ = l; }
+       ///
+       void setNumbered(bool nf) { numbered_ = nf; }
+       ///
+       void setTab(int i, int t) { widths_[i] = t; }
+private:
+       /// Vericals 
+       int asc_;
+       int desc_;
+       int y_;
+       /// widths 
+       Widths widths_;
+       /// 
+       string label_;
+       ///
+       bool numbered_;
+       ///
+       MathedRowSt * next_;
+};
+#endif
diff --git a/src/mathed/math_spaceinset.C b/src/mathed/math_spaceinset.C
new file mode 100644 (file)
index 0000000..11a51d9
--- /dev/null
@@ -0,0 +1,63 @@
+#include <config.h>
+
+#include "math_spaceinset.h"
+#include "LColor.h"
+#include "Painter.h"
+#include "mathed/support.h"
+
+
+void MathSpaceInset::Metrics()
+{
+       width = space ? space * 2 : 2;
+       if (space > 3) width *= 2;
+       if (space == 5) width *= 2;
+       width += 4;
+       ascent = 4; descent = 0;
+}
+
+
+void MathSpaceInset::SetSpace(int sp)
+{ 
+       space = sp;
+       Metrics();
+}
+
+
+MathSpaceInset::MathSpaceInset(int sp, short ot, short st)
+       : MathedInset("", ot, st), space(sp)
+{}
+
+
+MathedInset * MathSpaceInset::Clone()
+{
+       return new MathSpaceInset(space, GetType(), GetStyle());
+}
+
+
+void
+MathSpaceInset::draw(Painter & pain, int x, int y)
+{ 
+       
+// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
+       
+// Sadly, HP-UX CC can't handle that kind of initialization.
+       
+       int xp[4];
+       int yp[4];
+       
+       xp[0] = ++x;            yp[0] = y - 3;
+       xp[1] = x;                 yp[1] = y;
+       xp[2] = x + width - 2;  yp[2] = y;
+       xp[3] = x + width - 2;  yp[3] = y - 3;
+       
+       pain.lines(xp, yp, 4, (space) ? LColor::latex : LColor::math);
+}
+
+
+void
+MathSpaceInset::Write(ostream & os, bool /* fragile */)
+{
+   if (space >= 0 && space < 6) {
+          os << '\\' << latex_mathspace[space] << ' ';
+   }
+}
diff --git a/src/mathed/math_spaceinset.h b/src/mathed/math_spaceinset.h
new file mode 100644 (file)
index 0000000..33251ed
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef MATH_SPACEINSET_H
+#define MATH_SPACEINSET_H
+
+#include "math_inset.h"
+
+/// Smart spaces
+class MathSpaceInset: public MathedInset  {
+public:
+       ///
+       MathSpaceInset(int sp, short ot = LM_OT_SPACE, short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int, int);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       inline void Metrics();
+       ///
+       inline void SetSpace(int sp);
+       ///
+       int GetSpace() { return space; }
+protected:
+       ///
+       int space;
+};
+#endif
diff --git a/src/mathed/math_sqrtinset.C b/src/mathed/math_sqrtinset.C
new file mode 100644 (file)
index 0000000..1ff4b84
--- /dev/null
@@ -0,0 +1,68 @@
+#include <config.h>
+
+#include "math_sqrtinset.h"
+#include "math_iter.h"
+#include "LColor.h"
+#include "Painter.h"
+#include "support.h"
+
+
+MathSqrtInset::MathSqrtInset(short st)
+       : MathParInset(st, "sqrt", LM_OT_SQRT) {}
+
+
+MathedInset * MathSqrtInset::Clone()
+{   
+       MathSqrtInset * p = new MathSqrtInset(GetStyle());
+       MathedIter it(array);
+       p->SetData(it.Copy());
+       return p;
+}
+
+
+bool MathSqrtInset::Inside(int x, int y) 
+{
+       return x >= xo - hmax
+               && x <= xo + width - hmax
+               && y <= yo + descent
+               && y >= yo - ascent;
+}
+
+
+void
+MathSqrtInset::draw(Painter & pain, int x, int y)
+{ 
+       MathParInset::draw(pain, x + hmax + 2, y); 
+       int h = ascent;
+       int d = descent;
+       int h2 = Height() / 2;
+       int w2 = (Height() > 4 * hmax) ? hmax : hmax / 2; 
+       int xp[4], yp[4];
+       xp[0] = x + hmax + wbody; yp[0] = y - h;
+       xp[1] = x + hmax;         yp[1] = y - h;
+       xp[2] = x + w2;           yp[2] = y + d;
+       xp[3] = x;                yp[3] = y + d - h2;
+       pain.lines(xp, yp, 4, LColor::mathline);
+}
+
+
+void
+MathSqrtInset::Metrics()
+{
+       MathParInset::Metrics();
+       ascent += 4;
+       descent += 2;
+       int a, b;
+       hmax = mathed_char_height(LM_TC_VAR, size, 'I', a, b);
+       if (hmax < 10) hmax = 10;
+       wbody = width + 4;
+       width += hmax + 4;
+}
+
+
+void MathSqrtInset::Write(ostream & os, bool fragile)
+{
+       os << '\\' << name << '{';
+       MathParInset::Write(os, fragile); 
+       os << '}';
+}
diff --git a/src/mathed/math_sqrtinset.h b/src/mathed/math_sqrtinset.h
new file mode 100644 (file)
index 0000000..60a39b3
--- /dev/null
@@ -0,0 +1,26 @@
+
+#ifndef MATH_SQRTINSET_H
+#define MATH_SQRTINSET_H
+
+#include "math_parinset.h"
+
+///
+class MathSqrtInset: public MathParInset {
+public:
+       ///
+       MathSqrtInset(short st = LM_ST_TEXT);
+       ///
+       MathedInset * Clone();
+       ///
+       void draw(Painter &, int x, int baseline);
+       ///
+       void Write(std::ostream &, bool fragile);
+       ///
+       void Metrics();
+       ///
+       bool Inside(int, int);
+private:
+       ///
+       int hmax, wbody;
+};
+#endif
index 233635402657db86006010b3bf9fd78a14ced960..97cfd6d5486b3bc56b3198c27bc032a1441c7862 100644 (file)
@@ -21,6 +21,7 @@
 #include "math_inset.h"
 #include "math_iter.h"
 #include "math_parser.h"
+#include "math_parinset.h"
 #include "support/lstrings.h"
 #include "debug.h"
 
@@ -31,293 +32,8 @@ extern char const * latex_mathenv[];
 extern char * latex_mathspace[];
 
 // quite a hack i know. Should be done with return values...
-static int number_of_newlines;
+int number_of_newlines = 0;
 
-char const * math_font_name[] = {
-   "mathrm",
-   "mathcal",
-   "mathbf",
-   "mathsf",
-   "mathtt",
-   "mathit",
-   "textrm"
-};
-
-
-void
-MathSpaceInset::Write(ostream & os, bool /* fragile */)
-{
-   if (space >= 0 && space < 6) {
-          os << '\\' << latex_mathspace[space] << ' ';
-   }
-}
-
-
-void
-MathDotsInset::Write(ostream & os, bool /* fragile */)
-{
-       os << '\\' << name << ' ';
-}
-
-
-void MathSqrtInset::Write(ostream & os, bool fragile)
-{
-       os << '\\' << name << '{';
-       MathParInset::Write(os, fragile); 
-       os << '}';
-}
-
-
-void MathDelimInset::Write(ostream & os, bool fragile)
-{
-    latexkeys * l = (left != '|') ? lm_get_key_by_id(left, LM_TK_SYM): 0;
-    latexkeys * r = (right != '|') ? lm_get_key_by_id(right, LM_TK_SYM): 0;
-    os << "\\left";
-    if (l) {
-           os << '\\' << l->name << ' ';
-    } else {
-        if (left == '{' || left == '}') {
-               os << '\\' << char(left) << ' ';
-        } else {
-               os << char(left) << ' ';
-        }
-    }
-   MathParInset::Write(os, fragile);
-   os << "\\right";
-   if (r) {
-          os << '\\' << r->name << ' ';
-   } else {
-       if (right == '{' || right == '}') {
-              os << '\\' << char(right) << ' ';
-      } else {
-             os << char(right) << ' ';
-      }
-   }
-}
-
-
-void MathDecorationInset::Write(ostream & os, bool fragile)
-{
-       latexkeys * l = lm_get_key_by_id(deco, LM_TK_WIDE);
-       if (fragile &&
-           (strcmp(l->name, "overbrace") == 0 ||
-            strcmp(l->name, "underbrace") == 0 ||
-            strcmp(l->name, "overleftarrow") == 0 ||
-            strcmp(l->name, "overrightarrow") == 0))
-               os << "\\protect";
-       os << '\\' << l->name << '{';
-       MathParInset::Write(os, fragile);  
-       os << '}';
-}
-
-
-void MathAccentInset::Write(ostream & os, bool fragile)
-{
-       latexkeys * l = lm_get_key_by_id(code, LM_TK_ACCENT);
-       os << '\\' << l->name;
-       if (code!= LM_not)
-               os << '{';
-       else
-               os << ' ';
-       
-       if (inset) {
-               inset->Write(os, fragile);
-       } else {
-               if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM) {
-                       os << '\\'
-                          << math_font_name[fn-LM_TC_RM]
-                          << '{';
-               }
-               if (MathIsSymbol(fn)) {
-                       latexkeys * l = lm_get_key_by_id(c, LM_TK_SYM);
-                       if (l) {
-                               os << '\\' << l->name << ' ';
-                       }
-               } else
-                       os << char(c);
-               
-               if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM)
-                       os << '}';
-       }
-       
-       if (code!= LM_not)
-               os << '}';
-}
-
-
-void MathBigopInset::Write(ostream & os, bool /* fragile */)
-{
-    bool limp = GetLimits();
-    
-    os << '\\' << name;
-    
-    if (limp && !(sym != LM_int && sym != LM_oint
-                 && (GetStyle() == LM_ST_DISPLAY)))
-           os << "\\limits ";
-    else 
-    if (!limp && (sym != LM_int && sym != LM_oint
-                 && (GetStyle() == LM_ST_DISPLAY)))
-           os << "\\nolimits ";
-    else 
-           os << ' ';
-}
-
-
-void MathFracInset::Write(ostream & os, bool fragile)
-{
-       os << '\\' << name << '{';
-       MathParInset::Write(os, fragile);
-       os << "}{";
-       den->Write(os, fragile);
-       os << '}';
-}
-
-
-void MathParInset::Write(ostream & os, bool fragile)
-{
-       if (!array) return;
-       int brace = 0;
-       latexkeys * l;
-       MathedIter data(array);
-       // hack
-       MathedRowSt const * crow = getRowSt();   
-       data.Reset();
-       
-       if (!Permit(LMPF_FIXED_SIZE)) { 
-               l = lm_get_key_by_id(size, LM_TK_STY);
-               if (l) {
-                       os << '\\' << l->name << ' ';
-               }
-       }
-       while (data.OK()) {
-               byte cx = data.GetChar();
-               if (cx >= ' ') {
-                       string str = data.GetString();
-                       
-                       if (data.FCode() >= LM_TC_RM && data.FCode() <= LM_TC_TEXTRM) {
-                               os << '\\' << math_font_name[data.FCode()-LM_TC_RM] << '{';
-                       }
-                       for (string::const_iterator s = str.begin();
-                            s != str.end(); ++s) {
-                               byte c = *s;
-                               if (MathIsSymbol(data.FCode())) {
-                                       l = lm_get_key_by_id(c, (data.FCode() == LM_TC_BSYM) ?
-                                                            LM_TK_BIGSYM : LM_TK_SYM);
-                                       if (l) {
-                                               os << '\\' << l->name << ' ';
-                                       } else {
-#warning this does not compile on gcc 2.97
-                                               //lyxerr << "Illegal symbol code[" << c
-                                               //   << " " << str.end() - s << " " << data.FCode() << "]";
-                                       }
-                               } else {
-                                       // Is there a standard logical XOR?
-                                       if ((data.FCode() == LM_TC_TEX && c != '{' && c != '}') ||
-                                           (data.FCode() == LM_TC_SPECIAL))
-                                               os << '\\';
-                                       else {
-                                               if (c == '{') ++brace;
-                                               if (c == '}') --brace;
-                                       }
-                                       if (c == '}' && data.FCode() == LM_TC_TEX && brace < 0) 
-                                               lyxerr <<"Math warning: Unexpected closing brace."
-                                                      << endl;
-                                       else           
-                                               os << char(c);
-                               }
-                       }
-                       if (data.FCode()>= LM_TC_RM && data.FCode()<= LM_TC_TEXTRM)
-                               os << '}';
-               } else     
-                       if (MathIsInset(cx)) {
-                               MathedInset * p = data.GetInset();
-                               if (cx == LM_TC_UP)
-                                       os << "^{";
-                               if (cx == LM_TC_DOWN)
-                                       os << "_{";
-                               p->Write(os, fragile);
-                               if (cx == LM_TC_UP || cx == LM_TC_DOWN)
-                                       os << '}';
-                               data.Next();
-                       } else
-                               switch (cx) {
-                               case LM_TC_TAB:
-                               {
-                                       os << " & ";
-                                       data.Next();
-                                       break;
-                               }
-                               case LM_TC_CR:
-                               {
-                                       if (crow) {
-                                               if (!crow->isNumbered()) {  
-                                                       os << "\\nonumber ";
-                                               }
-                                               if (!crow->getLabel().empty()) {
-                                                       os << "\\label{"
-                                                          << crow->getLabel()
-                                                          << "} ";
-                                               }
-                                               crow = crow->getNext();
-                                       }
-                                       if (fragile)
-                                               os << "\\protect";
-                                       os << "\\\\\n";
-                                       ++number_of_newlines;
-                                       data.Next();
-                                       break;
-                               }
-                               default:
-                                       lyxerr << "WMath Error: unrecognized code[" << cx << "]";
-                                       return;
-                               }     
-       }
-       
-       if (crow) {
-               if (!crow->isNumbered()) {
-                       os << "\\nonumber ";
-               }
-               if (!crow->getLabel().empty()) {
-                       os << "\\label{"
-                          << crow->getLabel()
-                          << "} ";
-               }
-       }
-
-       if (brace > 0)
-               os << string(brace, '}');
-}
-
-
-void MathMatrixInset::Write(ostream & os, bool fragile)
-{
-    if (GetType() == LM_OT_MATRIX){
-           if (fragile)
-                   os << "\\protect";
-           os << "\\begin{"
-              << name
-              << '}';
-       if (v_align == 't' || v_align == 'b') {
-               os << '['
-                  << char(v_align)
-                  << ']';
-       }
-       os << '{'
-          << h_align
-          << "}\n";
-       ++number_of_newlines;
-    }
-    MathParInset::Write(os, fragile);
-    if (GetType() == LM_OT_MATRIX){
-           os << "\n";
-           if (fragile)
-                   os << "\\protect";
-           os << "\\end{"
-              << name
-              << '}';
-       ++number_of_newlines;
-    }
-}
 
 void mathed_write(MathParInset * p, ostream & os, int * newlines,
                  bool fragile, string const & label)
diff --git a/src/mathed/math_xiter.C b/src/mathed/math_xiter.C
new file mode 100644 (file)
index 0000000..0fa4462
--- /dev/null
@@ -0,0 +1,622 @@
+#include <config.h>
+
+#include "math_xiter.h"
+#include "math_parinset.h"
+#include "math_rowst.h"
+#include "array.h"
+#include "mathed/support.h"
+
+
+MathedXIter::MathedXIter()
+       : MathedIter(), sx(0), sw(0)
+{
+       x = y = size = 0;
+       p = 0;
+       crow = 0;
+}
+
+
+void MathedXIter::GetPos(int & xx, int & yy) const
+{ 
+       if (p) 
+               p->GetXY(xx, yy);
+       else {
+               xx = 0;
+               yy = 0;
+       }        
+       xx += x;
+       yy += y;
+}
+
+
+int MathedXIter::GetX() const
+{ 
+       int xx;
+       int dummy_y;
+       GetPos(xx, dummy_y);
+       return xx; 
+}
+
+
+int MathedXIter::GetY() const
+{ 
+       int dummy_x;
+       int yy;
+       GetPos(dummy_x, yy);
+       return yy; 
+}
+
+
+void MathedXIter::GetIncPos(int & xx, int & yy) const
+{ 
+       xx = x;
+       yy = y; 
+}
+
+
+void MathedXIter::getAD(int & a, int & d) const
+{ 
+       if (crow) {
+               a = crow->ascent();
+               d = crow->descent();
+       } else 
+               if (p) {
+                       a = p->Ascent();
+                       d = p->Descent();
+               } else {
+                       a = d = 0;
+               }
+}
+
+
+
+void MathedXIter::Clean(int pos2)
+{
+       if (!array) {
+               lyxerr << "Math error: Attempting to clean a void array." << endl;
+               return;
+       } 
+       
+       int pos1 = pos;
+       
+       if (pos2 < pos1) {
+               GoBegin();
+               while (pos < pos2 && OK()) {
+                       Next();
+               }
+               pos2 = pos1;
+               pos1 = pos;
+       }
+       
+       ipush();
+       while (OK() && pos < pos2) {
+               if (IsInset()) {
+                       MathedInset * inset = GetInset();
+                       Next();
+                       if (inset->GetType()!= LM_OT_MACRO_ARG)
+                               delete inset;
+                       continue;
+               } 
+               if (IsCR()) {
+                       if (crow) {
+                               MathedRowSt * r = crow->getNext();
+                               if (r) {
+                                       crow->setNext(r->getNext());
+                                       delete r;
+                               }          
+                       }
+               }
+               Next();
+       }    
+       ipop();
+       
+       if (pos2 <= array->last()) {
+               pos = pos1;
+               join(pos2);
+               checkTabs();
+       } 
+}
+
+
+void MathedXIter::Merge(MathedArray * a0)
+{
+       if (!a0) {
+               lyxerr[Debug::MATHED]
+                       << "Math error: Attempting to merge a void array." << endl;
+               
+               return;
+       }
+       // All insets must be clonned
+       MathedIter it(a0);
+       MathedArray * a = it.Copy();
+       
+       // make room for the data 
+       split(a->last());
+       array->mergeF(a, pos, a->last());
+       
+       int pos1 = pos;
+       int pos2 = pos + a->last();
+       
+       goPosAbs(pos1);
+       
+       // Complete rows
+       while (pos < pos2 && OK()) {
+               if (IsCR()) {
+                       if (p && p->Permit(LMPF_ALLOW_CR)) {
+                               MathedRowSt * r = new MathedRowSt(ncols+1);
+                               if (crow) {
+                                       r->setNext(crow->getNext());
+                                       crow->setNext(r);
+                               } else {
+                                       r->setNext(0);
+                               }
+                               crow = r;
+                       } else {
+                               Delete();
+                               --pos2;
+                       }
+               }
+               Next();    
+       }
+       pos2 = getPos();
+       goPosAbs(pos1);
+       checkTabs();
+       goPosAbs(pos2);
+       
+       delete a;
+}
+
+
+
+
+MathedXIter::MathedXIter(MathParInset * pp)
+       : p(pp) 
+{ 
+       x = y = 0;
+       sx = sw = 0;   
+       limits = false;
+       s_type = 0;  
+       if (p) 
+               SetData(p);
+       else {
+               crow = 0;
+               size = 0;
+       }
+}
+
+
+void MathedXIter::SetData(MathParInset * pp)
+{
+       p = pp;
+       x = y = 0;
+       array = p->GetData();
+       ncols = p->GetColumns();
+       crow = p->getRowSt();
+       if (p->Permit(LMPF_ALLOW_CR))
+               flags |= MthIF_CR;
+       if (p->Permit(LMPF_ALLOW_TAB))
+               flags |= MthIF_Tabs;
+       
+       if (crow) {
+               x = crow->getTab(0);
+               y = crow->getBaseline();
+       } 
+       if (!array) {
+               array = new MathedArray; // this leaks
+               p->SetData(array);
+       }
+       size = p->GetStyle();
+       Reset();
+}
+
+
+string const MathedXIter::GetString() const
+{
+       string s = MathedIter::GetString();
+       x += mathed_string_width(fcode, size, s);
+       return s;
+}
+
+
+bool MathedXIter::Next()
+{  
+//    lyxerr << "Ne[" << pos << "]";
+       if (!OK()) return false;
+       int w = 0;
+//   lyxerr << "xt ";
+       if (IsInset()) {
+               MathedInset * px = GetInset();
+               w = px->Width();
+               if (px->GetType() == LM_OT_SCRIPT) {
+                       if (w > sw) sw = w;
+                       w = 0;
+               } else
+                       sx = (px->GetLimits()) ? w : 0;
+       } else {  
+               byte c = GetChar();
+               if (c >= ' ') {
+//       lyxerr << "WD[" << fcode << " " << size << " " << c << endl;
+                       w = mathed_char_width(fcode, size, c);
+               } else
+                       if (c == LM_TC_TAB && p) {
+//      w = p->GetTab(col + 1);
+                               w = (crow) ? crow->getTab(col + 1) : 0;
+                               //lyxerr << "WW[" << w << "]";
+                       } else
+                               if (c == LM_TC_CR && p) {
+                                       x = 0;
+                                       if (crow && crow->getNext()) {
+                                               crow = crow->getNext();
+                                               y = crow->getBaseline();
+                                               w = crow->getTab(0);
+                                       }
+//       lyxerr << "WW[" << col " " << row << "|" << w << "]";
+                               } else 
+                                       lyxerr << "No hubo w[" << c << "]!";
+       }
+       if (MathedIter::Next()) {
+//       lyxerr <<"LNX " << pos << endl;
+//       if (sw>0 && GetChar()!= LM_TC_UP && GetChar()!= LM_TC_DOWN) {
+//        w = (sx>sw) ? 0: sw-sx;
+               if ((sw > 0 || sx > 0)
+                   && GetChar() != LM_TC_UP && GetChar() != LM_TC_DOWN) {
+                       if (sw > 0)
+                               w = (sx > sw) ? 0 : sw - sx;
+                       sx = sw = 0;
+               }
+               x += w;
+               return true;
+       } else
+               return false;
+}
+
+
+void MathedXIter::GoBegin()
+{
+       Reset();
+       x = y = 0;   
+       sw = sx = 0;
+       if (p) {
+               crow = p->getRowSt();
+               if (crow) {
+                       x = crow->getTab(0);
+                       y = crow->getBaseline();
+               }
+       }
+}
+
+
+void MathedXIter::GoLast()
+{
+       while (Next());
+}
+
+
+void MathedXIter::Adjust()
+{
+       int posx = pos;
+       GoBegin();
+       while (posx > pos && OK()) Next();  
+}
+
+
+bool MathedXIter::Prev()
+{  
+       if (pos == 0 || (pos == 1 && GetChar() >= ' '))
+               return false;
+       
+       int pos2 = pos; // pos1
+       GoBegin();
+       do {
+               ipush();
+               Next();
+       } while (pos<pos2);
+       ipop();
+       
+       return (!IsCR());
+}
+
+
+bool MathedXIter::goNextColumn()
+{  
+       int rowp = row;
+       int colp = col;
+       while (Next() && col == colp);
+       
+       return (col != colp + 1 || rowp != row);
+}
+
+
+bool MathedXIter::Up()
+{
+       if (row == 0) return false;
+       int xp = x;
+       int rowp = row;
+       int colp = col;
+       GoBegin();
+       while (row < rowp - 1) Next();
+       while (x < xp && OK() && !IsCR()) {
+               ipush();
+               Next();
+       }
+       if (col > colp) // || (stck.col == colp && stck.x<= xp && x>xp))
+               ipop();
+       
+       return true;
+}
+
+
+bool MathedXIter::Down()
+{
+       int xp = x;
+       int colp= col;
+       // int rowp = row
+       
+       bool res = (IsCR()) ? true : goNextCode(LM_TC_CR);
+       if (res) {
+               Next();
+               ipush();
+               while (x < xp && OK()) {
+                       ipush();
+                       Next();
+               }
+               if (col > colp || (stck.col == colp && stck.x <= xp && x > xp))
+                       ipop();
+               return true;
+       }
+       return false;
+}
+
+
+
+void MathedXIter::addRow()
+{
+       if (!crow) {
+               lyxerr[Debug::MATHED] << "MathErr: Attempt to insert new"
+                       " line in a subparagraph. " << this << endl;
+               
+               return;
+       }
+       // Create new item for the structure    
+       MathedRowSt * r = new MathedRowSt(ncols + 1);
+       if (crow) {
+               r->setNext(crow->getNext());
+               crow->setNext(r);
+       } else {
+               crow = r;
+               r->setNext(0);
+       }    
+       // Fill missed tabs in current row
+       while (col < ncols - 1) 
+               Insert('T', LM_TC_TAB); 
+       //newline
+       Insert('K', LM_TC_CR);
+       
+       ipush();
+       if (!IsCR())
+               goNextCode(LM_TC_CR);
+       
+       // Fill missed tabs in new row
+       while (col < ncols - 1) 
+               Insert('T', LM_TC_TAB);
+       ipop();
+}
+
+
+void MathedXIter::delRow()
+{
+       if (!crow) {
+               lyxerr[Debug::MATHED] << "MathErr: Attempt to delete a line in a subparagraph." << endl;
+               return;
+       }
+       bool line_empty = true;
+       ipush();
+//    while (Next()) {
+       do {
+               if (IsCR()) {
+                       break;
+               } else if (!IsTab()) {
+                       line_empty = false;
+               }
+       } while (Next());
+       int const p1 = getPos();
+       ipop();
+       
+       if (line_empty) {
+               
+               MathedRowSt * r = crow->getNext();
+               if (r) {
+                       crow->setNext(r->getNext());
+                       delete r;
+               }
+               join(p1);
+               Delete();
+       } else
+               Clean(p1);
+       
+       checkTabs();    
+}
+
+
+void MathedXIter::ipush()
+{ 
+       MathedIter::ipush();
+       stck.x = x;
+       stck.y = y;
+}
+
+
+void MathedXIter::ipop()
+{ 
+       MathedIter::ipop();
+       x = stck.x;
+       y = stck.y;
+       if (p) {
+               crow = p->getRowSt();
+               if (crow)
+                       for (int i = 0; i < row; ++i)
+                               crow = crow->getNext();
+       }
+}
+
+
+void MathedXIter::fitCoord(int /*xx*/, int yy)
+{
+       int xo = 0;
+       int yo = 0;
+       
+       GoBegin();
+       if (p)
+               p->GetXY(xo, yo);
+       // first fit vertically
+       while (crow && OK()) {
+               if (yy >= yo + y - crow->ascent() && yy <= yo + y + crow->descent()) 
+                       break;
+               goNextCode(LM_TC_CR);
+               Next();
+       }
+       // now horizontally
+//    while (x<xx && Next());
+}
+
+
+void MathedXIter::setTab(int tx, int tab)
+{
+       if (crow && tab <= ncols) {
+               crow->setTab(tab, tx);
+       } else
+               lyxerr << "MathErr: No tabs allowed here" << endl;
+}
+
+
+void MathedXIter::subMetrics(int a, int d)
+{
+       if (!crow) {
+               lyxerr[Debug::MATHED]
+                       << "MathErr: Attempt to submetric a subparagraph." << endl;
+               return;
+       }
+       crow->ascent(a);
+       crow->descent(d);
+}
+
+
+// This function is not recursive, as MathPar::Metrics is
+void MathedXIter::IMetrics(int pos2, int & width, int & ascent, int & descent)
+{  
+       byte cx;
+       int x1; // ls;
+       int asc = 0;
+       int des = 0;
+       bool limit = false;
+       
+       descent = ascent = width = 0;
+       if (!array) return;
+       if (array->empty()) return;
+//    if  (pos2 > array->last) return;
+       x1 = x; 
+       while (pos < pos2) {
+               cx = GetChar();
+               if (cx >= ' ') {
+                       mathed_char_height(FCode(), size, cx, asc, des);
+                       if (asc > ascent) ascent = asc;
+                       if (des > descent) descent = des;
+                       limit = false;
+               } else
+                       if (MathIsInset(cx)) {
+                               MathedInset * pp = GetInset();
+                               if (cx == LM_TC_UP) {
+                                       if (!asc && p) {
+                                               int xx;
+                                               int yy;
+                                               p->GetXY(xx, yy);
+                                               static_cast<MathParInset*>(pp)->GetXY(xx, asc);
+                                               asc = yy - asc;
+                                       }
+                                       asc += ((limits) ? pp->Height() + 4 : pp->Ascent());
+                               } else if (cx == LM_TC_DOWN) {
+                                       if (!des && p) {
+                                               int xx;
+                                               int yy;
+                                               p->GetXY(xx, yy);
+                                               static_cast<MathParInset*>(pp)->GetXY(xx, des);
+                                               if (des - pp->Height() < yy && !asc)
+                                                       asc = yy - (des - pp->Height());
+                                               des -= yy;
+                                       }
+                                       des += (limit ? pp->Height()+4: pp->Height()-pp->Ascent()/2);
+                               } else {
+                                       asc = pp->Ascent();
+                                       des = pp->Descent();
+                               }
+                               if (asc > ascent) ascent = asc;
+                               if (des > descent) descent = des;
+                               if (cx != LM_TC_UP && cx != LM_TC_DOWN)
+                                       limit = pp->GetLimits();
+                       } else if (cx == LM_TC_TAB) {
+                               limit = false;                   
+                       } else {
+                               lyxerr[Debug::MATHED]
+                                       << "Mathed Sel-Error: Unrecognized code["
+                                       << cx << ']' << endl;
+                               break;
+                       }
+               if (pos < pos2)  Next();
+       }
+       width = x - x1;
+}
+
+
+bool MathedXIter::setNumbered(bool numb)
+{  
+       if (crow) {
+               crow->setNumbered(numb);
+               return true;
+       }
+       
+       return false;
+}
+
+
+bool MathedXIter::setLabel(string const & label)
+{  
+       if (crow) {
+               crow->setLabel(label);
+               return true;
+       }
+       
+       return false;
+}
+
+
+MathedRowSt * MathedXIter::adjustVerticalSt()
+{
+       GoBegin();
+       if (!crow) {
+//     lyxerr << " CRW" << ncols << " ";
+               crow = new MathedRowSt(ncols + 1); // this leaks
+       }
+//    lyxerr<< " CRW[" << crow << "] ";
+       MathedRowSt * mrow = crow;
+       while (OK()) {
+               if (IsCR()) {
+                       if (col >= ncols) ncols = col + 1; 
+                       MathedRowSt * r = new MathedRowSt(ncols + 1); // this leaks
+//         r->next = crow->next;
+                       crow->setNext(r);
+                       crow = r;
+//         lyxerr << " CX[" << crow << "]";
+               }   
+               Next(); 
+       }
+       return mrow;
+}
+
+
+string const &  MathedXIter::getLabel() const
+{
+       return crow ? crow->getLabel() : error_label;
+}
+
+
+string MathedXIter::error_label = "$mathed-error$";
diff --git a/src/mathed/math_xiter.h b/src/mathed/math_xiter.h
new file mode 100644 (file)
index 0000000..b97aaaf
--- /dev/null
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+#ifndef MATH_XITER_H
+#define MATH_XITER_H
+
+#include "math_iter.h"
+
+struct MathedRowSt;
+
+/**
+ A graphic iterator (updates position.) Used for
+ metrics and updating cursor position
+ */
+class MathedXIter: public MathedIter {
+  public:
+  ///
+  MathedXIter();
+    //
+    MathedXIter(MathParInset *);
+    ///
+    void SetData(MathParInset *);
+    ///
+    MathParInset * getPar() const { return p; }
+    ///
+    bool Next();
+    ///
+    bool Prev();
+    ///
+    bool Up();
+    ///
+    bool Down();
+    ///
+    bool goNextColumn();
+    ///
+    void GoLast();
+    ///
+    void GoBegin();
+    ///
+    void Adjust();
+    ///
+    inline
+    void GetPos(int &, int &) const;
+    ///
+    inline
+    void GetIncPos(int &, int &) const;
+    ///
+    string const GetString() const;
+    ///
+    int GetX() const;
+    ///
+    int GetY() const;
+    ///
+    void subMetrics(int, int);
+    ///
+    void fitCoord(int, int);
+    /// 
+    void getAD(int & a, int & d) const;
+    
+    /// Create a new row and insert #ncols# tabs.
+    void addRow();
+    ///
+    void delRow();
+    
+    ///
+    bool setLabel(string const & label);
+    ///
+    static string error_label;
+    ///
+    string const & getLabel() const;
+    ///
+    bool setNumbered(bool);
+       
+    ///
+    void setTab(int, int);
+    /// Merge the array at current position
+    void Merge(MathedArray *);
+    /// Delete every object from current position to pos2
+    void Clean(int pos2);
+    ///
+    MathedRowSt * adjustVerticalSt();
+    
+private:
+    /// This function is not recursive, as MathPar::Metrics is
+    void IMetrics(int, int &, int &, int &);
+    /// Font size (display, text, script, script2) 
+    int size;
+    /// current position
+    mutable int x;
+    ///
+    int y;
+    ///
+    MathParInset * p;
+    
+    // Limits auxiliary variables
+    /// Position and max width of a script
+    int sx, sw;
+    /// true= center, false= left align (default)
+    bool limits;
+    /// Type of previous script
+    short s_type;  
+    ///
+    void ipush();
+    ///
+    void ipop();
+
+protected:
+    /// 
+    MathedRowSt * crow;
+    
+private:
+    ///
+    friend class MathedCursor;
+};
+#endif
diff --git a/src/mathed/matriz.C b/src/mathed/matriz.C
new file mode 100644 (file)
index 0000000..5efc33b
--- /dev/null
@@ -0,0 +1,60 @@
+#include <config.h>
+
+#include <cstring>
+
+#include "matriz.h"
+
+inline
+int odd(int x) { return ((x) & 1); }
+
+typedef float matriz_data[2][2];
+
+const matriz_data MATIDEN= { {1, 0}, {0, 1}};
+
+#define mateq(m1, m2)  memcpy(m1, m2, sizeof(matriz_data))
+
+Matriz::Matriz()
+{
+       mateq(m, MATIDEN);
+}
+
+
+void Matriz::rota(int code)
+{
+   float cs, sn;
+   
+   matriz_data r;
+   mateq(r, MATIDEN);
+   cs = (odd(code)) ? 0: 1 - code;
+   sn = (odd(code)) ? 2 - code: 0;
+   r[0][0] = cs;         r[0][1] = sn;
+   r[1][0] = -r[0][1];   r[1][1] = r[0][0];
+   matmat(r);
+}
+
+
+void Matriz::escala(float x, float y)
+{
+   matriz_data s;
+   mateq(s, MATIDEN);
+   s[0][0] = x;  s[1][1] = y;
+   matmat(s);
+}
+
+
+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];
+   }
+   mateq(m, c);
+}
+
+
+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;
+}
diff --git a/src/mathed/matriz.h b/src/mathed/matriz.h
new file mode 100644 (file)
index 0000000..ce82122
--- /dev/null
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+
+#ifndef MATH_MATRIZ_H
+#define MATH_MATRIZ_H
+
+typedef float matriz_data[2][2];
+
+class Matriz {
+ public: 
+   Matriz();
+   void rota(int);
+   void escala(float, float);
+   void transf(float, float, float &, float &);
+ protected:
+   matriz_data m;
+   void matmat(matriz_data & a);
+};
+
+#endif
diff --git a/src/mathed/support.C b/src/mathed/support.C
new file mode 100644 (file)
index 0000000..80506da
--- /dev/null
@@ -0,0 +1,453 @@
+#include <config.h>
+
+#include <algorithm>
+
+#include "mathed/support.h"
+#include "lyxfont.h"
+#include "font.h"
+#include "math_defs.h"
+#include "Painter.h"
+#include "matriz.h"
+#include "symbol_def.h"
+
+extern LyXFont WhichFont(short type, int size);
+
+char const * math_font_name[] = {
+   "mathrm",
+   "mathcal",
+   "mathbf",
+   "mathsf",
+   "mathtt",
+   "mathit",
+   "textrm"
+};
+
+
+char const * latex_mathspace[] = {
+   "!", ",", ":", ";", "quad", "qquad"
+};
+
+/* 
+ * 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
+ */
+
+
+static
+float parenthHigh[] = {
+    2.0, 13.0, 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772, 0.2540, 
+    0.1278, 0.1746, 0.1966, 0.0952, 0.3300, 0.0950, 0.5000, 0.0952, 0.6700, 
+    0.1746, 0.8034, 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677, 0.9840, 
+    0.9986, 0.0 
+};
+
+
+static float parenth[] = {
+  2.0, 13.0,
+  0.9930, 0.0071,  0.7324, 0.0578,  0.5141, 0.1126,  0.3380, 0.1714,
+  0.2183, 0.2333,  0.0634, 0.3621,  0.0141, 0.5000,  0.0563, 0.6369,
+  0.2113, 0.7647,  0.3310, 0.8276,  0.5070, 0.8864,  0.7254, 0.9412,
+  0.9930, 0.9919,
+  0.0   
+};
+
+
+static float brace[] = {
+  2.0, 21.0,
+  0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243, 0.5819, 0.0527,
+  0.4859, 0.0892, 0.4463, 0.1278, 0.4463, 0.3732, 0.4011, 0.4199,
+  0.2712, 0.4615, 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
+  0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268, 0.4463, 0.8722,
+  0.4859, 0.9108, 0.5819, 0.9473, 0.7458, 0.9757, 0.9379, 0.9980,
+  0.9492, 0.9980,
+  0.0
+};
+
+static float arrow[] = {
+   4, 7,
+   0.015, 0.7500,  0.2, 0.6,  0.35, 0.35,  0.5, 0.05,
+   0.65, 0.35,  0.8, 0.6,  0.95, 0.7500,
+   3, 0.5, 0.15,  0.5, 0.95,
+   0.0 
+};
+
+static float Arrow[] = {
+   4, 7,
+   0.015, 0.7500,  0.2, 0.6,  0.35, 0.35,  0.5, 0.05,
+   0.65, 0.35,  0.8, 0.6,  0.95, 0.7500,
+   3, 0.35, 0.5, 0.35, 0.95,
+   3, 0.65, 0.5, 0.65, 0.95,
+   0.0
+};
+
+static float udarrow[] = {
+   2, 3,
+   0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
+   2, 3,
+   0.015, 0.75,  0.5, 0.95, 0.95, 0.75,  
+   1, 0.5, 0.2,  0.5, 0.8,
+   0.0 
+};
+
+static float Udarrow[] = {
+   2, 3,
+   0.015, 0.25,  0.5, 0.05, 0.95, 0.25,
+   2, 3,
+   0.015, 0.75,  0.5, 0.95, 0.95, 0.75,  
+   1, 0.35, 0.2, 0.35, 0.8,
+   1, 0.65, 0.2, 0.65, 0.8,
+   0.0 
+};
+
+static float brack[] = {
+   2.0, 4,
+   0.95, 0.05,  0.05, 0.05,  0.05, 0.95,  0.95, 0.95,
+   0.0
+};
+
+static float corner[] = {
+   2.0, 3,
+   0.95, 0.05,  0.05, 0.05,  0.05, 0.95,
+   0.0
+};
+
+static float angle[] = {
+   2.0, 3,
+   1, 0,  0.05, 0.5,  1, 1,
+   0.0
+};
+
+static float slash[] = {
+   1, 0.95, 0.05,  0.05, 0.95, 
+   0.0
+};
+
+static float hline[] = {
+   1, 0.05, 0.5,  0.95, 0.5, 
+   0.0
+};
+
+
+static float hline2[] = {
+   1, 0.1, 0.5,  0.3, 0.5,
+   1, 0.7, 0.5,  0.9, 0.5,
+   0.0
+}; 
+
+static float hline3[] = {
+   1, 0.1, 0,  0.15, 0,
+   1, 0.475, 0,  0.525, 0,
+   1, 0.85, 0,  0.9, 0,  
+   0.0
+};
+
+
+static float dline3[] = {
+   1, 0.1, 0.1,  0.15, 0.15,
+   1, 0.475, 0.475,  0.525, 0.525,
+   1, 0.85, 0.85,  0.9, 0.9,
+   0.0
+};     
+
+static float hlinesmall[] = {
+   1, 0.4, 0.5,  0.6, 0.5, 
+   0.0
+};
+
+static float vert[] = {
+   1, 0.5, 0.05,  0.5, 0.95, 
+   0.0
+};
+
+static float Vert[] = {
+   1, 0.3, 0.05,  0.3, 0.95, 
+   1, 0.7, 0.05,  0.7, 0.95,
+   0.0
+};
+
+static float tilde[] = {
+   2.0, 4,
+   0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
+   0.0
+};
+
+
+static
+math_deco_struct math_deco_table[] = {   
+
+   // Decorations
+  { LM_widehat, &angle[0], 3 },
+  { LM_widetilde, &tilde[0], 0 },
+  { LM_underline, &hline[0], 0 },
+  { LM_overline, &hline[0], 0 },
+  { LM_underbrace, &brace[0], 1 },
+  { LM_overbrace,  &brace[0], 3 },
+  { LM_overleftarrow, &arrow[0], 1 },
+  { LM_overightarrow, &arrow[0], 3 },
+     
+  // Delimiters
+  { '(', &parenth[0], 0 },
+  { ')', &parenth[0], 2 },
+  { '{', &brace[0], 0 },
+  { '}', &brace[0], 2 },
+  { '[', &brack[0], 0 },
+  { ']', &brack[0], 2 },
+  { '|', &vert[0], 0 },
+  { '/', &slash[0], 0 },
+  { LM_Vert, &Vert[0], 0 },
+  { LM_backslash, &slash[0], 1 },
+  { LM_langle, &angle[0], 0 },
+  { LM_lceil, &corner[0], 0 }, 
+  { LM_lfloor, &corner[0], 1 },  
+  { LM_rangle, &angle[0], 2 }, 
+  { LM_rceil, &corner[0], 3 }, 
+  { LM_rfloor, &corner[0], 2 },
+  { LM_downarrow, &arrow[0], 2 },
+  { LM_Downarrow, &Arrow[0], 2 }, 
+  { LM_uparrow, &arrow[0], 0 },
+  { LM_Uparrow, &Arrow[0], 0 },
+  { LM_updownarrow, &udarrow[0], 0 },
+  { LM_Updownarrow, &Udarrow[0], 0 },   
+
+  // Accents   
+  { LM_ddot, &hline2[0], 0 },
+  { LM_hat, &angle[0], 3 },
+  { LM_grave, &slash[0], 1 },
+  { LM_acute, &slash[0], 0 },
+  { LM_tilde, &tilde[0], 0 },
+  { LM_bar, &hline[0], 0 },
+  { LM_dot, &hlinesmall[0], 0 },
+  { LM_check, &angle[0], 1 },
+  { LM_breve, &parenth[0], 1 },
+  { LM_vec, &arrow[0], 3 },
+  { LM_not, &slash[0], 0 },  
+
+  // Dots
+  { LM_ldots, &hline3[0], 0 }, 
+  { LM_cdots, &hline3[0], 0 },
+  { LM_vdots, &hline3[0], 1 },
+  { LM_ddots, &dline3[0], 0 }
+};
+
+
+struct math_deco_compare {
+       /// for use by sort and lower_bound
+       inline
+       int operator()(math_deco_struct const & a,
+                      math_deco_struct const & b) const {
+               return a.code < b.code;
+       }
+};
+
+
+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;
+
+
+int mathed_char_height(short type, int size, byte c, int & asc, int & des)
+{
+   LyXFont font = WhichFont(type, size);
+   des = lyxfont::descent(c, font);
+   asc = lyxfont::ascent(c, font);
+   return asc + des;
+}
+
+
+int mathed_char_width(short type, int size, byte c)
+{
+       if (MathIsBinary(type)) {
+               string s;
+               s += c;
+               return mathed_string_width(type, size, s);
+       }
+       else
+    return lyxfont::width(c, WhichFont(type, size));
+}
+
+
+int mathed_string_height(short type, int size, string const & s,
+                        int & asc, int & des)
+{
+       LyXFont font = WhichFont(type, size);
+       asc = des = 0;
+       for (string::const_iterator it = s.begin(); it != s.end(); ++it) {
+               des = max(des, lyxfont::descent(*it, font));
+               asc = max(asc, lyxfont::ascent(*it, font));
+       }
+       return asc + des;
+}
+
+
+int mathed_string_width(short type, int size, string const & s)
+{
+       string st;
+       if (MathIsBinary(type))
+               for (string::const_iterator it = s.begin();
+                    it != s.end(); ++it) {
+                       st += ' ';
+                       st += *it;
+                       st += ' ';
+               }
+       else
+               st = s;
+
+       LyXFont const f = WhichFont(type, size);
+       return lyxfont::width(st, f);
+}
+
+
+LyXFont mathed_get_font(short type, int size)
+{
+       LyXFont f = WhichFont(type, size);
+       if (type == LM_TC_TEX) {
+               f.setLatex(LyXFont::ON);
+       }
+       return f;
+}
+
+
+void mathed_draw_deco(Painter & pain, int x, int y, int w, int h, int code)
+{
+       Matriz mt;
+       Matriz sqmt;
+       float xx;
+       float yy;
+       float x2;
+       float 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 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 = 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);
+   
+       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);
+}
+
+
+#define USE_EXCEPTIONS 0
+#if USE_EXCEPTIONS
+struct deco_not_found {};
+
+
+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;
+       throw deco_not_found();
+}
+
+#else
+
+
+math_deco_struct const * search_deco(int code)
+{
+       math_deco_struct search_elem = { code, 0, 0 };
+       
+       math_deco_struct * res =
+               lower_bound(math_deco_table,
+                           math_deco_table + math_deco_table_size,
+                           search_elem, math_deco_compare());
+       if (res != math_deco_table + math_deco_table_size &&
+           res->code == code)
+               return res;
+       return 0;
+}
+#endif
diff --git a/src/mathed/support.h b/src/mathed/support.h
new file mode 100644 (file)
index 0000000..ee74a90
--- /dev/null
@@ -0,0 +1,34 @@
+// -*- C++ -*-
+
+#ifndef MATH_SUPPORT_H
+#define MATH_SUPPORT_H
+
+#include "lyxfont.h"
+
+#ifndef byte
+#define byte unsigned char
+#endif
+
+class Painter;
+
+struct math_deco_struct {
+       int code;
+       float * data;
+       int angle;
+};
+
+extern char const * math_font_name[];
+extern char const * latex_mathspace[];
+
+extern int mathed_char_height(short type, int size, byte c,
+                             int & asc, int & des);
+extern int mathed_char_width(short type, int size, byte c);
+extern void mathed_draw_deco(Painter & pain, int x, int y,
+                            int w, int h, int code);
+
+extern LyXFont mathed_get_font(short type, int size);
+extern int mathed_string_height(short type, int size, string const & s,
+                               int & asc, int & des);
+extern int mathed_string_width(short type, int size, string const & s);
+extern math_deco_struct const * search_deco(int code);
+#endif