mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Cleanup of spacing in mathed
This is a first cleanup step. More complex rules have to be implemented on top of this. Use proper spacing \thinmuskip, \medmuskip and \thickmuskip instead of ad-hoc values. Rename isRelOp to isMathRel and introduce isMathBin and isMathPunct (for InsetMathChar and InsetMathSymbol). Update the categories of characters in InsetMathChar according to LaTeX source (fontmath.ltx). Set correctly the spacing around mathrel, mathbin and mathpunct elements. Use \thinmuskip around MathDelim instead of a hardcoded 4. This is related to bug #8883.
This commit is contained in:
parent
320b616c50
commit
65a6cc1fc3
@ -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; }
|
||||
|
||||
|
@ -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<char>(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>(char_));
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathRel() const
|
||||
{
|
||||
return support::contains("<>=:", static_cast<char>(char_));
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathPunct() const
|
||||
{
|
||||
return support::contains(",;", static_cast<char>(char_));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstream.h"
|
||||
#include "support/lyxlib.h"
|
||||
#include "support/textutils.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
@ -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";
|
||||
|
@ -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?
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/docstream.h"
|
||||
#include "support/lyxlib.h"
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user