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

This patch avoid the metrics calculation by caching the last LyXFont used. I had to cleanup the width(), ascent() and descend() redundancies by transferring that to InsetBase.

This patch is pretty much mechanical, I have tested this extensively and I am _sure_ that there is no problem with it.

InsetMathDim should go now as it is not really needed. I'll do that after this patch is in.

Abdel.

Index: insets/inset.C
===================================================================
--- insets/inset.C      (revision 17897)
+++ insets/inset.C      (working copy)
@@ -53,24 +53,6 @@
 }
 
 
-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;
Index: insets/inset.h
===================================================================
--- insets/inset.h      (revision 17897)
+++ insets/inset.h      (working copy)
@@ -35,12 +35,6 @@
 
        ///
        InsetOld();
-       ///
-       int ascent() const;
-       ///
-       int descent() const;
-       ///
-       int width() const;
 
        ///
        void setInsetName(docstring const & s) { name_ = s; }
Index: insets/insetbase.h
===================================================================
--- insets/insetbase.h  (revision 17897)
+++ insets/insetbase.h  (working copy)
@@ -436,12 +436,12 @@
        /// 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 @@
        ///
        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'.
Index: mathed/InsetMathChar.C
===================================================================
--- mathed/InsetMathChar.C      (revision 17897)
+++ mathed/InsetMathChar.C      (working copy)
@@ -59,6 +59,12 @@
 
 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 @@
        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;
 }
Index: mathed/InsetMathChar.h
===================================================================
--- mathed/InsetMathChar.h      (revision 17897)
+++ mathed/InsetMathChar.h      (working copy)
@@ -14,6 +14,7 @@
 
 #include "InsetMath.h"
 
+#include "lyxfont.h"
 
 namespace lyx {
 
@@ -31,8 +32,6 @@
        ///
        void drawT(TextPainter &, int x, int y) const;
        ///
-       int width() const { return width_; }
-       ///
        int kerning() const { return kerning_; }
 
        ///
@@ -54,10 +53,10 @@
        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
Index: mathed/InsetMathDim.C
===================================================================
--- mathed/InsetMathDim.C       (revision 17897)
+++ mathed/InsetMathDim.C       (working copy)
@@ -25,24 +25,6 @@
 {}
 
 
-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;
Index: mathed/InsetMathDim.h
===================================================================
--- mathed/InsetMathDim.h       (revision 17897)
+++ mathed/InsetMathDim.h       (working copy)
@@ -27,15 +27,6 @@
        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;
 };
 
Index: mathed/InsetMathKern.C
===================================================================
--- mathed/InsetMathKern.C      (revision 17897)
+++ mathed/InsetMathKern.C      (working copy)
@@ -24,17 +24,26 @@
 
 
 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 @@
 
 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
 {}
 
Index: mathed/InsetMathKern.h
===================================================================
--- mathed/InsetMathKern.h      (revision 17897)
+++ mathed/InsetMathKern.h      (working copy)
@@ -38,15 +38,10 @@
        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_;
-
 };
 
 
Index: mathed/InsetMathSpace.C
===================================================================
--- mathed/InsetMathSpace.C     (revision 17897)
+++ mathed/InsetMathSpace.C     (working copy)
@@ -37,15 +37,22 @@
 
 InsetMathSpace::InsetMathSpace(int sp)
        : space_(sp)
-{}
+{
+       dim_.asc = 4;
+       dim_.des = 0;
+       updateWidth();
+}
 
 
 InsetMathSpace::InsetMathSpace(docstring const & name)
        : space_(1)
 {
+       dim_.asc = 4;
+       dim_.des = 0;
        for (int i = 0; i < nSpace; ++i)
                if (latex_mathspace[i] == name)
                        space_ = i;
+       updateWidth();
 }
 
 
@@ -55,36 +62,24 @@
 }
 
 
-int InsetMathSpace::width() const
+void InsetMathSpace::updateWidth()
 {
        switch (space_) {
-               case 0: return 6;
-               case 1: return 8;
-               case 2: return 10;
-               case 3: return 6;
-               case 4: return 8;
-               case 5: return 10;
-               case 6: return 20;
-               case 7: return 40;
-               case 8: return -2;
-               case 9: return  2;
-               default: return 6;
+               case 0: dim_.wid = 6; break;
+               case 1: dim_.wid = 8; break;
+               case 2: dim_.wid = 10; break;
+               case 3: dim_.wid = 6; break;
+               case 4: dim_.wid = 8; break;
+               case 5: dim_.wid = 10; break;
+               case 6: dim_.wid = 20; break;
+               case 7: dim_.wid = 40; break;
+               case 8: dim_.wid = -2; break;
+               case 9: dim_.wid =  2; break;
+               default: dim_.wid = 6;
        }
 }
 
 
-int InsetMathSpace::ascent() const
-{
-       return 4;
-}
-
-
-int InsetMathSpace::descent() const
-{
-       return 0;
-}
-
-
 bool InsetMathSpace::metrics(MetricsInfo &, Dimension & dim) const
 {
        dim.wid = width();
@@ -120,6 +115,7 @@
 void InsetMathSpace::incSpace()
 {
        space_ = (space_ + 1) % (nSpace - 2);
+       updateWidth();
 }
 
 
Index: mathed/InsetMathSpace.h
===================================================================
--- mathed/InsetMathSpace.h     (revision 17897)
+++ mathed/InsetMathSpace.h     (working copy)
@@ -32,12 +32,6 @@
        ///
        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;
@@ -57,6 +51,8 @@
 private:
        virtual std::auto_ptr<InsetBase> doClone() const;
        ///
+       void updateWidth();
+       ///
        int space_;
 };
 
Index: mathed/InsetMathSymbol.C
===================================================================
--- mathed/InsetMathSymbol.C    (revision 17897)
+++ mathed/InsetMathSymbol.C    (working copy)
@@ -29,17 +29,18 @@
 
 
 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,35 +63,38 @@
        //      << "' 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);
+
+               dim_ = dim;
        }
 
-       // 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);
-
        scriptable_ = false;
        if (mi.base.style == LM_ST_DISPLAY)
                if (sym_->inset == "cmex" || sym_->inset == "esint" ||
                    sym_->extra == "funclim")
                        scriptable_ = true;
 
-       width_ = dim.wid;
-       if (dim_ == dim)
-               return false;
-       dim_ = dim;
-       return true;
+       return dim_unchanged;
 }
 
 
Index: mathed/InsetMathSymbol.h
===================================================================
--- mathed/InsetMathSymbol.h    (revision 17897)
+++ mathed/InsetMathSymbol.h    (working copy)
@@ -14,6 +14,7 @@
 
 #include "InsetMath.h"
 
+#include "lyxfont.h"
 
 namespace lyx {
 
@@ -36,8 +37,6 @@
        ///
        void draw(PainterInfo &, int x, int y) const;
        ///
-       int width() const { return width_; }
-       ///
        int kerning() const { return kerning_; }
 
        ///
@@ -78,12 +77,12 @@
        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

Reply via email to