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
This commit is contained in:
Enrico Forestieri 2007-03-21 17:21:59 +00:00
parent 2593c4b206
commit 5b2d7ec76d
12 changed files with 47 additions and 4 deletions

View File

@ -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; }
};
///

View File

@ -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_))

View File

@ -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

View File

@ -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<InsetBase> doClone() const;

View File

@ -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();

View File

@ -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.

View File

@ -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;

View File

@ -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_;
};

View File

@ -282,6 +282,8 @@ void MathArray::metrics(MetricsInfo & mi) const
#endif
at->metrics(mi, d);
dim_ += d;
if (i == n - 1)
kerning_ = at->kerning();
}
}

View File

@ -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?

View File

@ -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)

View File

@ -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);