+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
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 \
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
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);
}
#include <vector>
+#include "math_defs.h"
class MathedInset;
#pragma interface
#endif
-#ifndef byte
-#define byte unsigned char
-#endif
-
/** \class MathedArray
\brief A resizable array.
#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;
MathedCursor * InsetFormula::mathcursor = 0;
-
-int MathedInset::df_asc;
-int MathedInset::df_des;
-int MathedInset::df_width;
-int MathedInset::workWidth;
+void mathed_init_fonts();
static
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;
}
}
-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);
+ }
}
}
-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)
--- /dev/null
+
+#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
--- /dev/null
+#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 << '}';
+}
--- /dev/null
+// -*- 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
--- /dev/null
+#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 << ' ';
+}
--- /dev/null
+// -*- 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
#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;
#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
--- /dev/null
+#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 << '}';
+}
--- /dev/null
+#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
#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 {
///
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 {
};
-/** 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;
-
-};
}
-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)
{
#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;
* 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;
- }
-}
--- /dev/null
+#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;
+}
--- /dev/null
+// -*- 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
--- /dev/null
+#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 << ' ';
+}
--- /dev/null
+#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
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;
-}
--- /dev/null
+#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 << '}';
+}
--- /dev/null
+#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
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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
#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)
}
-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());
-}
#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
#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"
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()
{
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;
// - 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$";
#include "math_defs.h"
+class MathedInset;
+
///
enum mathIterFlags {
/// Allow newlines
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();
};
///
///
#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
-
#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"
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;
#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;
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+// -*- 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
--- /dev/null
+#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, '}');
+}
--- /dev/null
+// -*- 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
#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;
};
-char const * latex_mathspace[] = {
- "!", ",", ":", ";", "quad", "qquad"
-};
char const * latex_special_chars = "#$%&_{}";
#pragma interface
#endif
-#include "math_defs.h"
-#include "math_inset.h"
+#include "math_sqrtinset.h"
#include "symbol_def.h"
#include "LString.h"
--- /dev/null
+// -*- 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
--- /dev/null
+#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] << ' ';
+ }
+}
--- /dev/null
+#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
--- /dev/null
+#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 << '}';
+}
--- /dev/null
+
+#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
#include "math_inset.h"
#include "math_iter.h"
#include "math_parser.h"
+#include "math_parinset.h"
#include "support/lstrings.h"
#include "debug.h"
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)
--- /dev/null
+#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$";
--- /dev/null
+// -*- 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
--- /dev/null
+#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;
+}
--- /dev/null
+// -*- 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
--- /dev/null
+#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
--- /dev/null
+// -*- 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