diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index b23ffb5179..088fce6c2b 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -162,8 +162,12 @@ public: /// identifies things that can get scripts virtual bool isScriptable() const { return false; } - /// is the a relational operator (used for splitting equations) - virtual bool isRelOp() const { return false; } + /// identifies a binary operators (used for spacing) + virtual bool isMathBin() const { return false; } + /// identifies relational operators (used for spacing and splitting equations) + virtual bool isMathRel() const { return false; } + /// identifies punctuation (used for spacing) + virtual bool isMathPunct() const { return false; } /// will this get written as a single block in {..} virtual bool extraBraces() const { return false; } diff --git a/src/mathed/InsetMathChar.cpp b/src/mathed/InsetMathChar.cpp index 713e1353e6..2879ac91fc 100644 --- a/src/mathed/InsetMathChar.cpp +++ b/src/mathed/InsetMathChar.cpp @@ -26,7 +26,6 @@ #include "support/debug.h" #include "support/lstrings.h" -#include "support/lyxlib.h" #include "support/textutils.h" @@ -35,12 +34,6 @@ namespace lyx { extern bool has_math_fonts; -static bool isBinaryOp(char_type c) -{ - return support::contains("+-<>=/*", static_cast(c)); -} - - static bool slanted(char_type c) { return isAlphaASCII(c) || Encodings::isMathAlpha(c); @@ -76,11 +69,15 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const dim = fm.dimension(char_); kerning_ = fm.rbearing(char_) - dim.wid; } - int const em = mathed_font_em(mi.base.font); - if (isBinaryOp(char_)) - dim.wid += support::iround(0.5 * em); + if (isMathBin()) + dim.wid += 2 * mathed_medmuskip(mi.base.font); + else if (isMathRel()) + dim.wid += 2 * mathed_thickmuskip(mi.base.font); + else if (isMathPunct()) + dim.wid += mathed_thinmuskip(mi.base.font); else if (char_ == '\'') - dim.wid += support::iround(0.1667 * em); + // FIXME: don't know where this is coming from + dim.wid += mathed_thinmuskip(mi.base.font); #else whichFont(font_, code_, mi); dim = theFontMetrics(font_).dimension(char_); @@ -94,11 +91,12 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const void InsetMathChar::draw(PainterInfo & pi, int x, int y) const { //lyxerr << "drawing '" << char_ << "' font: " << pi.base.fontname << std::endl; - int const em = mathed_font_em(pi.base.font); - if (isBinaryOp(char_)) - x += support::iround(0.25 * em); + if (isMathBin()) + x += mathed_medmuskip(pi.base.font); + else if (isMathRel()) + x += mathed_thickmuskip(pi.base.font); else if (char_ == '\'') - x += support::iround(0.0833 * em); + x += mathed_thinmuskip(pi.base.font) / 2; #if 1 if (char_ == '=' && has_math_fonts) { FontSetChanger dummy(pi.base, "cmr"); @@ -237,9 +235,21 @@ void InsetMathChar::htmlize(HtmlStream & ms) const } -bool InsetMathChar::isRelOp() const +bool InsetMathChar::isMathBin() const { - return char_ == '=' || char_ == '<' || char_ == '>'; + return support::contains("+-*", static_cast(char_)); +} + + +bool InsetMathChar::isMathRel() const +{ + return support::contains("<>=:", static_cast(char_)); +} + + +bool InsetMathChar::isMathPunct() const +{ + return support::contains(",;", static_cast(char_)); } diff --git a/src/mathed/InsetMathChar.h b/src/mathed/InsetMathChar.h index 65fac82fff..67bbc64e8c 100644 --- a/src/mathed/InsetMathChar.h +++ b/src/mathed/InsetMathChar.h @@ -49,7 +49,11 @@ public: /// char_type getChar() const { return char_; } /// - bool isRelOp() const; + bool isMathBin() const; + /// + bool isMathRel() const; + /// + bool isMathPunct() const; /// InsetCode lyxCode() const { return MATH_CHAR_CODE; } diff --git a/src/mathed/InsetMathDelim.cpp b/src/mathed/InsetMathDelim.cpp index 8e8b6e295b..b10d37ad69 100644 --- a/src/mathed/InsetMathDelim.cpp +++ b/src/mathed/InsetMathDelim.cpp @@ -115,7 +115,7 @@ void InsetMathDelim::metrics(MetricsInfo & mi, Dimension & dim) const dw_ = 8; if (dw_ < 4) dw_ = 4; - dim.wid = dim0.width() + 2 * dw_ + 8; + dim.wid = dim0.width() + 2 * dw_ + 2 * mathed_thinmuskip(mi.base.font); dim.asc = max(a0, d0) + h0; dim.des = max(a0, d0) - h0; } @@ -125,9 +125,10 @@ void InsetMathDelim::draw(PainterInfo & pi, int x, int y) const { Dimension const dim = dimension(*pi.base.bv); int const b = y - dim.asc; - cell(0).draw(pi, x + dw_ + 4, y); - mathed_draw_deco(pi, x + 4, b, dw_, dim.height(), left_); - mathed_draw_deco(pi, x + dim.width() - dw_ - 4, + int const skip = mathed_thinmuskip(pi.base.font); + cell(0).draw(pi, x + dw_ + skip, y); + mathed_draw_deco(pi, x + skip, b, dw_, dim.height(), left_); + mathed_draw_deco(pi, x + dim.width() - dw_ - skip, b, dw_, dim.height(), right_); setPosCache(pi, x, y); } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 48792a81ae..34955147e2 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -106,7 +106,7 @@ namespace { size_t firstRelOp(MathData const & ar) { for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) - if ((*it)->isRelOp()) + if ((*it)->isMathRel()) return it - ar.begin(); return ar.size(); } diff --git a/src/mathed/InsetMathSymbol.cpp b/src/mathed/InsetMathSymbol.cpp index a160dec684..a04f6e0bcf 100644 --- a/src/mathed/InsetMathSymbol.cpp +++ b/src/mathed/InsetMathSymbol.cpp @@ -21,7 +21,6 @@ #include "support/debug.h" #include "support/docstream.h" -#include "support/lyxlib.h" #include "support/textutils.h" #include @@ -68,7 +67,6 @@ void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const sym_->extra == "mathalpha" && mi.base.fontname == "mathit"; std::string const font = italic_upcase_greek ? "cmm" : sym_->inset; - int const em = mathed_font_em(mi.base.font); FontSetChanger dummy(mi.base, from_ascii(font)); mathed_string_dim(mi.base.font, sym_->draw, dim); docstring::const_reverse_iterator rit = sym_->draw.rbegin(); @@ -80,10 +78,15 @@ void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const dim.des -= h_; } // seperate things a bit - if (isRelOp()) - dim.wid += support::iround(0.5 * em); - else - dim.wid += support::iround(0.1667 * em); + if (isMathBin()) + dim.wid += 2 * mathed_medmuskip(mi.base.font); + else if (isMathRel()) + dim.wid += 2 * mathed_thickmuskip(mi.base.font); + else if (isMathPunct()) + dim.wid += mathed_thinmuskip(mi.base.font); + // FIXME: I see no reason for this + //else + // dim.wid += support::iround(0.1667 * em); scriptable_ = false; if (mi.base.style == LM_ST_DISPLAY) @@ -105,11 +108,13 @@ void InsetMathSymbol::draw(PainterInfo & pi, int x, int y) const sym_->extra == "mathalpha" && pi.base.fontname == "mathit"; std::string const font = italic_upcase_greek ? "cmm" : sym_->inset; - int const em = mathed_font_em(pi.base.font); - if (isRelOp()) - x += support::iround(0.25 * em); - else - x += support::iround(0.0833 * em); + if (isMathBin()) + x += mathed_medmuskip(pi.base.font); + else if (isMathRel()) + x += mathed_thickmuskip(pi.base.font); + // FIXME: I see no reason for this + //else + // x += support::iround(0.0833 * em); FontSetChanger dummy(pi.base, from_ascii(font)); pi.draw(x, y - h_, sym_->draw); @@ -122,12 +127,24 @@ InsetMath::mode_type InsetMathSymbol::currentMode() const } -bool InsetMathSymbol::isRelOp() const +bool InsetMathSymbol::isMathBin() const +{ + return sym_->extra == "mathbin"; +} + + +bool InsetMathSymbol::isMathRel() const { return sym_->extra == "mathrel"; } +bool InsetMathSymbol::isMathPunct() const +{ + return sym_->extra == "mathpunct"; +} + + bool InsetMathSymbol::isOrdAlpha() const { return sym_->extra == "mathord" || sym_->extra == "mathalpha"; diff --git a/src/mathed/InsetMathSymbol.h b/src/mathed/InsetMathSymbol.h index bb18217a84..6ca3ded7d1 100644 --- a/src/mathed/InsetMathSymbol.h +++ b/src/mathed/InsetMathSymbol.h @@ -40,7 +40,11 @@ public: /// mode_type currentMode() const; /// - bool isRelOp() const; + bool isMathRel() const; + /// + bool isMathBin() const; + /// + bool isMathPunct() const; /// bool isOrdAlpha() const; /// do we take scripts? diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp index 9801151129..7769176e7a 100644 --- a/src/mathed/MathSupport.cpp +++ b/src/mathed/MathSupport.cpp @@ -25,6 +25,7 @@ #include "support/debug.h" #include "support/docstream.h" +#include "support/lyxlib.h" #include #include @@ -506,6 +507,46 @@ int mathed_font_em(FontInfo const & font) return theFontMetrics(font).em(); } +/* The math units. Quoting TeX by Topic, p.205: + * + * Spacing around mathematical objects is measured in mu units. A mu + * is 1/18th part of \fontdimen6 of the font in family 2 in the + * current style, the ‘quad’ value of the symbol font. + * + * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is + * inserted around (binary) relations, except where these are preceded + * or followed by other relations or punctuation, and except if they + * follow an open, or precede a close symbol. + * + * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu) + * is put around binary operators. + * + * A \thinmuskip (default value in plain TeX: 3mu) follows after + * 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. + */ + +int mathed_thinmuskip(FontInfo font) +{ + font.setFamily(SYMBOL_FAMILY); + return support::iround(3.0 / 18 * theFontMetrics(font).em()); +} + + +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_char_width(FontInfo const & font, char_type c) { diff --git a/src/mathed/MathSupport.h b/src/mathed/MathSupport.h index aa5ef2adc2..c14f21a807 100644 --- a/src/mathed/MathSupport.h +++ b/src/mathed/MathSupport.h @@ -29,6 +29,12 @@ class InsetMath; int mathed_font_em(FontInfo const &); +int mathed_thinmuskip(FontInfo font); + +int mathed_medmuskip(FontInfo font); + +int mathed_thickmuskip(FontInfo font); + int mathed_char_width(FontInfo const &, char_type c); int mathed_char_kerning(FontInfo const &, char_type c);