From: Enrico Forestieri Date: Wed, 21 Mar 2007 17:21:59 +0000 (+0000) Subject: Account for real width of nucleus when positioning superscripts in mathed X-Git-Tag: 1.6.10~10555 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=5b2d7ec76d5c418519177a81053cb9d1241ece03;p=features.git Account for real width of nucleus when positioning superscripts in mathed * src/mathed/MathSupport.[Ch] (mathed_char_kerning): New. Compute right kerning for the given font and character as the difference between right bearing and logical width. * src/mathed/InsetMathScript.[Ch] (InsetMathScript::dx1, InsetMathScript::metrics): Account for nucleus right kerning. (InsetMathScript::nker): New. Return the nucleus right kerning if positive, zero otherwise. * src/mathed/MathData.[Ch] (MathArray::metrics): Cache the nucleus right kerning value. (MathArray::kerning): New. Return cached right kerning. * src/mathed/InsetMathChar.[Ch] (InsetMathChar::metrics): Cache the character right kerning. (InsetMathChar::kerning): New. Return cached right kerning. * src/mathed/InsetMath.h (InsetMath::kerning): New virtual method. * src/mathed/InsetMathSymbol.[Ch] (InsetMathSymbol::metrics): Cache the symbol right kerning. (InsetMathSymbol::kerning): New. Return cached right kerning. * src/mathed/InsetMathFont.[Ch] (InsetMathFont::kerning): New. Return cached right kerning. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17497 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index 90b8aabb09..6602d98b9c 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -200,6 +200,9 @@ public: /// math stuff usually isn't allowed in text mode virtual bool allowedIn(mode_type mode) const { return mode == MATH_MODE; } + + /// superscript kerning + virtual int kerning() const { return 0; } }; /// diff --git a/src/mathed/InsetMathChar.C b/src/mathed/InsetMathChar.C index 3557d2efc4..192ff94be9 100644 --- a/src/mathed/InsetMathChar.C +++ b/src/mathed/InsetMathChar.C @@ -46,7 +46,7 @@ namespace { InsetMathChar::InsetMathChar(char_type c) - : char_(c) + : char_(c), kerning_(0) {} @@ -70,7 +70,9 @@ bool InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const ShapeChanger dummy(mi.base.font, LyXFont::UP_SHAPE); dim = theFontMetrics(mi.base.font).dimension(char_); } else { - dim = theFontMetrics(mi.base.font).dimension(char_); + frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); + dim = fm.dimension(char_); + kerning_ = fm.rbearing(char_) - dim.wid; } int const em = mathed_char_width(mi.base.font, 'M'); if (isBinaryOp(char_)) diff --git a/src/mathed/InsetMathChar.h b/src/mathed/InsetMathChar.h index 8ee4e9c5cc..91bd159939 100644 --- a/src/mathed/InsetMathChar.h +++ b/src/mathed/InsetMathChar.h @@ -32,6 +32,8 @@ public: void drawT(TextPainter &, int x, int y) const; /// int width() const { return width_; } + /// + int kerning() const { return kerning_; } /// void write(WriteStream & os) const; @@ -54,6 +56,8 @@ private: char_type char_; /// cached width mutable int width_; + /// cached kerning for superscript + mutable int kerning_; }; } // namespace lyx diff --git a/src/mathed/InsetMathFont.h b/src/mathed/InsetMathFont.h index 085ca65b56..72a0728a6a 100644 --- a/src/mathed/InsetMathFont.h +++ b/src/mathed/InsetMathFont.h @@ -45,6 +45,8 @@ public: void validate(LaTeXFeatures & features) const; /// void infoize(odocstream & os) const; + /// + int kerning() const { return cell(0).kerning(); } private: virtual std::auto_ptr doClone() const; diff --git a/src/mathed/InsetMathScript.C b/src/mathed/InsetMathScript.C index d7e1d879bc..e65d9c74a4 100644 --- a/src/mathed/InsetMathScript.C +++ b/src/mathed/InsetMathScript.C @@ -225,7 +225,7 @@ int InsetMathScript::dx0() const int InsetMathScript::dx1() const { BOOST_ASSERT(hasUp()); - return hasLimits() ? (dim_.wid - up().width()) / 2 : nwid(); + return hasLimits() ? (dim_.wid - up().width()) / 2 : nwid() + nker(); } @@ -253,6 +253,16 @@ int InsetMathScript::ndes() const } +int InsetMathScript::nker() const +{ + if (nuc().size()) { + int kerning = nuc().kerning(); + return kerning > 0 ? kerning : 0; + } + return 0; +} + + bool InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const { cell(0).metrics(mi); @@ -270,7 +280,7 @@ bool InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = max(dim.wid, down().width()); } else { if (hasUp()) - dim.wid = max(dim.wid, up().width()); + dim.wid = max(dim.wid, nker() + up().width()); if (hasDown()) dim.wid = max(dim.wid, down().width()); dim.wid += nwid(); diff --git a/src/mathed/InsetMathScript.h b/src/mathed/InsetMathScript.h index 1a631b3ba8..9f346e21c0 100644 --- a/src/mathed/InsetMathScript.h +++ b/src/mathed/InsetMathScript.h @@ -124,6 +124,8 @@ private: int nasc() const; /// returns descent of nucleus if any int ndes() const; + /// returns superscript kerning of nucleus if any + int nker() const; /// where do we have to draw the scripts? bool hasLimits() const; /// clean up empty cells and return true if a cell has been deleted. diff --git a/src/mathed/InsetMathSymbol.C b/src/mathed/InsetMathSymbol.C index 1a5176b666..15ef723034 100644 --- a/src/mathed/InsetMathSymbol.C +++ b/src/mathed/InsetMathSymbol.C @@ -64,6 +64,8 @@ bool InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const int const em = mathed_char_width(mi.base.font, 'M'); FontSetChanger dummy(mi.base, sym_->inset); mathed_string_dim(mi.base.font, sym_->draw, dim); + docstring::const_reverse_iterator rit = sym_->draw.rbegin(); + kerning_ = mathed_char_kerning(mi.base.font, *rit); // correct height for broken cmex and wasy font if (sym_->inset == "cmex" || sym_->inset == "wasy") { h_ = 4 * dim.des / 5; diff --git a/src/mathed/InsetMathSymbol.h b/src/mathed/InsetMathSymbol.h index c34d30c696..5ac141724c 100644 --- a/src/mathed/InsetMathSymbol.h +++ b/src/mathed/InsetMathSymbol.h @@ -37,6 +37,8 @@ public: void draw(PainterInfo &, int x, int y) const; /// int width() const { return width_; } + /// + int kerning() const { return kerning_; } /// bool isRelOp() const; @@ -76,6 +78,8 @@ private: mutable int h_; /// cached width mutable int width_; + /// cached superscript kerning + mutable int kerning_; /// mutable bool scriptable_; }; diff --git a/src/mathed/MathData.C b/src/mathed/MathData.C index 2509dae423..babbef64b8 100644 --- a/src/mathed/MathData.C +++ b/src/mathed/MathData.C @@ -282,6 +282,8 @@ void MathArray::metrics(MetricsInfo & mi) const #endif at->metrics(mi, d); dim_ += d; + if (i == n - 1) + kerning_ = at->kerning(); } } diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h index db7b28024e..1fdac721e8 100644 --- a/src/mathed/MathData.h +++ b/src/mathed/MathData.h @@ -158,6 +158,8 @@ public: int slevel() const { return slevel_; } /// additional super/subscript shift int sshift() const { return sshift_; } + /// superscript kerning + int kerning() const { return kerning_; } protected: /// cached dimensions of cell @@ -167,6 +169,7 @@ protected: mutable int mindes_; mutable int slevel_; mutable int sshift_; + mutable int kerning_; private: /// is this an exact match at this position? diff --git a/src/mathed/MathSupport.C b/src/mathed/MathSupport.C index 44a5393d09..f338e08c49 100644 --- a/src/mathed/MathSupport.C +++ b/src/mathed/MathSupport.C @@ -373,6 +373,13 @@ int mathed_char_width(LyXFont const & font, char_type c) } +int mathed_char_kerning(LyXFont const & font, char_type c) +{ + frontend::FontMetrics const & fm = theFontMetrics(font); + return fm.rbearing(c) - fm.width(c); +} + + void mathed_string_dim(LyXFont const & font, docstring const & s, Dimension & dim) diff --git a/src/mathed/MathSupport.h b/src/mathed/MathSupport.h index d872b371f9..b37d42bc33 100644 --- a/src/mathed/MathSupport.h +++ b/src/mathed/MathSupport.h @@ -30,6 +30,8 @@ class InsetMath; int mathed_char_width(LyXFont const &, char_type c); +int mathed_char_kerning(LyXFont const &, char_type c); + void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h, docstring const & name);