From e8ee0100fcabad72b03cf0a17cccd589bd1cdd46 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Fri, 17 Jul 2020 18:49:08 +0200 Subject: [PATCH] Implement variable size bigops The goal is to reproduce the change of size of operators like \sum wen they are in display style. The syntax of the symbols file has been extended to allow for two code points (like 80|88 for \sum). In this case, the second one will be used in display style. Update the symbols file to handle all bigops from cmex, esint, wasy and stmaryrd. Let the code for math symbol inset handle symbols which can change size, using the information from the symbols file. --- lib/symbols | 135 +++++++++++++++++---------------- src/mathed/InsetMathSymbol.cpp | 27 +++++-- src/mathed/MathFactory.cpp | 14 +++- src/mathed/MathParser.h | 3 + src/mathed/MathSupport.cpp | 11 ++- src/mathed/MathSupport.h | 2 + 6 files changed, 115 insertions(+), 77 deletions(-) diff --git a/lib/symbols b/lib/symbols index 277dd80cba..4da0aac80f 100644 --- a/lib/symbols +++ b/lib/symbols @@ -244,6 +244,9 @@ tag* mbox forcetext # symbols generated from fontmath.ltx # +# When two codes n1|n2 are specified for charid, the the second one will +# be used in display mode. This is only useful for mathop symbold (e.g.\sum). + #symbol font charid charid-in-fallback-Xsymbol-font math-class HTML-entity XML-entity alpha cmm 174 97 mathord α α beta cmm 175 98 mathord β β @@ -319,18 +322,18 @@ iffont cmsy else \def\not{\kern4mu\lyxnot\kern-19mu} endif -coprod cmex 96 0 mathop ⨿ ⨿ -bigvee cmex 87 0 mathop ⋁ ⋁ -bigwedge cmex 86 0 mathop ⋀ ⋀ -biguplus cmex 85 0 mathop ⨄ ⨄ -bigcap cmex 84 0 mathop ⋂ ⋂ -bigcup cmex 83 0 mathop ⋃ ⋃ -prod cmex 81 213 mathop ∏ ∏ -sum cmex 80 229 mathop ∑ ∑ -bigotimes cmex 78 0 mathop ⨂ ⨂ -bigoplus cmex 76 0 mathop ⨁ ⨁ -bigodot cmex 74 0 mathop ⨀ ⨀ -bigsqcup cmex 70 0 mathop ⨆ ⨆ +coprod cmex 96|97 0 mathop ⨿ ⨿ +bigvee cmex 87|95 0 mathop ⋁ ⋁ +bigwedge cmex 86|94 0 mathop ⋀ ⋀ +biguplus cmex 85|93 0 mathop ⨄ ⨄ +bigcap cmex 84|92 0 mathop ⋂ ⋂ +bigcup cmex 83|91 0 mathop ⋃ ⋃ +prod cmex 81|89 213 mathop ∏ ∏ +sum cmex 80|88 229 mathop ∑ ∑ +bigotimes cmex 78|79 0 mathop ⨂ ⨂ +bigoplus cmex 76|77 0 mathop ⨁ ⨁ +bigodot cmex 74|75 0 mathop ⨀ ⨀ +bigsqcup cmex 70|71 0 mathop ⨆ ⨆ smallint cmsy 115 0 mathop ∫ ∫ triangleleft cmm 47 0 mathbin ◃ ◃ triangleright cmm 46 0 mathbin ▹ ▹ @@ -854,8 +857,8 @@ wasypropto wasy 29 0 mathrel ∝ ∝ invneg wasy 24 0 mathrel ⌐ ⌐ ocircle wasy 35 0 mathbin ⊚ ⊚ logof wasy 22 0 mathrel x x -varint wasy 114 0 mathop ∫ ∫ -varoint wasy 117 0 mathop ∫ ∫ +varint wasy 114|119 0 mathop ∫ ∫ +varoint wasy 117|122 0 mathop ∫ ∫ # Generated from stmaryrd.sty @@ -962,13 +965,13 @@ leftarrowtriangle stmry 94 0 mathrel x x stmaryrd rightarrowtriangle stmry 95 0 mathrel x x stmaryrd #bigtriangledown stmry 96 0 mathop x x stmaryrd #already in cmsy #bigtriangleup stmry 97 0 mathop x x stmaryrd #already in cmsy -bigcurlyvee stmry 98 0 mathop x x stmaryrd -bigcurlywedge stmry 99 0 mathop x x stmaryrd -bigsqcap stmry 100 0 mathop x x stmaryrd -bigbox stmry 101 0 mathop x x stmaryrd -bigparallel stmry 102 0 mathop x x stmaryrd -biginterleave stmry 103 0 mathop x x stmaryrd -#hugetriangledown stmry 104 0 mathop x x stmaryrd # only in the font, not the .sty +bigcurlyvee stmry 98|106 0 mathop x x stmaryrd +bigcurlywedge stmry 99|107 0 mathop x x stmaryrd +bigsqcap stmry 100|108 0 mathop x x stmaryrd +bigbox stmry 101|109 0 mathop x x stmaryrd +bigparallel stmry 102|110 0 mathop x x stmaryrd +biginterleave stmry 103|111 0 mathop x x stmaryrd +#hugetriangledown stmry 104 0 mathop x x stmaryrd # only in the font, not the .sty #hugetriangleup stmry 105 0 mathop x x stmaryrd # only in the font, not the .sty #hugecurlyvee stmry 106 0 mathop x x stmaryrd # only in the font, not the .sty #hugecurlywedge stmry 107 0 mathop x x stmaryrd # only in the font, not the .sty @@ -976,7 +979,7 @@ biginterleave stmry 103 0 mathop x x stmaryrd #hugebox stmry 109 0 mathop x x stmaryrd # only in the font, not the .sty #hugeparallel stmry 110 0 mathop x x stmaryrd # only in the font, not the .sty #hugeinterleave stmry 111 0 mathop x x stmaryrd # only in the font, not the .sty -bignplus stmry 112 0 mathop x x stmaryrd # caution: named hugenplus in the font +bignplus stmry 112|120 0 mathop x x stmaryrd # caution: named hugenplus in the font #largellbracket stmry 113 0 mathopen x x stmaryrd # only in the font, not the .sty #Largellbracket stmry 114 0 mathopen x x stmaryrd # only in the font, not the .sty #LARGEllbracket stmry 115 0 mathopen x x stmaryrd # only in the font, not the .sty @@ -1026,44 +1029,44 @@ tbond cmsy 180 186 mathord x x # If the wasysym integrals are really wanted then one has to load the package # manually and disable automatic loading of amsmath and esint. iffont esint -int esint 001 0 mathop ∫ ∫ esint|amsmath -intop esint 001 0 mathop ∫ ∫ esint -iint esint 003 0 mathop ∬ ∬ esint|amsmath -iintop esint 003 0 mathop ∬ ∬ esint -iiint esint 005 0 mathop ∭ ∭ esint|amsmath -iiintop esint 005 0 mathop ∭ ∭ esint -iiiint esint 007 0 mathop ⨌ ⨌ esint|amsmath -iiiintop esint 007 0 mathop ⨌ ⨌ esint +int esint 001|002 0 mathop ∫ ∫ esint|amsmath +intop esint 001|002 0 mathop ∫ ∫ esint +iint esint 003|004 0 mathop ∬ ∬ esint|amsmath +iintop esint 003|004 0 mathop ∬ ∬ esint +iiint esint 005|006 0 mathop ∭ ∭ esint|amsmath +iiintop esint 005|006 0 mathop ∭ ∭ esint +iiiint esint 007|008 0 mathop ⨌ ⨌ esint|amsmath +iiiintop esint 007|008 0 mathop ⨌ ⨌ esint #9 codepoint forbidden in qt4, 10,12,13 in qt5 -oint esint 043 0 mathop ∮ ∮ esint -ointop esint 043 0 mathop ∮ ∮ esint -oiint esint 045 0 mathop ∯ ∯ esint -oiintop esint 045 0 mathop ∯ ∯ esint -sqint esint 015 0 mathop ⨖ ⨖ esint -sqintop esint 015 0 mathop ⨖ ⨖ esint -sqiint esint 017 0 mathop x esint -sqiintop esint 017 0 mathop x esint -dotsint esint 041 0 mathop ∫⋯∫ ∫⋯∫ esint -dotsintop esint 042 0 mathop ∫⋯∫ ∫⋯∫ esint -ointctrclockwise esint 023 0 mathop ∳ ∳ esint -ointctrclockwiseop esint 023 0 mathop ∳ ∳ esint -ointclockwise esint 025 0 mathop ∲ ∲ esint -ointclockwiseop esint 025 0 mathop ∲ ∲ esint +oint esint 043|044 0 mathop ∮ ∮ esint +ointop esint 043|044 0 mathop ∮ ∮ esint +oiint esint 045|046 0 mathop ∯ ∯ esint +oiintop esint 045|046 0 mathop ∯ ∯ esint +sqint esint 015|016 0 mathop ⨖ ⨖ esint +sqintop esint 015|016 0 mathop ⨖ ⨖ esint +sqiint esint 017|018 0 mathop x esint +sqiintop esint 017|017 0 mathop x esint +dotsint esint 041|042 0 mathop ∫⋯∫ ∫⋯∫ esint +dotsintop esint 041|042 0 mathop ∫⋯∫ ∫⋯∫ esint +ointctrclockwise esint 023|024 0 mathop ∳ ∳ esint +ointctrclockwiseop esint 023|024 0 mathop ∳ ∳ esint +ointclockwise esint 025|026 0 mathop ∲ ∲ esint +ointclockwiseop esint 025|026 0 mathop ∲ ∲ esint else -int cmex 82 242 mathop ∫ ∫ esint|amsmath -intop cmex 82 242 mathop ∫ ∫ esint -iint wasy 115 0 mathop ∬ ∬ esint|amsmath -iintop wasy 115 0 mathop &Int ∬ esint -iiint wasy 116 0 mathop ∭ ∭ esint|amsmath -iiintop wasy 116 0 mathop ∭ ∭ esint +int cmex 82|90 242 mathop ∫ ∫ esint|amsmath +intop cmex 82|90 242 mathop ∫ ∫ esint +iint wasy 115|120 0 mathop ∬ ∬ esint|amsmath +iintop wasy 115|120 0 mathop &Int ∬ esint +iiint wasy 116|121 0 mathop ∭ ∭ esint|amsmath +iiintop wasy 116|121 0 mathop ∭ ∭ esint \def\iiiint{\int\kern-6mu\int\kern-6mu\int\kern-6mu\int} esint|amsmath \def\iiiintop{\int\kern-6mu\int\kern-6mu\int\kern-6mu\int} esint \def\dotsint{\int\kern-3mu\cdots\kern-3mu\int} esint \def\dotsintop{\int\kern-3mu\cdots\kern-3mu\int} esint -oint cmex 72 0 mathop ∮ ∮ esint -ointop cmex 72 0 mathop ∮ ∮ esint -oiint wasy 118 0 mathop ∯ ∯ esint -oiintop wasy 118 0 mathop ∯ ∯ esint +oint cmex 72|73 0 mathop ∮ ∮ esint +ointop cmex 72|73 0 mathop ∮ ∮ esint +oiint wasy 118|123 0 mathop ∯ ∯ esint +oiintop wasy 118|123 0 mathop ∯ ∯ esint \def\sqint{\square\kern-17mu\int\kern6mu} esint \def\sqintop{\square\kern-17mu\int\kern6mu} esint \def\sqiint{\square\kern-20mu\iint\kern3mu} esint @@ -1074,18 +1077,18 @@ oiintop wasy 118 0 mathop ∯ ∯ \def\ointclockwiseop{\circlearrowright\kern-21mu\int\kern6mu} esint endif -varointclockwise esint 027 0 mathop ∲ ∲ esint -varointclockwiseop esint 027 0 mathop ∲ ∲ esint -varointctrclockwise esint 029 0 mathop ∳ ∳ esint -varointctrclockwiseop esint 029 0 mathop ∳ ∳ esint -fint esint 031 0 mathop ⨏ ⨏ esint -fintop esint 031 0 mathop ⨏ ⨏ esint -varoiint esint 033 0 mathop ∯ ∯ esint -varoiintop esint 033 0 mathop ∯ ∯ esint -landupint esint 035 0 mathop x x esint -landupintop esint 035 0 mathop x x esint -landdownint esint 037 0 mathop x x esint -landdownintop esint 037 0 mathop x x esint +varointclockwise esint 027|028 0 mathop ∲ ∲ esint +varointclockwiseop esint 027|028 0 mathop ∲ ∲ esint +varointctrclockwise esint 029|030 0 mathop ∳ ∳ esint +varointctrclockwiseop esint 029|030 0 mathop ∳ ∳ esint +fint esint 031|032 0 mathop ⨏ ⨏ esint +fintop esint 031|032 0 mathop ⨏ ⨏ esint +varoiint esint 033|034 0 mathop ∯ ∯ esint +varoiintop esint 033|034 0 mathop ∯ ∯ esint +landupint esint 035|036 0 mathop x x esint +landupintop esint 035|036 0 mathop x x esint +landdownint esint 037|038 0 mathop x x esint +landdownintop esint 037|038 0 mathop x x esint # From the amsmath package: diff --git a/src/mathed/InsetMathSymbol.cpp b/src/mathed/InsetMathSymbol.cpp index 8e98db747e..d354d016a5 100644 --- a/src/mathed/InsetMathSymbol.cpp +++ b/src/mathed/InsetMathSymbol.cpp @@ -60,17 +60,32 @@ docstring InsetMathSymbol::name() const void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const { - // set dim mathedSymbolDim(mi.base, dim, sym_); - // set kerning_ - kerning_ = mathed_char_kerning(mi.base.font, *sym_->draw.rbegin()); - // correct height for broken cmex and wasy font - if (sym_->inset == "cmex" || sym_->inset == "wasy") { - h_ = 4 * dim.des / 5; + if (sym_->draw != sym_->name) { + // set dim + // FIXME: this should depend on BufferView + // set kerning_ + kerning_ = mathed_char_kerning(mi.base.font, + mathedSymbol(mi.base, sym_).back()); + + // align character vertically + // FIXME: this should depend on BufferView + h_ = 0; + if (mathClass() == MC_OP) { + // center the symbol around the fraction axis + // See rule 13 of Appendix G of the TeXbook. + h_ = axis_height(mi.base) + (dim.des - dim.asc) / 2; + } else if (sym_->inset == "wasy") { + // correct height for broken wasy font + h_ = 4 * dim.des / 5; + } dim.asc += h_; dim.des -= h_; } + // set scriptable_ + //FIXME: get rid of that? Only "funclim" probably, along with + // class==MC_OP. The issue is to implement \limits properly. scriptable_ = false; if (mi.base.font.style() == DISPLAY_STYLE) if (sym_->inset == "cmex" || sym_->inset == "esint" || diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 33b674b2b8..afee57ef1c 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -155,6 +155,7 @@ void initSymbols() bool skip = false; while (getline(fs, line)) { int charid = 0; + int dsp_charid = 0; int fallbackid = 0; if (line.empty() || line[0] == '#') continue; @@ -243,9 +244,12 @@ void initSymbols() docstring help; is >> tmp.name >> help; tmp.inset = to_ascii(help); - if (isFontName(tmp.inset)) - is >> charid >> fallbackid >> tmp.extra >> tmp.htmlname >> tmp.xmlname; - else + if (isFontName(tmp.inset)) { + is >> help >> fallbackid >> tmp.extra >> tmp.htmlname >> tmp.xmlname; + docstring cid, dsp_cid; + idocstringstream is2(subst(help, '|', ' ')); + is2 >> charid >> dsp_charid; + } else is >> tmp.extra; // requires is optional if (is) { @@ -289,6 +293,10 @@ void initSymbols() } else if (isMathFontAvailable(tmp.inset) && canBeDisplayed(charid)) { LYXERR(Debug::MATHED, "symbol available for " << to_utf8(tmp.name)); tmp.draw.push_back(char_type(charid)); + if (dsp_charid && canBeDisplayed(dsp_charid)) { + LYXERR(Debug::MATHED, "large symbol available for " << to_utf8(tmp.name)); + tmp.dsp_draw.push_back(char_type(dsp_charid)); + } } else if (fallbackid && isMathFontAvailable(symbol_font) && canBeDisplayed(fallbackid)) { if (tmp.inset == "cmex") diff --git a/src/mathed/MathParser.h b/src/mathed/MathParser.h index 24e6c22b5c..20403de5fb 100644 --- a/src/mathed/MathParser.h +++ b/src/mathed/MathParser.h @@ -52,6 +52,9 @@ public: * on screen. */ docstring draw; + /// the same thing, but as an alternative in display mode + // Useful for \sum operator, for example + docstring dsp_draw; /// operator/..., fontname e docstring extra; /// how is this called as HTML entity in MathML? diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index 9ed1e7bd95..12f8a842f6 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -673,6 +673,13 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, } +docstring const & mathedSymbol(MetricsBase & mb, latexkeys const * sym) +{ + return (mb.font.style() == DISPLAY_STYLE && !sym->dsp_draw.empty()) ? + sym->dsp_draw : sym->draw; +} + + void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym) { LASSERT((bool)sym, return); @@ -686,7 +693,7 @@ void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym) mb.fontname == "mathit"; std::string const font = italic_upcase_greek ? "cmm" : sym->inset; Changer dummy = mb.changeFontSet(font); - mathed_string_dim(mb.font, sym->draw, dim); + mathed_string_dim(mb.font, mathedSymbol(mb, sym), dim); } @@ -704,7 +711,7 @@ void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym) std::string const font = italic_upcase_greek ? "cmm" : sym->inset; Changer dummy = pi.base.changeFontSet(font); - pi.draw(x, y, sym->draw); + pi.draw(x, y, mathedSymbol(pi.base, sym)); } diff --git a/src/mathed/MathSupport.h b/src/mathed/MathSupport.h index d9301453dd..fa7b2fe0ea 100644 --- a/src/mathed/MathSupport.h +++ b/src/mathed/MathSupport.h @@ -55,6 +55,8 @@ void mathed_string_dim(FontInfo const & font, int mathed_string_width(FontInfo const &, docstring const & s); +docstring const & mathedSymbol(MetricsBase & mb, latexkeys const * sym); + void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym); void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym); -- 2.39.2