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.
This commit is contained in:
Jean-Marc Lasgouttes 2020-07-17 18:49:08 +02:00
parent 8d54457dbf
commit e8ee0100fc
6 changed files with 115 additions and 77 deletions

View File

@ -244,6 +244,9 @@ tag* mbox forcetext
# symbols generated from fontmath.ltx # 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 #symbol font charid charid-in-fallback-Xsymbol-font math-class HTML-entity XML-entity
alpha cmm 174 97 mathord α α alpha cmm 174 97 mathord α α
beta cmm 175 98 mathord β β beta cmm 175 98 mathord β β
@ -319,18 +322,18 @@ iffont cmsy
else else
\def\not{\kern4mu\lyxnot\kern-19mu} \def\not{\kern4mu\lyxnot\kern-19mu}
endif endif
coprod cmex 96 0 mathop ⨿ ⨿ coprod cmex 96|97 0 mathop ⨿ ⨿
bigvee cmex 87 0 mathop ⋁ ⋁ bigvee cmex 87|95 0 mathop ⋁ ⋁
bigwedge cmex 86 0 mathop ⋀ ⋀ bigwedge cmex 86|94 0 mathop ⋀ ⋀
biguplus cmex 85 0 mathop ⨄ ⨄ biguplus cmex 85|93 0 mathop ⨄ ⨄
bigcap cmex 84 0 mathop ⋂ ⋂ bigcap cmex 84|92 0 mathop ⋂ ⋂
bigcup cmex 83 0 mathop ⋃ ⋃ bigcup cmex 83|91 0 mathop ⋃ ⋃
prod cmex 81 213 mathop ∏ ∏ prod cmex 81|89 213 mathop ∏ ∏
sum cmex 80 229 mathop ∑ ∑ sum cmex 80|88 229 mathop ∑ ∑
bigotimes cmex 78 0 mathop ⨂ ⨂ bigotimes cmex 78|79 0 mathop ⨂ ⨂
bigoplus cmex 76 0 mathop ⨁ ⨁ bigoplus cmex 76|77 0 mathop ⨁ ⨁
bigodot cmex 74 0 mathop ⨀ ⨀ bigodot cmex 74|75 0 mathop ⨀ ⨀
bigsqcup cmex 70 0 mathop ⨆ ⨆ bigsqcup cmex 70|71 0 mathop ⨆ ⨆
smallint cmsy 115 0 mathop ∫ ∫ smallint cmsy 115 0 mathop ∫ ∫
triangleleft cmm 47 0 mathbin ◃ ◃ triangleleft cmm 47 0 mathbin ◃ ◃
triangleright cmm 46 0 mathbin ▹ ▹ triangleright cmm 46 0 mathbin ▹ ▹
@ -854,8 +857,8 @@ wasypropto wasy 29 0 mathrel ∝ ∝
invneg wasy 24 0 mathrel ⌐ ⌐ invneg wasy 24 0 mathrel ⌐ ⌐
ocircle wasy 35 0 mathbin ⊚ ⊚ ocircle wasy 35 0 mathbin ⊚ ⊚
logof wasy 22 0 mathrel x x logof wasy 22 0 mathrel x x
varint wasy 114 0 mathop ∫ ∫ varint wasy 114|119 0 mathop ∫ ∫
varoint wasy 117 0 mathop ∫ ∫ varoint wasy 117|122 0 mathop ∫ ∫
# Generated from stmaryrd.sty # Generated from stmaryrd.sty
@ -962,13 +965,13 @@ leftarrowtriangle stmry 94 0 mathrel x x stmaryrd
rightarrowtriangle stmry 95 0 mathrel x x stmaryrd rightarrowtriangle stmry 95 0 mathrel x x stmaryrd
#bigtriangledown stmry 96 0 mathop x x stmaryrd #already in cmsy #bigtriangledown stmry 96 0 mathop x x stmaryrd #already in cmsy
#bigtriangleup stmry 97 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 bigcurlyvee stmry 98|106 0 mathop x x stmaryrd
bigcurlywedge stmry 99 0 mathop x x stmaryrd bigcurlywedge stmry 99|107 0 mathop x x stmaryrd
bigsqcap stmry 100 0 mathop x x stmaryrd bigsqcap stmry 100|108 0 mathop x x stmaryrd
bigbox stmry 101 0 mathop x x stmaryrd bigbox stmry 101|109 0 mathop x x stmaryrd
bigparallel stmry 102 0 mathop x x stmaryrd bigparallel stmry 102|110 0 mathop x x stmaryrd
biginterleave stmry 103 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 #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 #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 #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 #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 #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 #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 #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 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 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 #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 # If the wasysym integrals are really wanted then one has to load the package
# manually and disable automatic loading of amsmath and esint. # manually and disable automatic loading of amsmath and esint.
iffont esint iffont esint
int esint 001 0 mathop ∫ ∫ esint|amsmath int esint 001|002 0 mathop ∫ ∫ esint|amsmath
intop esint 001 0 mathop ∫ ∫ esint intop esint 001|002 0 mathop ∫ ∫ esint
iint esint 003 0 mathop ∬ ∬ esint|amsmath iint esint 003|004 0 mathop ∬ ∬ esint|amsmath
iintop esint 003 0 mathop ∬ ∬ esint iintop esint 003|004 0 mathop ∬ ∬ esint
iiint esint 005 0 mathop ∭ ∭ esint|amsmath iiint esint 005|006 0 mathop ∭ ∭ esint|amsmath
iiintop esint 005 0 mathop ∭ ∭ esint iiintop esint 005|006 0 mathop ∭ ∭ esint
iiiint esint 007 0 mathop ⨌ ⨌ esint|amsmath iiiint esint 007|008 0 mathop ⨌ ⨌ esint|amsmath
iiiintop esint 007 0 mathop ⨌ ⨌ esint iiiintop esint 007|008 0 mathop ⨌ ⨌ esint
#9 codepoint forbidden in qt4, 10,12,13 in qt5 #9 codepoint forbidden in qt4, 10,12,13 in qt5
oint esint 043 0 mathop ∮ ∮ esint oint esint 043|044 0 mathop ∮ ∮ esint
ointop esint 043 0 mathop ∮ ∮ esint ointop esint 043|044 0 mathop ∮ ∮ esint
oiint esint 045 0 mathop ∯ ∯ esint oiint esint 045|046 0 mathop ∯ ∯ esint
oiintop esint 045 0 mathop ∯ ∯ esint oiintop esint 045|046 0 mathop ∯ ∯ esint
sqint esint 015 0 mathop ⨖ ⨖ esint sqint esint 015|016 0 mathop ⨖ ⨖ esint
sqintop esint 015 0 mathop ⨖ ⨖ esint sqintop esint 015|016 0 mathop ⨖ ⨖ esint
sqiint esint 017 0 mathop x esint sqiint esint 017|018 0 mathop x esint
sqiintop esint 017 0 mathop x esint sqiintop esint 017|017 0 mathop x esint
dotsint esint 041 0 mathop ∫⋯∫ ∫⋯∫ esint dotsint esint 041|042 0 mathop ∫⋯∫ ∫⋯∫ esint
dotsintop esint 042 0 mathop ∫⋯∫ ∫⋯∫ esint dotsintop esint 041|042 0 mathop ∫⋯∫ ∫⋯∫ esint
ointctrclockwise esint 023 0 mathop ∳ ∳ esint ointctrclockwise esint 023|024 0 mathop ∳ ∳ esint
ointctrclockwiseop esint 023 0 mathop ∳ ∳ esint ointctrclockwiseop esint 023|024 0 mathop ∳ ∳ esint
ointclockwise esint 025 0 mathop ∲ ∲ esint ointclockwise esint 025|026 0 mathop ∲ ∲ esint
ointclockwiseop esint 025 0 mathop ∲ ∲ esint ointclockwiseop esint 025|026 0 mathop ∲ ∲ esint
else else
int cmex 82 242 mathop ∫ ∫ esint|amsmath int cmex 82|90 242 mathop ∫ ∫ esint|amsmath
intop cmex 82 242 mathop ∫ ∫ esint intop cmex 82|90 242 mathop ∫ ∫ esint
iint wasy 115 0 mathop ∬ ∬ esint|amsmath iint wasy 115|120 0 mathop ∬ ∬ esint|amsmath
iintop wasy 115 0 mathop &Int ∬ esint iintop wasy 115|120 0 mathop &Int ∬ esint
iiint wasy 116 0 mathop ∭ ∭ esint|amsmath iiint wasy 116|121 0 mathop ∭ ∭ esint|amsmath
iiintop wasy 116 0 mathop ∭ ∭ esint iiintop wasy 116|121 0 mathop ∭ ∭ esint
\def\iiiint{\int\kern-6mu\int\kern-6mu\int\kern-6mu\int} esint|amsmath \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\iiiintop{\int\kern-6mu\int\kern-6mu\int\kern-6mu\int} esint
\def\dotsint{\int\kern-3mu\cdots\kern-3mu\int} esint \def\dotsint{\int\kern-3mu\cdots\kern-3mu\int} esint
\def\dotsintop{\int\kern-3mu\cdots\kern-3mu\int} esint \def\dotsintop{\int\kern-3mu\cdots\kern-3mu\int} esint
oint cmex 72 0 mathop ∮ ∮ esint oint cmex 72|73 0 mathop ∮ ∮ esint
ointop cmex 72 0 mathop ∮ ∮ esint ointop cmex 72|73 0 mathop ∮ ∮ esint
oiint wasy 118 0 mathop ∯ ∯ esint oiint wasy 118|123 0 mathop ∯ ∯ esint
oiintop wasy 118 0 mathop ∯ ∯ esint oiintop wasy 118|123 0 mathop ∯ ∯ esint
\def\sqint{\square\kern-17mu\int\kern6mu} esint \def\sqint{\square\kern-17mu\int\kern6mu} esint
\def\sqintop{\square\kern-17mu\int\kern6mu} esint \def\sqintop{\square\kern-17mu\int\kern6mu} esint
\def\sqiint{\square\kern-20mu\iint\kern3mu} 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 \def\ointclockwiseop{\circlearrowright\kern-21mu\int\kern6mu} esint
endif endif
varointclockwise esint 027 0 mathop ∲ ∲ esint varointclockwise esint 027|028 0 mathop ∲ ∲ esint
varointclockwiseop esint 027 0 mathop ∲ ∲ esint varointclockwiseop esint 027|028 0 mathop ∲ ∲ esint
varointctrclockwise esint 029 0 mathop ∳ ∳ esint varointctrclockwise esint 029|030 0 mathop ∳ ∳ esint
varointctrclockwiseop esint 029 0 mathop ∳ ∳ esint varointctrclockwiseop esint 029|030 0 mathop ∳ ∳ esint
fint esint 031 0 mathop ⨏ ⨏ esint fint esint 031|032 0 mathop ⨏ ⨏ esint
fintop esint 031 0 mathop ⨏ ⨏ esint fintop esint 031|032 0 mathop ⨏ ⨏ esint
varoiint esint 033 0 mathop ∯ ∯ esint varoiint esint 033|034 0 mathop ∯ ∯ esint
varoiintop esint 033 0 mathop ∯ ∯ esint varoiintop esint 033|034 0 mathop ∯ ∯ esint
landupint esint 035 0 mathop x x esint landupint esint 035|036 0 mathop x x esint
landupintop esint 035 0 mathop x x esint landupintop esint 035|036 0 mathop x x esint
landdownint esint 037 0 mathop x x esint landdownint esint 037|038 0 mathop x x esint
landdownintop esint 037 0 mathop x x esint landdownintop esint 037|038 0 mathop x x esint
# From the amsmath package: # From the amsmath package:

View File

@ -60,17 +60,32 @@ docstring InsetMathSymbol::name() const
void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
{ {
// set dim
mathedSymbolDim(mi.base, dim, sym_); mathedSymbolDim(mi.base, dim, sym_);
// set kerning_ if (sym_->draw != sym_->name) {
kerning_ = mathed_char_kerning(mi.base.font, *sym_->draw.rbegin()); // set dim
// correct height for broken cmex and wasy font // FIXME: this should depend on BufferView
if (sym_->inset == "cmex" || sym_->inset == "wasy") { // set kerning_
h_ = 4 * dim.des / 5; 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.asc += h_;
dim.des -= h_; dim.des -= h_;
} }
// set scriptable_ // set scriptable_
//FIXME: get rid of that? Only "funclim" probably, along with
// class==MC_OP. The issue is to implement \limits properly.
scriptable_ = false; scriptable_ = false;
if (mi.base.font.style() == DISPLAY_STYLE) if (mi.base.font.style() == DISPLAY_STYLE)
if (sym_->inset == "cmex" || sym_->inset == "esint" || if (sym_->inset == "cmex" || sym_->inset == "esint" ||

View File

@ -155,6 +155,7 @@ void initSymbols()
bool skip = false; bool skip = false;
while (getline(fs, line)) { while (getline(fs, line)) {
int charid = 0; int charid = 0;
int dsp_charid = 0;
int fallbackid = 0; int fallbackid = 0;
if (line.empty() || line[0] == '#') if (line.empty() || line[0] == '#')
continue; continue;
@ -243,9 +244,12 @@ void initSymbols()
docstring help; docstring help;
is >> tmp.name >> help; is >> tmp.name >> help;
tmp.inset = to_ascii(help); tmp.inset = to_ascii(help);
if (isFontName(tmp.inset)) if (isFontName(tmp.inset)) {
is >> charid >> fallbackid >> tmp.extra >> tmp.htmlname >> tmp.xmlname; is >> help >> fallbackid >> tmp.extra >> tmp.htmlname >> tmp.xmlname;
else docstring cid, dsp_cid;
idocstringstream is2(subst(help, '|', ' '));
is2 >> charid >> dsp_charid;
} else
is >> tmp.extra; is >> tmp.extra;
// requires is optional // requires is optional
if (is) { if (is) {
@ -289,6 +293,10 @@ void initSymbols()
} else if (isMathFontAvailable(tmp.inset) && canBeDisplayed(charid)) { } else if (isMathFontAvailable(tmp.inset) && canBeDisplayed(charid)) {
LYXERR(Debug::MATHED, "symbol available for " << to_utf8(tmp.name)); LYXERR(Debug::MATHED, "symbol available for " << to_utf8(tmp.name));
tmp.draw.push_back(char_type(charid)); 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) && } else if (fallbackid && isMathFontAvailable(symbol_font) &&
canBeDisplayed(fallbackid)) { canBeDisplayed(fallbackid)) {
if (tmp.inset == "cmex") if (tmp.inset == "cmex")

View File

@ -52,6 +52,9 @@ public:
* on screen. * on screen.
*/ */
docstring draw; docstring draw;
/// the same thing, but as an alternative in display mode
// Useful for \sum operator, for example
docstring dsp_draw;
/// operator/..., fontname e /// operator/..., fontname e
docstring extra; docstring extra;
/// how is this called as HTML entity in MathML? /// how is this called as HTML entity in MathML?

View File

@ -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) void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
{ {
LASSERT((bool)sym, return); LASSERT((bool)sym, return);
@ -686,7 +693,7 @@ void mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym)
mb.fontname == "mathit"; mb.fontname == "mathit";
std::string const font = italic_upcase_greek ? "cmm" : sym->inset; std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
Changer dummy = mb.changeFontSet(font); 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; std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
Changer dummy = pi.base.changeFontSet(font); Changer dummy = pi.base.changeFontSet(font);
pi.draw(x, y, sym->draw); pi.draw(x, y, mathedSymbol(pi.base, sym));
} }

View File

@ -55,6 +55,8 @@ void mathed_string_dim(FontInfo const & font,
int mathed_string_width(FontInfo const &, docstring const & s); 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 mathedSymbolDim(MetricsBase & mb, Dimension & dim, latexkeys const * sym);
void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym); void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym);