Trying to solve bug-2452, I optimized some of the most significant problems outlined in the profile report attached in there.

This commit avoids unnecessary metrics recalculations by caching the last LyXFont used. I had to cleanup the width(), ascent() and descend() redundancies by transferring that to InsetBase.

InsetMathDim should go now as it is not really needed.

* InsetBase: properly handle inset Dimension.

* InsetOld: get rid of redundant width(), ascent() and descent()

* InsetMathDim: ditto

* InsetMathChar::metrics(): avoid metrics recalculation if font is unchanged.

* InsetMathSymbol::metrics(): ditto

* InsetMathKern: use InsetBase::dim_ instead of local ones.

* InsetMathSpace:
  - use InsetBase::dim_ instead of local ones.
  - space to width transformation transferred to anonymous namespace.



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17899 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2007-04-22 08:26:06 +00:00
parent 48744f0fbd
commit 24c8ca10d2
13 changed files with 90 additions and 147 deletions

View File

@ -53,24 +53,6 @@ LColor_color InsetOld::backgroundColor() const
}
int InsetOld::ascent() const
{
return dim_.asc;
}
int InsetOld::descent() const
{
return dim_.des;
}
int InsetOld::width() const
{
return dim_.wid;
}
void InsetOld::setPosCache(PainterInfo const & pi, int x, int y) const
{
//lyxerr << "InsetOld:: position cache to " << x << " " << y << std::endl;

View File

@ -35,12 +35,6 @@ public:
///
InsetOld();
///
int ascent() const;
///
int descent() const;
///
int width() const;
///
void setInsetName(docstring const & s) { name_ = s; }

View File

@ -436,12 +436,12 @@ public:
/// reject the changes within the inset
virtual void rejectChanges(BufferParams const &) {};
/// pretty arbitrary
virtual int width() const { return 10; }
/// pretty arbitrary
virtual int ascent() const { return 10; }
/// pretty arbitrary
virtual int descent() const { return 10; }
/// inset width.
int width() const { return dim_.wid; }
/// inset ascent.
int ascent() const { return dim_.asc; }
/// inset descent.
int descent() const { return dim_.des; }
///
int scroll() const { return 0; }
///
@ -453,8 +453,9 @@ public:
///
virtual void setStatus(LCursor &, CollapseStatus) {}
protected:
InsetBase() {}
InsetBase(InsetBase const &) {}
/// pretty arbitrary dimensions
InsetBase(): dim_(10, 10, 10) {}
InsetBase(InsetBase const & i): dim_(i.dim_) {}
/** The real dispatcher.
* Gets normally called from LCursor::dispatch(). LCursor::dispatch()
* assumes the common case of 'LFUN handled, need update'.

View File

@ -59,6 +59,12 @@ auto_ptr<InsetBase> InsetMathChar::doClone() const
bool InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
{
if (mi.base.font == font_cache_) {
dim = dim_;
return false;
}
font_cache_ = mi.base.font;
#if 1
if (char_ == '=' && has_math_fonts) {
FontSetChanger dummy(mi.base, "cmr");
@ -83,12 +89,9 @@ bool InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
whichFont(font_, code_, mi);
dim = theFontMetrics(font_).dimension(char_);
if (isBinaryOp(char_, code_))
width_ += 2 * theFontMetrics(font_).width(' ');
dim.wid += 2 * theFontMetrics(font_).width(' ');
lyxerr << "InsetMathChar::metrics: " << dim << endl;
#endif
width_ = dim.wid;
if (dim_ == dim)
return false;
dim_ = dim;
return true;
}

View File

@ -14,6 +14,7 @@
#include "InsetMath.h"
#include "lyxfont.h"
namespace lyx {
@ -31,8 +32,6 @@ public:
///
void drawT(TextPainter &, int x, int y) const;
///
int width() const { return width_; }
///
int kerning() const { return kerning_; }
///
@ -54,10 +53,10 @@ private:
virtual std::auto_ptr<InsetBase> doClone() const;
/// the character
char_type char_;
/// cached width
mutable int width_;
/// cached kerning for superscript
mutable int kerning_;
///
mutable LyXFont font_cache_;
};
} // namespace lyx

View File

@ -25,24 +25,6 @@ InsetMathDim::InsetMathDim()
{}
int InsetMathDim::ascent() const
{
return dim_.asc;
}
int InsetMathDim::descent() const
{
return dim_.des;
}
int InsetMathDim::width() const
{
return dim_.wid;
}
void InsetMathDim::setPosCache(PainterInfo const & pi, int x, int y) const
{
//lyxerr << "InsetMathDim: cache to " << x << " " << y << std::endl;

View File

@ -26,15 +26,6 @@ public:
///
InsetMathDim();
///
Dimension dimensions() const { return dim_; }
///
int ascent() const;
///
int descent() const;
///
int width() const;
///
void setPosCache(PainterInfo const & pi, int x, int y) const;
};

View File

@ -24,17 +24,26 @@ using std::auto_ptr;
InsetMathKern::InsetMathKern()
{}
{
dim_.asc = 0;
dim_.des = 0;
}
InsetMathKern::InsetMathKern(LyXLength const & w)
: wid_(w)
{}
{
dim_.asc = 0;
dim_.des = 0;
}
InsetMathKern::InsetMathKern(docstring const & s)
: wid_(to_utf8(s))
{}
{
dim_.asc = 0;
dim_.des = 0;
}
auto_ptr<InsetBase> InsetMathKern::doClone() const
@ -45,23 +54,15 @@ auto_ptr<InsetBase> InsetMathKern::doClone() const
bool InsetMathKern::metrics(MetricsInfo & mi, Dimension & dim) const
{
wid_pix_ = wid_.inPixels(0, mathed_char_width(mi.base.font, 'M'));
dim.wid = wid_pix_;
dim.asc = 0;
dim.des = 0;
if (dim_ == dim)
int wid_pixel = wid_.inPixels(0, mathed_char_width(mi.base.font, 'M'));
if (wid_pixel == dim_.wid)
return false;
dim_ = dim;
dim_.wid = wid_pixel;
dim = dim_;
return true;
}
int InsetMathKern::width() const
{
return wid_pix_;
}
void InsetMathKern::draw(PainterInfo &, int, int) const
{}

View File

@ -38,15 +38,10 @@ public:
void write(WriteStream & os) const;
///
void normalize(NormalStream & ns) const;
///
int width() const;
private:
virtual std::auto_ptr<InsetBase> doClone() const;
/// width in em
LyXLength wid_;
/// in pixels
mutable int wid_pix_;
};

View File

@ -34,30 +34,11 @@ char const * latex_mathspace[] = {
int const nSpace = sizeof(latex_mathspace)/sizeof(char *);
namespace {
InsetMathSpace::InsetMathSpace(int sp)
: space_(sp)
{}
InsetMathSpace::InsetMathSpace(docstring const & name)
: space_(1)
int spaceToWidth(int space)
{
for (int i = 0; i < nSpace; ++i)
if (latex_mathspace[i] == name)
space_ = i;
}
auto_ptr<InsetBase> InsetMathSpace::doClone() const
{
return auto_ptr<InsetBase>(new InsetMathSpace(*this));
}
int InsetMathSpace::width() const
{
switch (space_) {
switch (space) {
case 0: return 6;
case 1: return 8;
case 2: return 10;
@ -72,16 +53,32 @@ int InsetMathSpace::width() const
}
}
} // anon namespace
int InsetMathSpace::ascent() const
InsetMathSpace::InsetMathSpace(int sp)
: space_(sp)
{
return 4;
dim_.asc = 4;
dim_.des = 0;
dim_.wid = spaceToWidth(space_);
}
int InsetMathSpace::descent() const
InsetMathSpace::InsetMathSpace(docstring const & name)
: space_(1)
{
return 0;
dim_.asc = 4;
dim_.des = 0;
for (int i = 0; i < nSpace; ++i)
if (latex_mathspace[i] == name)
space_ = i;
dim_.wid = spaceToWidth(space_);
}
auto_ptr<InsetBase> InsetMathSpace::doClone() const
{
return auto_ptr<InsetBase>(new InsetMathSpace(*this));
}
@ -120,6 +117,7 @@ void InsetMathSpace::draw(PainterInfo & pi, int x, int y) const
void InsetMathSpace::incSpace()
{
space_ = (space_ + 1) % (nSpace - 2);
dim_.wid = spaceToWidth(space_);
}

View File

@ -32,12 +32,6 @@ public:
///
void incSpace();
///
int ascent() const;
///
int descent() const;
///
int width() const;
///
bool metrics(MetricsInfo & mi, Dimension & dim) const;
///
void draw(PainterInfo & pi, int x, int y) const;

View File

@ -29,17 +29,18 @@ using std::auto_ptr;
InsetMathSymbol::InsetMathSymbol(latexkeys const * l)
: sym_(l), h_(0), width_(0), scriptable_(false)
: sym_(l), h_(0), scriptable_(false), font_cache_(LyXFont::ALL_IGNORE)
{}
InsetMathSymbol::InsetMathSymbol(char const * name)
: sym_(in_word_set(from_ascii(name))), h_(0), width_(0), scriptable_(false)
: sym_(in_word_set(from_ascii(name))), h_(0), scriptable_(false),
font_cache_(LyXFont::ALL_IGNORE)
{}
InsetMathSymbol::InsetMathSymbol(docstring const & name)
: sym_(in_word_set(name)), h_(0), width_(0), scriptable_(false)
: sym_(in_word_set(name)), h_(0), scriptable_(false), font_cache_(LyXFont::ALL_IGNORE)
{}
@ -62,23 +63,30 @@ bool InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
// << "' drawn as: '" << sym_->draw
// << "'" << std::endl;
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;
dim.asc += h_;
dim.des -= h_;
}
bool dim_unchanged = (mi.base.font == font_cache_);
if (dim_unchanged)
dim = dim_;
else {
font_cache_ = mi.base.font;
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;
dim.asc += h_;
dim.des -= h_;
}
// seperate things a bit
if (isRelOp())
dim.wid += static_cast<int>(0.5 * em + 0.5);
else
dim.wid += static_cast<int>(0.1667 * em + 0.5);
// seperate things a bit
if (isRelOp())
dim.wid += static_cast<int>(0.5 * em + 0.5);
else
dim.wid += static_cast<int>(0.1667 * em + 0.5);
dim_ = dim;
}
scriptable_ = false;
if (mi.base.style == LM_ST_DISPLAY)
@ -86,11 +94,7 @@ bool InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
sym_->extra == "funclim")
scriptable_ = true;
width_ = dim.wid;
if (dim_ == dim)
return false;
dim_ = dim;
return true;
return dim_unchanged;
}

View File

@ -14,6 +14,7 @@
#include "InsetMath.h"
#include "lyxfont.h"
namespace lyx {
@ -36,8 +37,6 @@ public:
///
void draw(PainterInfo &, int x, int y) const;
///
int width() const { return width_; }
///
int kerning() const { return kerning_; }
///
@ -78,12 +77,12 @@ private:
latexkeys const * sym_;
///
mutable int h_;
/// cached width
mutable int width_;
/// cached superscript kerning
mutable int kerning_;
///
mutable bool scriptable_;
///
mutable LyXFont font_cache_;
};
} // namespace lyx