X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMathSupport.cpp;h=45ca4296816d4161b34c2284fa595c1073df39b0;hb=21c92c8a129b5f3ff56de33bf2941a25967cffbb;hp=e18a351c82543e46d4a1cfa28226f5607d4f85fa;hpb=b2b8733096543b80b918375cc8a0e1fa6c5fd8b8;p=lyx.git diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index e18a351c82..45ca429681 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -15,10 +15,13 @@ #include "InsetMathFont.h" #include "InsetMathSymbol.h" +#include "Length.h" #include "MathData.h" +#include "MathFactory.h" #include "MathParser.h" #include "MathStream.h" +#include "LaTeXFeatures.h" #include "MetricsInfo.h" #include "frontends/FontLoader.h" @@ -27,6 +30,7 @@ #include "support/debug.h" #include "support/docstream.h" +#include "support/lassert.h" #include "support/lyxlib.h" #include @@ -78,6 +82,7 @@ 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 + * 5 = rounded thick line (i.e. dot for short line) */ @@ -289,9 +294,18 @@ double const hline[] = { }; +double const dot[] = { +// 1, 0.5, 0.2, 0.5, 0.2, +// 1, 0.4, 0.4, 0.6, 0.4, +// 1, 0.5, 0.5, 0.5, 0.5, + 5, 0.4, 0.4, 0.6, 0.4, + 0 +}; + + double const ddot[] = { - 1, 0.2, 0.5, 0.3, 0.5, - 1, 0.7, 0.5, 0.8, 0.5, + 5, 0.0, 0.4, 0.3, 0.4, + 5, 0.6, 0.4, 1.0, 0.4, 0 }; @@ -329,12 +343,6 @@ double const dline3[] = { }; -double const hlinesmall[] = { - 1, 0.4, 0.5, 0.6, 0.5, - 0 -}; - - 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, @@ -453,7 +461,7 @@ named_deco_struct deco_table[] = { {"acute", slash, 0 }, {"tilde", tilde, 0 }, {"bar", hline, 0 }, - {"dot", hlinesmall, 0 }, + {"dot", dot, 0 }, {"check", angle, 1 }, {"breve", parenth, 1 }, {"vec", arrow, 3 }, @@ -491,7 +499,7 @@ public: } }; -static init_deco_table dummy; +static init_deco_table dummy_deco_table; deco_struct const * search_deco(docstring const & name) @@ -501,7 +509,7 @@ deco_struct const * search_deco(docstring const & name) } -} // namespace anon +} // namespace int mathed_font_em(FontInfo const & font) @@ -509,6 +517,12 @@ int mathed_font_em(FontInfo const & font) return theFontMetrics(font).em(); } + +int mathed_font_x_height(FontInfo const & font) +{ + return theFontMetrics(font).xHeight(); +} + /* The math units. Quoting TeX by Topic, p.205: * * Spacing around mathematical objects is measured in mu units. A mu @@ -527,27 +541,20 @@ int mathed_font_em(FontInfo const & font) * punctuation, and is put around inner objects, except where these * are followed by a close or preceded by an open symbol, and except * if the other object is a large operator or a binary relation. + * + * See the file MathClass.cpp for a formal implementation of the rules + * above. */ -int mathed_thinmuskip(FontInfo font) +int mathed_mu(FontInfo const & font, double mu) { - font.setFamily(SYMBOL_FAMILY); - return support::iround(3.0 / 18 * theFontMetrics(font).em()); + MetricsBase mb(nullptr, font); + return mb.inPixels(Length(mu, Length::MU)); } - -int mathed_medmuskip(FontInfo font) -{ - font.setFamily(SYMBOL_FAMILY); - return support::iround(4.0 / 18 * theFontMetrics(font).em()); -} - - -int mathed_thickmuskip(FontInfo font) -{ - font.setFamily(SYMBOL_FAMILY); - return support::iround(5.0 / 18 * theFontMetrics(font).em()); -} +int mathed_thinmuskip(FontInfo const & font) { return mathed_mu(font, 3.0); } +int mathed_medmuskip(FontInfo const & font) { return mathed_mu(font, 4.0); } +int mathed_thickmuskip(FontInfo const & font) { return mathed_mu(font, 5.0); } int mathed_char_width(FontInfo const & font, char_type c) @@ -559,7 +566,7 @@ int mathed_char_width(FontInfo const & font, char_type c) int mathed_char_kerning(FontInfo const & font, char_type c) { frontend::FontMetrics const & fm = theFontMetrics(font); - return fm.rbearing(c) - fm.width(c); + return max(0, fm.rbearing(c) - fm.width(c)); } @@ -620,7 +627,7 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, for (int i = 0; d[i]; ) { int code = int(d[i++]); - if (code & 1) { // code == 1 || code == 3 + if (code & 1) { // code == 1 || code == 3 || code == 5 double xx = d[i++]; double yy = d[i++]; double x2 = d[i++]; @@ -634,11 +641,21 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, int(x + xx + 0.5), int(y + yy + 0.5), int(x + x2 + 0.5), int(y + y2 + 0.5), pi.base.font.color()); + if (code == 5) { // thicker, but rounded + pi.pain.line( + int(x + xx + 0.5+1), int(y + yy + 0.5-1), + int(x + x2 + 0.5-1), int(y + y2 + 0.5-1), + pi.base.font.color()); + pi.pain.line( + int(x + xx + 0.5+1), int(y + yy + 0.5+1), + int(x + x2 + 0.5-1), int(y + y2 + 0.5+1), + pi.base.font.color()); + } } else { int xp[32]; int yp[32]; - int const n = int(d[i++]); - for (int j = 0; j < n; ++j) { + int const n2 = int(d[i++]); + for (int j = 0; j < n2; ++j) { double xx = d[i++]; double yy = d[i++]; // lyxerr << ' ' << xx << ' ' << yy << ' '; @@ -650,12 +667,55 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, yp[j] = int(y + yy + 0.5); // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']'; } - pi.pain.lines(xp, yp, n, pi.base.font.color()); + pi.pain.lines(xp, yp, n2, pi.base.font.color()); } } } +docstring const & mathedSymbol(MetricsBase & mb, latexkeys const * sym) +{ + return (mb.font.style() == DISPLAY_STYLE && !sym->dsp_draw.empty()) ? + sym->dsp_draw : sym->draw; +} + + +int mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym) +{ + LASSERT((bool)sym, return 0); + //lyxerr << "metrics: symbol: '" << sym->name + // << "' in font: '" << sym->inset + // << "' drawn as: '" << sym->draw + // << "'" << endl; + + bool const italic_upcase_greek = sym->inset == "cmr" && + sym->extra == "mathalpha" && + mb.fontname == "mathit"; + std::string const font = italic_upcase_greek ? "cmm" : sym->inset; + Changer dummy = mb.changeFontSet(font); + mathed_string_dim(mb.font, mathedSymbol(mb, sym), dim); + return mathed_char_kerning(mb.font, mathedSymbol(mb, sym).back()); +} + + +void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym) +{ + LASSERT((bool)sym, return); + //lyxerr << "drawing: symbol: '" << sym->name + // << "' in font: '" << sym->inset + // << "' drawn as: '" << sym->draw + // << "'" << endl; + + bool const italic_upcase_greek = sym->inset == "cmr" && + sym->extra == "mathalpha" && + pi.base.fontname == "mathit"; + std::string const font = italic_upcase_greek ? "cmm" : sym->inset; + + Changer dummy = pi.base.changeFontSet(font); + pi.draw(x, y, mathedSymbol(pi.base, sym)); +} + + void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str) { FontInfo font = mi.base.font; @@ -708,6 +768,7 @@ FontShape const inh_shape = INHERIT_SHAPE; // does not work fontinfo fontinfos[] = { // math fonts + // Color_math determines which fonts are math (see isMathFont) {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES, ITALIC_SHAPE, Color_math}, {"mathbf", inh_family, BOLD_SERIES, @@ -722,6 +783,8 @@ fontinfo fontinfos[] = { inh_shape, Color_math}, {"mathbb", MSB_FAMILY, inh_series, inh_shape, Color_math}, + {"mathds", DS_FAMILY, inh_series, + inh_shape, Color_math}, {"mathtt", TYPEWRITER_FAMILY, inh_series, inh_shape, Color_math}, {"mathit", inh_family, inh_series, @@ -919,8 +982,7 @@ bool isAlphaSymbol(MathAtom const & at) docstring asString(MathData const & ar) { odocstringstream os; - TexRow texrow(false); - otexrowstream ots(os,texrow); + otexrowstream ots(os); WriteStream ws(ots); ws << ar; return os.str(); @@ -929,8 +991,13 @@ docstring asString(MathData const & ar) void asArray(docstring const & str, MathData & ar, Parse::flags pf) { + // If the QUIET flag is set, we are going to parse for either + // a paste operation or a macro definition. We try to do the + // right thing in all cases. + bool quiet = pf & Parse::QUIET; - if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet)) + bool macro = pf & Parse::MACRODEF; + if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet && !macro)) mathed_parse_cell(ar, str, pf | Parse::VERBATIM); } @@ -938,8 +1005,7 @@ void asArray(docstring const & str, MathData & ar, Parse::flags pf) docstring asString(InsetMath const & inset) { odocstringstream os; - TexRow texrow(false); - otexrowstream ots(os,texrow); + otexrowstream ots(os); WriteStream ws(ots); inset.write(ws); return os.str(); @@ -949,12 +1015,30 @@ docstring asString(InsetMath const & inset) docstring asString(MathAtom const & at) { odocstringstream os; - TexRow texrow(false); - otexrowstream ots(os,texrow); + otexrowstream ots(os); WriteStream ws(ots); at->write(ws); return os.str(); } +int axis_height(MetricsBase & mb) +{ + Changer dummy = mb.changeFontSet("mathnormal"); + return theFontMetrics(mb.font).ascent('-') - 1; +} + + +void validate_math_word(LaTeXFeatures & features, docstring const & word) +{ + MathWordList const & words = mathedWordList(); + MathWordList::const_iterator it = words.find(word); + if (it != words.end()) { + string const req = it->second.required; + if (!req.empty()) + features.require(req); + } +} + + } // namespace lyx