]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_support.C
Andreas' patch to prevent crash on click on previewd inset
[lyx.git] / src / mathed / math_support.C
index 8bea104b7d35149920c49c1c57dea63906b26f36..f857d8e753c09c41c888ff3a1fb9bdad593b0e50 100644 (file)
@@ -1,28 +1,36 @@
-#include <config.h>
+/**
+ * \file math_support.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Alejandro Aguilar Sierra
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
+ */
 
-#include <map>
+#include <config.h>
 
 #include "math_support.h"
-#include "lyxfont.h"
-#include "FontLoader.h"
-#include "font.h"
-#include "math_cursor.h"
-#include "math_defs.h"
+#include "math_data.h"
 #include "math_inset.h"
+#include "math_mathmlstream.h"
 #include "math_parser.h"
-#include "Painter.h"
+
 #include "debug.h"
-#include "commandtags.h"
+#include "LColor.h"
 
-using std::map;
-using std::endl;
-using std::max;
+#include "frontends/Painter.h"
+#include "frontends/font_metrics.h"
+#include "frontends/lyx_gui.h"
 
+#include <map>
+#include <sstream>
 
-bool isBinaryOp(char c, MathTextCodes type)
-{
-       return type < LM_TC_SYMB && strchr("+-<>=/*", c);
-}
+
+using std::string;
+using std::max;
+using std::endl;
 
 
 ///
@@ -58,227 +66,12 @@ void Matrix::transform(double & x, double & y)
 }
 
 
-namespace {
-
-LyXFont * MathFonts = 0;
-bool font_available[LM_FONT_END];
-bool font_available_initialized[LM_FONT_END];
-
-enum MathFont {
-       FONT_IT,
-       FONT_SYMBOL,
-       FONT_SYMBOLI,
-       FONT_BF,
-       FONT_TT,
-       FONT_RM,
-       FONT_SF,
-       FONT_CMR,
-       FONT_CMSY,
-       FONT_CMM,
-       FONT_CMEX,
-       FONT_MSA,
-       FONT_MSB,
-       FONT_EUFRAK,
-       FONT_FAKEBB,
-       FONT_FAKECAL,
-       FONT_FAKEFRAK,
-       FONT_NUM
-};
-
-void mathed_init_fonts()
-{
-       MathFonts = new LyXFont[FONT_NUM];
-
-       MathFonts[FONT_IT].setShape(LyXFont::ITALIC_SHAPE);
-
-       MathFonts[FONT_SYMBOL].setFamily(LyXFont::SYMBOL_FAMILY);
-
-       MathFonts[FONT_SYMBOLI].setFamily(LyXFont::SYMBOL_FAMILY);
-       MathFonts[FONT_SYMBOLI].setShape(LyXFont::ITALIC_SHAPE);
-
-       MathFonts[FONT_BF].setSeries(LyXFont::BOLD_SERIES);
-
-       MathFonts[FONT_TT].setFamily(LyXFont::TYPEWRITER_FAMILY);
-       MathFonts[FONT_RM].setFamily(LyXFont::ROMAN_FAMILY);
-       MathFonts[FONT_SF].setFamily(LyXFont::SANS_FAMILY);
-
-       MathFonts[FONT_CMR].setFamily(LyXFont::CMR_FAMILY);
-       MathFonts[FONT_CMSY].setFamily(LyXFont::CMSY_FAMILY);
-       MathFonts[FONT_CMM].setFamily(LyXFont::CMM_FAMILY);
-       MathFonts[FONT_CMEX].setFamily(LyXFont::CMEX_FAMILY);
-       MathFonts[FONT_MSA].setFamily(LyXFont::MSA_FAMILY);
-       MathFonts[FONT_MSB].setFamily(LyXFont::MSB_FAMILY);
-       MathFonts[FONT_EUFRAK].setFamily(LyXFont::EUFRAK_FAMILY);
-
-       MathFonts[FONT_FAKEBB].setFamily(LyXFont::TYPEWRITER_FAMILY);
-       MathFonts[FONT_FAKEBB].setSeries(LyXFont::BOLD_SERIES);
-
-       MathFonts[FONT_FAKECAL].setFamily(LyXFont::SANS_FAMILY);
-       MathFonts[FONT_FAKECAL].setShape(LyXFont::ITALIC_SHAPE);
-
-       MathFonts[FONT_FAKEFRAK].setFamily(LyXFont::SANS_FAMILY);
-       MathFonts[FONT_FAKEFRAK].setSeries(LyXFont::BOLD_SERIES);
-
-       for (int i = 0; i < LM_FONT_END; ++i)
-               font_available_initialized[i] = false;
-}
-
-
-LyXFont const & whichFontBaseIntern(MathTextCodes type)
-{
-       if (!MathFonts)
-               mathed_init_fonts();
-
-       switch (type) {
-       case LM_TC_SYMB:        
-       case LM_TC_BOLDSYMB:    
-               return MathFonts[FONT_SYMBOLI];
-
-       case LM_TC_VAR:
-       case LM_TC_IT:
-               return MathFonts[FONT_IT];
-
-       case LM_TC_BF:
-               return MathFonts[FONT_BF];
-
-       case LM_TC_BB:
-               return MathFonts[FONT_MSB];
-
-       case LM_TC_CAL:
-               return MathFonts[FONT_CMSY];
-
-       case LM_TC_TT:
-               return MathFonts[FONT_TT];
-
-       case LM_TC_BOX:
-       case LM_TC_TEXTRM:
-       case LM_TC_CONST:
-       case LM_TC_TEX:
-       case LM_TC_RM:
-               return MathFonts[FONT_RM];
-
-       case LM_TC_SF:
-               return MathFonts[FONT_SF];
-
-       case LM_TC_CMR:
-               return MathFonts[FONT_CMR];
-
-       case LM_TC_CMSY:
-               return MathFonts[FONT_CMSY];
-
-       case LM_TC_CMM:
-               return MathFonts[FONT_CMM];
-
-       case LM_TC_CMEX:
-               return MathFonts[FONT_CMEX];
-
-       case LM_TC_MSA:
-               return MathFonts[FONT_MSA];
-
-       case LM_TC_MSB:
-               return MathFonts[FONT_MSB];
-
-       case LM_TC_EUFRAK:
-               return MathFonts[FONT_EUFRAK];
-
-       default:
-               break;
-       }
-       return MathFonts[1];
-}
-
-
-LyXFont const & whichFontBase(MathTextCodes type)
-{
-       if (!MathFonts)
-               mathed_init_fonts();
-
-       switch (type) {
-       case LM_TC_BB:
-               if (math_font_available(LM_TC_MSB))
-                       return MathFonts[FONT_MSB];
-               else
-                       return MathFonts[FONT_FAKEBB];
-
-       case LM_TC_CAL:
-               if (math_font_available(LM_TC_CMSY))
-                       return MathFonts[FONT_CMSY];
-               else
-                       return MathFonts[FONT_FAKECAL];
-
-       case LM_TC_EUFRAK:
-               if (math_font_available(LM_TC_EUFRAK))
-                       return MathFonts[FONT_EUFRAK];
-               else
-                       return MathFonts[FONT_FAKEFRAK];
-
-       default:
-               break;
-       }
-       return whichFontBaseIntern(type);
-}
-
-
-void whichFont(LyXFont & f, MathTextCodes type, MathMetricsInfo const & size)
-{
-       f = whichFontBase(type);
-       // use actual size
-       f.setSize(size.font.size());
-
-       switch (size.style) {
-       case LM_ST_DISPLAY:
-               if (type == LM_TC_BOLDSYMB || type == LM_TC_CMEX) {
-                       f.incSize();
-                       f.incSize();
-               }
-               break;
-
-       case LM_ST_TEXT:
-               break;
-
-       case LM_ST_SCRIPT:
-               f.decSize();
-               f.decSize();
-               break;
-
-       case LM_ST_SCRIPTSCRIPT:
-               f.decSize();
-               f.decSize();
-               f.decSize();
-               break;
-
-       default:
-               lyxerr << "Math Error: wrong font size: " << size.style << endl;
-               break;
-       }
-
-       if (type != LM_TC_TEXTRM && type != LM_TC_BOX)
-               f.setColor(LColor::math);
-
-       if (type == LM_TC_TEX)
-               f.setColor(LColor::latex);
-}
-
-} // namespace
-
-
-bool math_font_available(MathTextCodes type)
-{
-       if (!font_available_initialized[type]) {
-               font_available_initialized[type] = true;
-               font_available[type] = fontloader.available(whichFontBaseIntern(type));
-               if (!font_available[type])
-                       lyxerr[Debug::FONT] << "Math font " << type << " not available.\n";
-       }
-       return font_available[type];
-}
-
 
 namespace {
 
 /*
  * 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
+ * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
  */
 
 
@@ -429,6 +222,13 @@ double const hlinesmall[] = {
 };
 
 
+double const ring[] = {
+       2, 5,
+       0.5, 0.8,  0.8, 0.5,  0.5, 0.2,  0.2, 0.5,  0.5, 0.8,
+       0
+};
+
+
 double const vert[] = {
        1, 0.5, 0.05,  0.5, 0.95,
        0
@@ -444,7 +244,7 @@ double const  Vert[] = {
 
 double const tilde[] = {
        2, 4,
-       0.05, 0.8,  0.25, 0.2,  0.75, 0.8,  0.95, 0.2,
+       0.00, 0.8,  0.25, 0.2,  0.75, 0.8,  1.00, 0.2,
        0
 };
 
@@ -462,21 +262,21 @@ struct named_deco_struct {
 
 named_deco_struct deco_table[] = {
        // Decorations
-       {"widehat",        angle,      3 },
-       {"widetilde",      tilde,      0 },
-       {"underbar",       hline,      0 },
-       {"underline",      hline,      0 },
-       {"overline",       hline,      0 },
-       {"underbrace",     brace,      1 },
-       {"overbrace",      brace,      3 },
-       {"overleftarrow",  arrow,      1 },
-       {"overrightarrow", arrow,      3 },
-       {"overleftrightarrow", udarrow, 1 },
-       {"xleftarrow",     arrow,      1 },
-       {"xrightarrow",    arrow,      3 },
-       {"underleftarrow", arrow,      1 },
-       {"underrightarrow", arrow,     3 },
-       {"underleftrightarrow",udarrow, 1 },
+       {"widehat",             angle,    3 },
+       {"widetilde",           tilde,    0 },
+       {"underbar",            hline,    0 },
+       {"underline",           hline,    0 },
+       {"overline",            hline,    0 },
+       {"underbrace",          brace,    1 },
+       {"overbrace",           brace,    3 },
+       {"overleftarrow",       arrow,    1 },
+       {"overrightarrow",      arrow,    3 },
+       {"overleftrightarrow",  udarrow,  1 },
+       {"xleftarrow",          arrow,    1 },
+       {"xrightarrow",         arrow,    3 },
+       {"underleftarrow",      arrow,    1 },
+       {"underrightarrow",     arrow,    3 },
+       {"underleftrightarrow", udarrow,  1 },
 
        // Delimiters
        {"(",              parenth,    0 },
@@ -487,6 +287,7 @@ named_deco_struct deco_table[] = {
        {"]",              brack,      2 },
        {"|",              vert,       0 },
        {"/",              slash,      0 },
+       {"vert",           vert,       0 },
        {"Vert",           Vert,       0 },
        {"'",              slash,      1 },
        {"backslash",      slash,      1 },
@@ -501,8 +302,8 @@ named_deco_struct deco_table[] = {
        {"uparrow",        arrow,      0 },
        {"Uparrow",        Arrow,      0 },
        {"updownarrow",    udarrow,    0 },
-       {"Updownarrow",    Udarrow,    0 },     
-       
+       {"Updownarrow",    Udarrow,    0 },
+
        // Accents
        {"ddot",           ddot,       0 },
        {"dddot",          dddot,      0 },
@@ -515,20 +316,27 @@ named_deco_struct deco_table[] = {
        {"check",          angle,      1 },
        {"breve",          parenth,    1 },
        {"vec",            arrow,      3 },
-       {"not",            slash,      0 },
-       
+       {"mathring",       ring,       0 },
+
        // Dots
+       {"dots",           hline3,     0 },
        {"ldots",          hline3,     0 },
        {"cdots",          hline3,     0 },
        {"vdots",          hline3,     1 },
-       {"ddots",          dline3,     0 }
+       {"ddots",          dline3,     0 },
+       {"dotsb",          hline3,     0 },
+       {"dotsc",          hline3,     0 },
+       {"dotsi",          hline3,     0 },
+       {"dotsm",          hline3,     0 },
+       {"dotso",          hline3,     0 }
 };
 
 
-map<string, deco_struct> deco_list;
+std::map<string, deco_struct> deco_list;
 
 // sort the table on startup
-struct init_deco_table {
+class init_deco_table {
+public:
        init_deco_table() {
                unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
                for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
@@ -545,7 +353,7 @@ static init_deco_table dummy;
 
 deco_struct const * search_deco(string const & name)
 {
-       map<string, deco_struct>::const_iterator p = deco_list.find(name);
+       std::map<string, deco_struct>::const_iterator p = deco_list.find(name);
        return (p == deco_list.end()) ? 0 : &(p->second);
 }
 
@@ -553,146 +361,78 @@ deco_struct const * search_deco(string const & name)
 } // namespace anon
 
 
-void mathed_char_dim(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c, int & asc, int & des, int & wid)
+void mathed_char_dim(LyXFont const & font, unsigned char c, Dimension & dim)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       des = lyxfont::descent(c, font);
-       asc = lyxfont::ascent(c, font);
-       wid = mathed_char_width(type, size, c);
+       dim.des = font_metrics::descent(c, font);
+       dim.asc = font_metrics::ascent(c, font);
+       dim.wid = mathed_char_width(font, c);
 }
 
 
-int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c, int & asc, int & des)
+int mathed_char_ascent(LyXFont const & font, unsigned char c)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       des = lyxfont::descent(c, font);
-       asc = lyxfont::ascent(c, font);
-       return asc + des;
+       return font_metrics::ascent(c, font);
 }
 
 
-int mathed_char_height(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c)
+int mathed_char_descent(LyXFont const & font, unsigned char c)
 {
-       int asc;
-       int des;
-       return mathed_char_height(type, size, c, asc, des);
+       return font_metrics::descent(c, font);
 }
 
 
-int mathed_char_ascent(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c)
+int mathed_char_width(LyXFont const & font, unsigned char c)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       return lyxfont::ascent(c, font);
+       return font_metrics::width(c, font);
 }
 
 
-int mathed_char_descent(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c)
+void mathed_string_dim(LyXFont const & font, string const & s, Dimension & dim)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       return lyxfont::descent(c, font);
-}
-
-
-int mathed_char_width(MathTextCodes type, MathMetricsInfo const & size,
-       unsigned char c)
-{
-       LyXFont font;
-       whichFont(font, type, size);
-       if (isBinaryOp(c, type))
-               return lyxfont::width(c, font) + 2 * lyxfont::width(' ', font);
-       else
-               return lyxfont::width(c, font);
-}
-
-
-void mathed_string_dim(MathTextCodes type, MathMetricsInfo const & size,
-       string const & s, int & asc, int & des, int & wid)
-{
-       mathed_string_height(type, size, s, asc, des);
-       wid = mathed_string_width(type, size, s);
-}
-
-
-int mathed_string_height(MathTextCodes type, MathMetricsInfo const & size,
-       string const & s, int & asc, int & des)
-{
-       LyXFont font;
-       whichFont(font, type, size);
-       asc = des = 0;
+#if 1
+       dim.asc = 0;
+       dim.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));
+               dim.asc = max(dim.asc, font_metrics::ascent(*it, font));
+               dim.des = max(dim.des, font_metrics::descent(*it, font));
        }
-       return asc + des;
-}
-
-
-int mathed_string_width(MathTextCodes type, MathMetricsInfo const & size,
-       string const & s)
-{
-       LyXFont font;
-       whichFont(font, type, size);
-       return lyxfont::width(s, font);
+#else
+       dim.asc = font_metrics::maxAscent(font);
+       dim.des = font_metrics::maxDescent(font);
+#endif
+       dim.wid = font_metrics::width(s, font);
 }
 
 
-int mathed_string_ascent(MathTextCodes type, MathMetricsInfo const & size,
-       string const & s)
+int mathed_string_width(LyXFont const & font, string const & s)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       int asc = 0;
-       for (string::const_iterator it = s.begin(); it != s.end(); ++it)
-               asc = max(asc, lyxfont::ascent(*it, font));
-       return asc;
+       return font_metrics::width(s, font);
 }
 
 
-int mathed_string_descent(MathTextCodes type, MathMetricsInfo const & size,
-       string const & s)
-{
-       LyXFont font;
-       whichFont(font, type, size);
-       int des = 0;
-       for (string::const_iterator it = s.begin(); it != s.end(); ++it)
-               des = max(des, lyxfont::descent(*it, font));
-       return des;
-}
-
-
-
-void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
-       const string & name)
+void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
+       string const & name)
 {
        if (name == ".") {
-               pain.line(x + w/2, y, x + w/2, y + h,
-                         LColor::mathcursor, Painter::line_onoffdash);
+               pi.pain.line(x + w/2, y, x + w/2, y + h,
+                         LColor::cursor, Painter::line_onoffdash);
                return;
-       }       
-       
+       }
+
        deco_struct const * mds = search_deco(name);
        if (!mds) {
-               lyxerr << "Deco was not found. Programming error?\n";
-               lyxerr << "name: '" << name << "'\n";
+               lyxerr << "Deco was not found. Programming error?" << endl;
+               lyxerr << "name: '" << name << "'" << endl;
                return;
        }
-       
+
        int const n = (w < h) ? w : h;
        int const r = mds->angle;
        double const * d = mds->data;
-       
+
        if (h > 70 && (name == "(" || name == ")"))
                d = parenthHigh;
-       
+
        Matrix mt(r, w, h);
        Matrix sqmt(r, n, n);
 
@@ -714,135 +454,259 @@ void mathed_draw_deco(Painter & pain, int x, int y, int w, int h,
                        else
                                mt.transform(xx, yy);
                        mt.transform(x2, y2);
-                       pain.line(x + int(xx), y + int(yy), x + int(x2), y + int(y2),
-                                       LColor::math);
-               }       else {
+                       pi.pain.line(
+                               int(x + xx + 0.5), int(y + yy + 0.5),
+                               int(x + x2 + 0.5), int(y + y2 + 0.5),
+                               LColor::math);
+               } else {
                        int xp[32];
                        int yp[32];
                        int const n = int(d[i++]);
                        for (int j = 0; j < n; ++j) {
                                double xx = d[i++];
                                double yy = d[i++];
-//          lyxerr << " " << xx << " " << yy << " ";
+//          lyxerr << ' ' << xx << ' ' << yy << ' ';
                                if (code == 4)
                                        sqmt.transform(xx, yy);
                                else
                                        mt.transform(xx, yy);
-                               xp[j] = x + int(xx);
-                               yp[j] = y + int(yy);
-                               //  lyxerr << "P[" << j " " << xx << " " << yy << " " << x << " " << y << "]";
+                               xp[j] = int(x + xx + 0.5);
+                               yp[j] = int(y + yy + 0.5);
+                               //  lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
                        }
-                       pain.lines(xp, yp, n, LColor::math);
+                       pi.pain.lines(xp, yp, n, LColor::math);
                }
        }
 }
 
 
-void mathed_draw_framebox(Painter & pain, int x, int y, MathInset const * p)
+void drawStrRed(PainterInfo & pi, int x, int y, string const & str)
 {
-       if (mathcursor && mathcursor->isInside(p))
-               pain.rectangle(x, y - p->ascent(), p->width(), p->height(),
-                       LColor::mathframe);
+       LyXFont f = pi.base.font;
+       f.setColor(LColor::latex);
+       pi.pain.text(x, y, str, f);
 }
 
 
-// In the future maybe we use a better fonts renderer
-void drawStr(Painter & pain, MathTextCodes type, MathMetricsInfo const & size,
-       int x, int y, string const & str)
+void drawStrBlack(PainterInfo & pi, int x, int y, string const & str)
 {
-       LyXFont font;
-       whichFont(font, type, size);
-       pain.text(x, y, str, font);
+       LyXFont f = pi.base.font;
+       f.setColor(LColor::foreground);
+       pi.pain.text(x, y, str, f);
 }
 
 
-void drawChar(Painter & pain, MathTextCodes type, MathMetricsInfo const & size,
-       int x, int y, char c)
+void math_font_max_dim(LyXFont const & font, int & asc, int & des)
 {
-       string s;
-       if (isBinaryOp(c, type))
-               s += ' ';
-       s += c;
-       if (isBinaryOp(c, type))
-               s += ' ';
-       drawStr(pain, type, size, x, y, s);
+       asc = font_metrics::maxAscent(font);
+       des = font_metrics::maxDescent(font);
 }
 
 
-// decrease math size for super- and subscripts
-void smallerStyleScript(MathMetricsInfo & st)
+struct fontinfo {
+       string cmd_;
+       LyXFont::FONT_FAMILY family_;
+       LyXFont::FONT_SERIES series_;
+       LyXFont::FONT_SHAPE  shape_;
+       LColor::color        color_;
+};
+
+
+LyXFont::FONT_FAMILY const inh_family = LyXFont::INHERIT_FAMILY;
+LyXFont::FONT_SERIES const inh_series = LyXFont::INHERIT_SERIES;
+LyXFont::FONT_SHAPE  const inh_shape  = LyXFont::INHERIT_SHAPE;
+
+
+// mathnormal should be the first, otherwise the fallback further down
+// does not work
+fontinfo fontinfos[] = {
+       // math fonts
+       {"mathnormal",    LyXFont::ROMAN_FAMILY, LyXFont::MEDIUM_SERIES,
+                         LyXFont::ITALIC_SHAPE, LColor::math},
+       {"mathbf",        inh_family, LyXFont::BOLD_SERIES,
+                         inh_shape, LColor::math},
+       {"mathcal",       LyXFont::CMSY_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"mathfrak",      LyXFont::EUFRAK_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"mathrm",        LyXFont::ROMAN_FAMILY, inh_series,
+                         LyXFont::UP_SHAPE, LColor::math},
+       {"mathsf",        LyXFont::SANS_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"mathbb",        LyXFont::MSB_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"mathtt",        LyXFont::TYPEWRITER_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"mathit",        inh_family, inh_series,
+                         LyXFont::ITALIC_SHAPE, LColor::math},
+       {"cmex",          LyXFont::CMEX_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"cmm",           LyXFont::CMM_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"cmr",           LyXFont::CMR_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"cmsy",          LyXFont::CMSY_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"eufrak",        LyXFont::EUFRAK_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"msa",           LyXFont::MSA_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"msb",           LyXFont::MSB_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"wasy",          LyXFont::WASY_FAMILY, inh_series,
+                         inh_shape, LColor::none},
+
+       // Text fonts
+       {"text",          inh_family, inh_series,
+                         inh_shape, LColor::foreground},
+       {"textbf",        inh_family, LyXFont::BOLD_SERIES,
+                         inh_shape, LColor::foreground},
+       {"textit",        inh_family, inh_series,
+                         LyXFont::ITALIC_SHAPE, LColor::foreground},
+       {"textmd",        inh_family, LyXFont::MEDIUM_SERIES,
+                         inh_shape, LColor::foreground},
+       {"textnormal",    inh_family, inh_series,
+                         LyXFont::UP_SHAPE, LColor::foreground},
+       {"textrm",        LyXFont::ROMAN_FAMILY,
+                         inh_series, LyXFont::UP_SHAPE,LColor::foreground},
+       {"textsc",        inh_family, inh_series,
+                         LyXFont::SMALLCAPS_SHAPE, LColor::foreground},
+       {"textsf",        LyXFont::SANS_FAMILY, inh_series,
+                         inh_shape, LColor::foreground},
+       {"textsl",        inh_family, inh_series,
+                         LyXFont::SLANTED_SHAPE, LColor::foreground},
+       {"texttt",        LyXFont::TYPEWRITER_FAMILY, inh_series,
+                         inh_shape, LColor::foreground},
+       {"textup",        inh_family, inh_series,
+                         LyXFont::UP_SHAPE, LColor::foreground},
+
+       // TIPA support
+       {"textipa",       inh_family, inh_series,
+                         inh_shape, LColor::foreground},
+
+       // LyX internal usage
+       {"lyxtex",        inh_family, inh_series,
+                         LyXFont::UP_SHAPE, LColor::latex},
+       {"lyxsymbol",     LyXFont::SYMBOL_FAMILY, inh_series,
+                         inh_shape, LColor::math},
+       {"lyxboldsymbol", LyXFont::SYMBOL_FAMILY, LyXFont::BOLD_SERIES,
+                         inh_shape, LColor::math},
+       {"lyxblacktext",  LyXFont::ROMAN_FAMILY, LyXFont::MEDIUM_SERIES,
+                         LyXFont::UP_SHAPE, LColor::foreground},
+       {"lyxnochange",   inh_family, inh_series,
+                         inh_shape, LColor::foreground},
+       {"lyxfakebb",     LyXFont::TYPEWRITER_FAMILY, LyXFont::BOLD_SERIES,
+                         LyXFont::UP_SHAPE, LColor::math},
+       {"lyxfakecal",    LyXFont::SANS_FAMILY, LyXFont::MEDIUM_SERIES,
+                         LyXFont::ITALIC_SHAPE, LColor::math},
+       {"lyxfakefrak",   LyXFont::ROMAN_FAMILY, LyXFont::BOLD_SERIES,
+                         LyXFont::ITALIC_SHAPE, LColor::math}
+};
+
+
+fontinfo * lookupFont(string const & name)
 {
-       switch (st.style) {
-               case LM_ST_DISPLAY:
-               case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
-               default:            st.style = LM_ST_SCRIPTSCRIPT;
-       }
+       //lyxerr << "searching font '" << name << "'" << endl;
+       int const n = sizeof(fontinfos) / sizeof(fontinfo);
+       for (int i = 0; i < n; ++i)
+               if (fontinfos[i].cmd_ == name) {
+                       //lyxerr << "found '" << i << "'" << endl;
+                       return fontinfos + i;
+               }
+       return 0;
 }
 
 
-// decrease math size for fractions
-void smallerStyleFrac(MathMetricsInfo & st)
+fontinfo * searchFont(string const & name)
 {
-       switch (st.style) {
-               case LM_ST_DISPLAY: st.style = LM_ST_TEXT; break;
-               case LM_ST_TEXT:    st.style = LM_ST_SCRIPT; break;
-               default:            st.style = LM_ST_SCRIPTSCRIPT;
-       }
+       fontinfo * f = lookupFont(name);
+       return f ? f : fontinfos;
+       // this should be mathnormal
+       //return searchFont("mathnormal");
+}
+
+
+bool isFontName(string const & name)
+{
+       return lookupFont(name);
 }
 
 
-void math_font_max_dim(MathTextCodes code, MathMetricsInfo const & size,
-       int & asc, int & des)
+LyXFont getFont(string const & name)
 {
        LyXFont font;
-       whichFont(font, code, size);
-       asc = lyxfont::maxAscent(font);
-       des = lyxfont::maxDescent(font);
+       augmentFont(font, name);
+       return font;
 }
 
 
-char const * latex_mathspace[] = {
-       "!", ",", ":", ";", "quad", "qquad"
-};
+void fakeFont(string const & orig, string const & fake)
+{
+       fontinfo * forig = searchFont(orig);
+       fontinfo * ffake = searchFont(fake);
+       if (forig && ffake) {
+               forig->family_ = ffake->family_;
+               forig->series_ = ffake->series_;
+               forig->shape_  = ffake->shape_;
+               forig->color_  = ffake->color_;
+       } else {
+               lyxerr << "Can't fake font '" << orig << "' with '"
+                      << fake << "'" << endl;
+       }
+}
+
+
+void augmentFont(LyXFont & font, string const & name)
+{
+       static bool initialized = false;
+       if (!initialized) {
+               initialized = true;
+               // fake fonts if necessary
+               if (!lyx_gui::font_available(getFont("mathfrak")))
+                       fakeFont("mathfrak", "lyxfakefrak");
+               if (!lyx_gui::font_available(getFont("mathcal")))
+                       fakeFont("mathcal", "lyxfakecal");
+       }
+       fontinfo * info = searchFont(name);
+       if (info->family_ != inh_family)
+               font.setFamily(info->family_);
+       if (info->series_ != inh_series)
+               font.setSeries(info->series_);
+       if (info->shape_ != inh_shape)
+               font.setShape(info->shape_);
+       if (info->color_ != LColor::none)
+               font.setColor(info->color_);
+}
+
 
+string asString(MathArray const & ar)
+{
+       std::ostringstream os;
+       WriteStream ws(os);
+       ws << ar;
+       return os.str();
+}
 
 
-char const * math_font_name(MathTextCodes code)
+void asArray(string const & str, MathArray & ar)
 {
-       static char const * theFontNames[] = {
-               "mathrm",
-               "mathcal",
-               "mathfrak",
-               "mathbf",
-               "mathbb",
-               "mathsf",
-               "mathtt",
-               "mathit",
-               "textrm"
-       };
-
-       if (code >= LM_TC_RM && code <= LM_TC_TEXTRM) 
-               return theFontNames[code - LM_TC_RM];
-       return 0;
+       mathed_parse_cell(ar, str);
 }
 
-string convertDelimToLatexName(string const & name)
+
+string asString(MathInset const & inset)
 {
-       if (name == "(")
-               return name;
-       if (name == "[")
-               return name;
-       if (name == ".")
-               return name;
-       if (name == ")")
-               return name;
-       if (name == "]")
-               return name;
-       if (name == "/")
-               return name;
-       if (name == "|")
-               return name;
-       return "\\" + name + " ";
+       std::ostringstream os;
+       WriteStream ws(os);
+       inset.write(ws);
+       return os.str();
 }
 
 
+string asString(MathAtom const & at)
+{
+       std::ostringstream os;
+       WriteStream ws(os);
+       at->write(ws);
+       return os.str();
+}