X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMathSupport.cpp;h=45ca4296816d4161b34c2284fa595c1073df39b0;hb=21c92c8a129b5f3ff56de33bf2941a25967cffbb;hp=0c610b1e69412c202c66505d576d4401870452fc;hpb=be836909c52f8586646fa6360df649288b5e2875;p=lyx.git diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index 0c610b1e69..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" @@ -79,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) */ @@ -290,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 }; @@ -330,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, @@ -454,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 }, @@ -492,7 +499,7 @@ public: } }; -static init_deco_table dummy; +static init_deco_table dummy_deco_table; deco_struct const * search_deco(docstring const & name) @@ -502,7 +509,7 @@ deco_struct const * search_deco(docstring const & name) } -} // namespace anon +} // namespace int mathed_font_em(FontInfo const & font) @@ -510,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 @@ -528,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) -{ - font.setFamily(SYMBOL_FAMILY); - return support::iround(3.0 / 18 * theFontMetrics(font).em()); -} - - -int mathed_medmuskip(FontInfo font) +int mathed_mu(FontInfo const & font, double mu) { - font.setFamily(SYMBOL_FAMILY); - return support::iround(4.0 / 18 * theFontMetrics(font).em()); + MetricsBase mb(nullptr, font); + return mb.inPixels(Length(mu, Length::MU)); } - -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) @@ -560,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)); } @@ -621,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++]; @@ -635,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 << ' '; @@ -651,15 +667,22 @@ 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()); } } } -void mathedSymbolDim(MetricsInfo & mi, Dimension & dim, latexkeys const * sym) +docstring const & mathedSymbol(MetricsBase & mb, latexkeys const * sym) { - LASSERT((bool)sym, return); + 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 @@ -667,17 +690,11 @@ void mathedSymbolDim(MetricsInfo & mi, Dimension & dim, latexkeys const * sym) bool const italic_upcase_greek = sym->inset == "cmr" && sym->extra == "mathalpha" && - mi.base.fontname == "mathit"; + mb.fontname == "mathit"; std::string const font = italic_upcase_greek ? "cmm" : sym->inset; - Changer dummy = mi.base.changeFontSet(font); - mathed_string_dim(mi.base.font, sym->draw, dim); - // seperate things a bit - if (sym->extra == "mathbin") - dim.wid += 2 * mathed_medmuskip(mi.base.font); - else if (sym->extra == "mathrel") - dim.wid += 2 * mathed_thickmuskip(mi.base.font); - else if (sym->extra == "mathpunct") - dim.wid += mathed_thinmuskip(mi.base.font); + Changer dummy = mb.changeFontSet(font); + mathed_string_dim(mb.font, mathedSymbol(mb, sym), dim); + return mathed_char_kerning(mb.font, mathedSymbol(mb, sym).back()); } @@ -693,13 +710,9 @@ void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym) sym->extra == "mathalpha" && pi.base.fontname == "mathit"; std::string const font = italic_upcase_greek ? "cmm" : sym->inset; - if (sym->extra == "mathbin") - x += mathed_medmuskip(pi.base.font); - else if (sym->extra == "mathrel") - x += mathed_thickmuskip(pi.base.font); Changer dummy = pi.base.changeFontSet(font); - pi.draw(x, y, sym->draw); + pi.draw(x, y, mathedSymbol(pi.base, sym)); } @@ -770,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, @@ -976,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); } @@ -1002,4 +1022,23 @@ docstring asString(MathAtom const & at) } +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