From 93baf8eb9b4df52aa86e0fe5de0b4cef57ba3e83 Mon Sep 17 00:00:00 2001 From: Stefan Schimanski Date: Thu, 24 May 2007 16:29:40 +0000 Subject: [PATCH] * do not lookup the same macro all the time * only update the representation if anything was changed (this gives a huge speedup), fixes #2452 * minor cleanup of the code, especially setting up the coordinate cache. Without this can lead to crashes if the macros do not mention all the arguments. * And a last fix included makes sure that the metrics are always in sync with the drawing. Before it was possible to go into the macro with the cursor in a way that the metrics were for the viewing mode, but the drawing was done for editing. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18489 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/MacroTable.h | 10 ++++++ src/mathed/MathMacro.cpp | 74 +++++++++++++++++++++++++--------------- src/mathed/MathMacro.h | 6 ++-- 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/mathed/MacroTable.h b/src/mathed/MacroTable.h index 7bc220a7e2..1909c04de4 100644 --- a/src/mathed/MacroTable.h +++ b/src/mathed/MacroTable.h @@ -49,6 +49,16 @@ public: /// void unlock() const { --lockCount_; BOOST_ASSERT(lockCount_ >= 0); } + /// + bool operator==(MacroData const & x) const { + return def_ == x.def_ && + numargs_ == x.numargs_ && + disp_ == x.disp_ && + requires_ == x.requires_; + } + /// + bool operator!=(MacroData const & x) const { return !operator==(x); } + private: /// docstring def_; diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index 6da3c6e596..ba1c34a37f 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -38,8 +38,8 @@ using std::vector; class MathMacroArgumentValue : public InsetMath { public: /// - MathMacroArgumentValue(MathData const * value, docstring const & macroName) - : value_(value), macroName_(macroName) {} + MathMacroArgumentValue(MathMacro const & mathMacro, size_t idx) + : mathMacro_(mathMacro), idx_(idx) {} /// bool metrics(MetricsInfo & mi, Dimension & dim) const; /// @@ -47,8 +47,8 @@ public: private: std::auto_ptr doClone() const; - MathData const * value_; - docstring macroName_; + MathMacro const & mathMacro_; + size_t idx_; }; @@ -61,9 +61,10 @@ auto_ptr MathMacroArgumentValue::doClone() const bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const { // unlock outer macro in arguments, and lock it again later - MacroTable::globalMacros().get(macroName_).unlock(); - value_->metrics(mi, dim); - MacroTable::globalMacros().get(macroName_).lock(); + MacroData const & macro = MacroTable::globalMacros().get(mathMacro_.name()); + macro.unlock(); + mathMacro_.cell(idx_).metrics(mi, dim); + macro.lock(); metricsMarkers2(dim); if (dim_ == dim) return false; @@ -75,20 +76,24 @@ bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const { // unlock outer macro in arguments, and lock it again later - MacroTable::globalMacros().get(macroName_).unlock(); - value_->draw(pi, x, y); - MacroTable::globalMacros().get(macroName_).lock(); + MacroData const & macro = MacroTable::globalMacros().get(mathMacro_.name()); + macro.unlock(); + mathMacro_.cell(idx_).draw(pi, x, y); + macro.lock(); } MathMacro::MathMacro(docstring const & name, int numargs) - : InsetMathNest(numargs), name_(name) + : InsetMathNest(numargs), name_(name), editing_(false) {} auto_ptr MathMacro::doClone() const { - return auto_ptr(new MathMacro(*this)); + MathMacro * x = new MathMacro(*this); + x->expanded_ = MathData(); + x->macroBackup_ = MacroData(); + return auto_ptr(x); } @@ -113,12 +118,13 @@ bool MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const mathed_string_dim(mi.base.font, "Unknown: " + name(), dim); } else { MacroData const & macro = MacroTable::globalMacros().get(name()); + + if (macroBackup_ != macro) + updateExpansion(); + if (macro.locked()) { mathed_string_dim(mi.base.font, "Self reference: " + name(), dim); - expanded_ = MathData(); } else if (editing(mi.base.bv)) { - // FIXME UNICODE - asArray(macro.def(), tmpl_); Font font = mi.base.font; augmentFont(font, from_ascii("lyxtex")); tmpl_.metrics(mi, dim); @@ -132,17 +138,12 @@ bool MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = max(dim.wid, c.width() + ww); dim.des += c.height() + 10; } + editing_ = true; } else { - // create MathMacroArgumentValue object pointing to the cells of the macro - MacroData const & macro = MacroTable::globalMacros().get(name()); - vector values(nargs()); - for (size_t i = 0; i != nargs(); ++i) - values[i].insert(0, MathAtom(new MathMacroArgumentValue(&cells_[i], name()))); - macro.expand(values, expanded_); - - MacroTable::globalMacros().get(name()).lock(); + macro.lock(); expanded_.metrics(mi, dim); - MacroTable::globalMacros().get(name()).unlock(); + macro.unlock(); + editing_ = false; } } metricsMarkers2(dim); @@ -160,10 +161,15 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const drawStrRed(pi, x, y, "Unknown: " + name()); } else { MacroData const & macro = MacroTable::globalMacros().get(name()); + + // warm up cache + for (size_t i = 0; i < nargs(); ++i) + cell(i).setXY(*pi.base.bv, x, y); + if (macro.locked()) { // FIXME UNICODE drawStrRed(pi, x, y, "Self reference: " + name()); - } else if (editing(pi.base.bv)) { + } else if (editing_) { Font font = pi.base.font; augmentFont(font, from_ascii("lyxtex")); int h = y - dim_.ascent() + 2 + tmpl_.ascent(); @@ -184,10 +190,14 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const h += max(c.descent(), ldim.des) + 5; } } else { - MacroTable::globalMacros().get(name()).lock(); + macro.lock(); expanded_.draw(pi, x, y); - MacroTable::globalMacros().get(name()).unlock(); + macro.unlock(); } + + // edit mode changed? + if (editing_ != editing(pi.base.bv) || macroBackup_ != macro) + pi.base.bv->cursor().updateFlags(Update::Force); } drawMarkers2(pi, x, y); } @@ -274,7 +284,15 @@ void MathMacro::octave(OctaveStream & os) const void MathMacro::updateExpansion() const { - //expanded_.substitute(*this); + MacroData const & macro = MacroTable::globalMacros().get(name()); + + // create MathMacroArgumentValue object pointing to the cells of the macro + vector values(nargs()); + for (size_t i = 0; i != nargs(); ++i) + values[i].insert(0, MathAtom(new MathMacroArgumentValue(*this, i))); + macro.expand(values, expanded_); + asArray(macro.def(), tmpl_); + macroBackup_ = macro; } diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h index 5d1428c7c0..6193ec62fe 100644 --- a/src/mathed/MathMacro.h +++ b/src/mathed/MathMacro.h @@ -72,8 +72,6 @@ private: virtual std::auto_ptr doClone() const; /// void updateExpansion() const; - /// - void expand() const; /// name of macro docstring name_; @@ -81,6 +79,10 @@ private: mutable MathData tmpl_; /// the macro substituted with our args mutable MathData expanded_; + /// + mutable MacroData macroBackup_; + /// + mutable bool editing_; };