]> git.lyx.org Git - features.git/commitdiff
RefChanger
authorGuillaume Munch <gm@lyx.org>
Mon, 23 May 2016 21:30:23 +0000 (22:30 +0100)
committerGuillaume Munch <gm@lyx.org>
Mon, 13 Jun 2016 07:46:15 +0000 (08:46 +0100)
RefChanger temporarily assigns a value to a non-const reference of any
kind. RefChanger provides a flexible and uniform generalisation of the various
scope guards previously derived from the old Changer class in MetricsInfo.h.

As before, a temporary assignment lasts as long as the Changer object lives. But
the new Changer is movable. In particular, contorsions are no longer needed to
change a private field. Special code can be moved into the appropriate classes,
and it is no longer necessary to create a new class for each specific use.

Syntax change:

   FontSetChanger dummy(mi.base, value);
-> Changer dummy = mi.base.changeFontSet(value);

New function for generating arbitrary Changers:

  Changer dummy = make_change(ref, val, condition);

Bugfix:

* Fix the display of \displaystyle{\substack{\frac{xyz}{}}} (missing style
  change).

34 files changed:
src/FontInfo.cpp
src/FontInfo.h
src/MetricsInfo.cpp
src/MetricsInfo.h
src/insets/InsetScript.cpp
src/mathed/InsetMathAMSArray.cpp
src/mathed/InsetMathArray.cpp
src/mathed/InsetMathBoldSymbol.cpp
src/mathed/InsetMathBox.cpp
src/mathed/InsetMathChar.cpp
src/mathed/InsetMathDecoration.cpp
src/mathed/InsetMathEnsureMath.cpp
src/mathed/InsetMathFont.cpp
src/mathed/InsetMathFontOld.cpp
src/mathed/InsetMathFrac.cpp
src/mathed/InsetMathHull.cpp
src/mathed/InsetMathOverset.cpp
src/mathed/InsetMathPar.cpp
src/mathed/InsetMathScript.cpp
src/mathed/InsetMathSideset.cpp
src/mathed/InsetMathSize.cpp
src/mathed/InsetMathSpecialChar.cpp
src/mathed/InsetMathStackrel.cpp
src/mathed/InsetMathSubstack.cpp
src/mathed/InsetMathSymbol.cpp
src/mathed/InsetMathTabular.cpp
src/mathed/InsetMathUnderset.cpp
src/mathed/InsetMathXArrow.cpp
src/mathed/InsetMathXYArrow.cpp
src/mathed/MathMacro.cpp
src/mathed/MathMacroTemplate.cpp
src/support/Changer.h [new file with mode: 0644]
src/support/Makefile.am
src/support/RefChanger.h [new file with mode: 0644]

index e611288ff4422ef58d6b370b13162de02fd12bea..9edf97e52e9e7ee56e63d9e7da738a502bec1595 100644 (file)
@@ -21,6 +21,7 @@
 #include "support/debug.h"
 #include "support/docstring.h"
 #include "support/lstrings.h"
+#include "support/RefChanger.h"
 
 #include <ostream>
 #include <sstream>
@@ -245,6 +246,26 @@ FontInfo & FontInfo::realize(FontInfo const & tmplt)
 }
 
 
+Changer FontInfo::changeColor(ColorCode const color, bool cond)
+{
+       return make_change(color_, color, cond);
+}
+
+
+Changer FontInfo::changeShape(FontShape const shape, bool cond)
+{
+       return make_change(shape_, shape, cond);
+}
+
+
+Changer FontInfo::change(FontInfo font, bool realiz, bool cond)
+{
+       if (realiz)
+               font.realize(*this);
+       return make_change(*this, font, cond);
+}
+
+
 /// Updates a misc setting according to request
 static FontState setMisc(FontState newfont,
        FontState org)
index c31c7fac779f7173b512d7672d23924277332fee..370610c84e71c1395a37770a509e923d14d6f0c1 100644 (file)
 #include "Color.h"
 #include "ColorCode.h"
 #include "FontEnums.h"
+
+#include "support/Changer.h"
 #include "support/strfwd.h"
 
+
 namespace lyx {
 
 class Lexer;
@@ -136,6 +139,14 @@ public:
                }
        }
 
+       /// Temporarily replace the color with \param color.
+       Changer changeColor(ColorCode const color, bool cond = true);
+       /// Temporarily replace the shape with \param shape.
+       Changer changeShape(FontShape const shape, bool cond = true);
+       /// Temporarily replace the FontInfo with \param font, and optionally
+       /// \param realize the \param font against the current FontInfo.
+       Changer change(FontInfo font, bool realize = false, bool cond = true);
+
 private:
        friend bool operator==(FontInfo const & lhs, FontInfo const & rhs);
 
index 2b954d3ed96d12926f78963c9f84cfb74587c6aa..3808da6a2457f6fce1fd774b67c86ab8130e028d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "support/docstring.h"
 #include "support/lassert.h"
+#include "support/RefChanger.h"
 
 using namespace std;
 
@@ -46,6 +47,33 @@ MetricsBase::MetricsBase(BufferView * b, FontInfo const & f, int w)
 {}
 
 
+Changer MetricsBase::changeFontSet(docstring const & name, bool cond)
+{
+       RefChanger<MetricsBase> rc = make_save(*this);
+       if (!cond)
+               rc->keep();
+       else {
+               ColorCode oldcolor = font.color();
+               docstring const oldname = from_ascii(fontname);
+               fontname = to_utf8(name);
+               font = sane_font;
+               augmentFont(font, name);
+               font.setSize(rc->old.font.size());
+               if (name != "lyxtex"
+                   && ((isTextFont(oldname) && oldcolor != Color_foreground)
+                       || (isMathFont(oldname) && oldcolor != Color_math)))
+                       font.setColor(oldcolor);
+       }
+       return move(rc);
+}
+
+
+Changer MetricsBase::changeFontSet(char const * name, bool cond)
+{
+       return changeFontSet(from_ascii(name), cond);
+}
+
+
 /////////////////////////////////////////////////////////////////////////
 //
 // MetricsInfo
@@ -117,210 +145,58 @@ Color PainterInfo::textColor(Color const & color) const
 }
 
 
-/////////////////////////////////////////////////////////////////////////
-//
-// ScriptChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-Styles smallerScriptStyle(Styles st)
+Changer MetricsBase::changeScript(bool cond)
 {
-       switch (st) {
-               case LM_ST_DISPLAY:
-               case LM_ST_TEXT:
-                       return LM_ST_SCRIPT;
-               case LM_ST_SCRIPT:
-               case LM_ST_SCRIPTSCRIPT:
-               default: // shut up compiler
-                       return LM_ST_SCRIPTSCRIPT;
+       switch (style) {
+       case LM_ST_DISPLAY:
+       case LM_ST_TEXT:
+               return changeStyle(LM_ST_SCRIPT, cond);
+       case LM_ST_SCRIPT:
+       case LM_ST_SCRIPTSCRIPT:
+               return changeStyle(LM_ST_SCRIPTSCRIPT, cond);
        }
+       //remove Warning
+       LASSERT(false, return Changer());
 }
 
 
-ScriptChanger::ScriptChanger(MetricsBase & mb)
-       : StyleChanger(mb, smallerScriptStyle(mb.style))
-{}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// FracChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-Styles smallerFracStyle(Styles st)
+Changer MetricsBase::changeFrac(bool cond)
 {
-       switch (st) {
-               case LM_ST_DISPLAY:
-                       return LM_ST_TEXT;
-               case LM_ST_TEXT:
-                       return LM_ST_SCRIPT;
-               case LM_ST_SCRIPT:
-               case LM_ST_SCRIPTSCRIPT:
-               default: // shut up compiler
-                       return LM_ST_SCRIPTSCRIPT;
+       switch (style) {
+       case LM_ST_DISPLAY:
+               return changeStyle(LM_ST_TEXT, cond);
+       case LM_ST_TEXT:
+               return changeStyle(LM_ST_SCRIPT, cond);
+       case LM_ST_SCRIPT:
+       case LM_ST_SCRIPTSCRIPT:
+               return changeStyle(LM_ST_SCRIPTSCRIPT, cond);
        }
+       //remove Warning
+       return Changer();
 }
 
 
-FracChanger::FracChanger(MetricsBase & mb)
-       : StyleChanger(mb, smallerFracStyle(mb.style))
-{}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// ArrayChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-ArrayChanger::ArrayChanger(MetricsBase & mb)
-       : StyleChanger(mb, mb.style == LM_ST_DISPLAY ? LM_ST_TEXT : mb.style)
-{}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// ShapeChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-ShapeChanger::ShapeChanger(FontInfo & font, FontShape shape)
-       : Changer<FontInfo, FontShape>(font, font.shape())
-{
-       orig_.setShape(shape);
-}
-
-
-ShapeChanger::~ShapeChanger()
-{
-       orig_.setShape(save_);
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// StyleChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-StyleChanger::StyleChanger(MetricsBase & mb, Styles style)
-       : Changer<MetricsBase>(mb)
+Changer MetricsBase::changeStyle(Styles new_style, bool cond)
 {
        static const int diff[4][4] =
                { { 0, 0, -3, -5 },
                  { 0, 0, -3, -5 },
                  { 3, 3,  0, -2 },
                  { 5, 5,  2,  0 } };
-       int t = diff[mb.style][style];
-       if (t > 0)
-               while (t--)
-                       mb.font.incSize();
-       else
-               while (t++)
-                       mb.font.decSize();
-       mb.style = style;
-}
-
-
-StyleChanger::~StyleChanger()
-{
-       orig_ = save_;
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// FontSetChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-FontSetChanger::FontSetChanger(MetricsBase & mb, char const * name,
-                               bool really_change_font)
-       : Changer<MetricsBase>(mb), change_(really_change_font)
-{
-       if (change_) {
-               FontSize oldsize = save_.font.size();
-               ColorCode oldcolor = save_.font.color();
-               docstring const oldname = from_ascii(save_.fontname);
-               mb.fontname = name;
-               mb.font = sane_font;
-               augmentFont(mb.font, from_ascii(name));
-               mb.font.setSize(oldsize);
-               if (string(name) != "lyxtex"
-                   && ((isTextFont(oldname) && oldcolor != Color_foreground)
-                       || (isMathFont(oldname) && oldcolor != Color_math)))
-                       mb.font.setColor(oldcolor);
-       }
-}
-
-
-FontSetChanger::FontSetChanger(MetricsBase & mb, docstring const & name,
-                               bool really_change_font)
-       : Changer<MetricsBase>(mb), change_(really_change_font)
-{
-       if (change_) {
-               FontSize oldsize = save_.font.size();
-               ColorCode oldcolor = save_.font.color();
-               docstring const oldname = from_ascii(save_.fontname);
-               mb.fontname = to_utf8(name);
-               mb.font = sane_font;
-               augmentFont(mb.font, name);
-               mb.font.setSize(oldsize);
-               if (name != "lyxtex"
-                   && ((isTextFont(oldname) && oldcolor != Color_foreground)
-                       || (isMathFont(oldname) && oldcolor != Color_math)))
-                       mb.font.setColor(oldcolor);
-       }
-}
-
-
-FontSetChanger::~FontSetChanger()
-{
-       if (change_)
-               orig_ = save_;
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// WidthChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-WidthChanger::WidthChanger(MetricsBase & mb, int w)
-       : Changer<MetricsBase>(mb)
-{
-       mb.textwidth = w;
-}
-
-
-WidthChanger::~WidthChanger()
-{
-       orig_ = save_;
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-//
-// ColorChanger
-//
-/////////////////////////////////////////////////////////////////////////
-
-ColorChanger::ColorChanger(FontInfo & font, ColorCode color,
-                          bool really_change_color)
-       : Changer<FontInfo, ColorCode>(font, font.color()), change_(really_change_color)
-{
-       if (change_) {
-               font.setColor(color);
+       int t = diff[style][new_style];
+       RefChanger<MetricsBase> rc = make_save(*this);
+       if (!cond)
+               rc->keep();
+       else {
+               if (t > 0)
+                       while (t--)
+                               font.incSize();
+               else
+                       while (t++)
+                               font.decSize();
+               style = new_style;
        }
-}
-
-
-ColorChanger::~ColorChanger()
-{
-       if (change_)
-               orig_.setColor(save_);
+       return move(rc);
 }
 
 
index 195d705459c6860a338fc41d553d1b1e96f935d0..3f18724cb72313e23df648116519c42f1317f69d 100644 (file)
@@ -18,6 +18,8 @@
 #include "FontInfo.h"
 
 #include "support/strfwd.h"
+#include "support/Changer.h"
+
 
 #include <string>
 
@@ -31,6 +33,7 @@ class MacroContext;
 
 
 /// Standard Sizes (mode styles)
+/// note: These values are hard-coded in changeStyle
 enum Styles {
        ///
        LM_ST_DISPLAY = 0,
@@ -63,6 +66,16 @@ public:
        std::string fontname;
        /// This is the width available in pixels
        int textwidth;
+
+       /// Temporarily change a full font.
+       Changer changeFontSet(docstring const & font, bool cond = true);
+       Changer changeFontSet(char const * font, bool cond = true);
+       /// Temporarily change the font size and the math style.
+       Changer changeStyle(Styles style, bool cond = true);
+       // Temporarily change to the style suitable for use in fractions
+       Changer changeFrac(bool cond = true);
+       // Temporarily change the style to (script)script style
+       Changer changeScript(bool cond = true);
 };
 
 
@@ -127,121 +140,6 @@ public:
 
 class TextMetricsInfo {};
 
-
-/// Generic base for temporarily changing things. The derived class is
-/// responsible for restoring the original state when the Changer is
-/// destructed.
-template <class Struct, class Temp = Struct>
-class Changer {
-protected:
-       ///
-       Changer(Struct & orig, Temp const & save) : orig_(orig), save_(save) {}
-       ///
-       Changer(Struct & orig) : orig_(orig), save_(orig) {}
-       ///
-       Struct & orig_;
-       ///
-       Temp save_;
-};
-
-
-
-// temporarily change some aspect of a font
-class FontChanger : public Changer<FontInfo> {
-public:
-       ///
-       FontChanger(FontInfo & orig, docstring const & font);
-       FontChanger(MetricsBase & mb, char const * const font);
-       ///
-       ~FontChanger();
-};
-
-
-// temporarily change a full font
-class FontSetChanger : public Changer<MetricsBase> {
-public:
-       ///
-       FontSetChanger(MetricsBase & mb, docstring const & font,
-                       bool really_change_font = true);
-       FontSetChanger(MetricsBase & mb, char const * const font,
-                       bool really_change_font = true);
-       ///
-       ~FontSetChanger();
-private:
-       ///
-       bool change_;
-};
-
-
-// temporarily change the style
-class StyleChanger : public Changer<MetricsBase> {
-public:
-       ///
-       StyleChanger(MetricsBase & mb, Styles style);
-       ///
-       ~StyleChanger();
-};
-
-
-// temporarily change the style to script style
-class ScriptChanger : public StyleChanger {
-public:
-       ///
-       ScriptChanger(MetricsBase & mb);
-};
-
-
-// temporarily change the style suitable for use in fractions
-class FracChanger : public StyleChanger {
-public:
-       ///
-       FracChanger(MetricsBase & mb);
-};
-
-
-// temporarily change the style suitable for use in tabulars and arrays
-class ArrayChanger : public StyleChanger {
-public:
-       ///
-       ArrayChanger(MetricsBase & mb);
-};
-
-
-
-// temporarily change the shape of a font
-class ShapeChanger : public Changer<FontInfo, FontShape> {
-public:
-       ///
-       ShapeChanger(FontInfo & font, FontShape shape);
-       ///
-       ~ShapeChanger();
-};
-
-
-// temporarily change the available text width
-class WidthChanger : public Changer<MetricsBase>
-{
-public:
-       ///
-       WidthChanger(MetricsBase & mb, int width);
-       ///
-       ~WidthChanger();
-};
-
-
-// temporarily change the used color
-class ColorChanger : public Changer<FontInfo, ColorCode> {
-public:
-       ///
-       ColorChanger(FontInfo & font, ColorCode color,
-                    bool really_change_color = true);
-       ///
-       ~ColorChanger();
-private:
-       ///
-       bool change_;
-};
-
 } // namespace lyx
 
 #endif
index bee4c541cf95cca6e1522ba496dc1a2df4efda79..fec226fe3a52b6c2f6ce53becde410bf82d68b0b 100644 (file)
@@ -160,7 +160,7 @@ Inset::DisplayType InsetScript::display() const
 void InsetScript::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        int const shift = params_.shift(mi.base.font);
-       ScriptChanger dummy(mi.base);
+       Changer dummy = mi.base.changeScript();
        InsetText::metrics(mi, dim);
        dim.asc -= shift;
        dim.des += shift;
@@ -170,7 +170,7 @@ void InsetScript::metrics(MetricsInfo & mi, Dimension & dim) const
 void InsetScript::draw(PainterInfo & pi, int x, int y) const
 {
        int const shift = params_.shift(pi.base.font);
-       ScriptChanger dummy(pi.base);
+       Changer dummy = pi.base.changeScript();
        InsetText::draw(pi, x, y + shift);
 }
 
index 13d7a9425e5244a77a2cb226d1b060fcb66fe7f0..426362dfd7ee6d2d4718cd96f277400b7f51928a 100644 (file)
@@ -20,8 +20,8 @@
 
 #include "FuncRequest.h"
 #include "FuncStatus.h"
-#include "support/gettext.h"
 
+#include "support/gettext.h"
 #include "support/lstrings.h"
 
 #include <sstream>
@@ -85,7 +85,8 @@ char const * InsetMathAMSArray::name_right() const
 
 void InsetMathAMSArray::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       ArrayChanger dummy(mi.base);
+       Changer dummy =
+               mi.base.changeStyle(LM_ST_TEXT, mi.base.style == LM_ST_DISPLAY);
        InsetMathGrid::metrics(mi, dim);
        dim.wid += 14;
 }
@@ -95,10 +96,11 @@ void InsetMathAMSArray::draw(PainterInfo & pi, int x, int y) const
 {
        Dimension const dim = dimension(*pi.base.bv);
        int const yy = y - dim.ascent();
-       // Drawing the deco after an ArrayChanger does not work
+       // Drawing the deco after changeStyle does not work
        mathed_draw_deco(pi, x + 1, yy, 5, dim.height(), from_ascii(name_left()));
        mathed_draw_deco(pi, x + dim.width() - 8, yy, 5, dim.height(), from_ascii(name_right()));
-       ArrayChanger dummy(pi.base);
+       Changer dummy =
+               pi.base.changeStyle(LM_ST_TEXT, pi.base.style == LM_ST_DISPLAY);
        InsetMathGrid::drawWithMargin(pi, x, y, 6, 8);
 }
 
index d5f9164273f93263ec21528b2b4b406bf0468c85..22f8471bfe2fda2bf9289d3072d29b7fa605473a 100644 (file)
@@ -74,7 +74,8 @@ Inset * InsetMathArray::clone() const
 
 void InsetMathArray::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       ArrayChanger dummy(mi.base);
+       Changer dummy =
+               mi.base.changeStyle(LM_ST_TEXT, mi.base.style == LM_ST_DISPLAY);
        InsetMathGrid::metrics(mi, dim);
        dim.wid += 6;
 }
@@ -91,7 +92,8 @@ Dimension const InsetMathArray::dimension(BufferView const & bv) const
 void InsetMathArray::draw(PainterInfo & pi, int x, int y) const
 {
        setPosCache(pi, x, y);
-       ArrayChanger dummy(pi.base);
+       Changer dummy =
+               pi.base.changeStyle(LM_ST_TEXT, pi.base.style == LM_ST_DISPLAY);
        InsetMathGrid::drawWithMargin(pi, x, y, 4, 2);
 }
 
index 465a7bf77a1469fec36aa611689dcb400fbbdfe9..215bd5ff30367739f4cfa9bb5d0635005f685c99 100644 (file)
@@ -49,7 +49,7 @@ docstring InsetMathBoldSymbol::name() const
 
 void InsetMathBoldSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       //FontSetChanger dummy(mi.base, "mathbf");
+       //Changer dummy = mi.base.changeFontSet("mathbf");
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
        ++dim.wid;  // for 'double stroke'
@@ -58,7 +58,7 @@ void InsetMathBoldSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathBoldSymbol::draw(PainterInfo & pi, int x, int y) const
 {
-       //FontSetChanger dummy(pi.base, "mathbf");
+       //Changer dummy = pi.base.changeFontSet("mathbf");
        cell(0).draw(pi, x + 1, y);
        cell(0).draw(pi, x + 2, y);
        drawMarkers(pi, x, y);
index aee9381cd79ff1bcd852e3041f3d0aa6a7514294..e9e483c29f655fae79b27e362d76a6f2b2dbfd36 100644 (file)
@@ -81,7 +81,7 @@ void InsetMathBox::htmlize(HtmlStream & ms) const
 
 void InsetMathBox::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy(mi.base, "textnormal");
+       Changer dummy = mi.base.changeFontSet("textnormal");
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
 }
@@ -89,7 +89,7 @@ void InsetMathBox::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathBox::draw(PainterInfo & pi, int x, int y) const
 {
-       FontSetChanger dummy(pi.base, "textnormal");
+       Changer dummy = pi.base.changeFontSet("textnormal");
        cell(0).draw(pi, x, y);
        drawMarkers(pi, x, y);
 }
@@ -133,7 +133,7 @@ InsetMathFBox::InsetMathFBox(Buffer * buf)
 
 void InsetMathFBox::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy(mi.base, "textnormal");
+       Changer dummy = mi.base.changeFontSet("textnormal");
        cell(0).metrics(mi, dim);
        metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
 }
@@ -144,7 +144,7 @@ void InsetMathFBox::draw(PainterInfo & pi, int x, int y) const
        Dimension const dim = dimension(*pi.base.bv);
        pi.pain.rectangle(x + 1, y - dim.ascent() + 1,
                dim.width() - 2, dim.height() - 2, Color_foreground);
-       FontSetChanger dummy(pi.base, "textnormal");
+       Changer dummy = pi.base.changeFontSet("textnormal");
        cell(0).draw(pi, x + 3, y);
        setPosCache(pi, x, y);
 }
@@ -219,7 +219,7 @@ InsetMathMakebox::InsetMathMakebox(Buffer * buf, bool framebox)
 
 void InsetMathMakebox::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy(mi.base, "textnormal");
+       Changer dummy = mi.base.changeFontSet("textnormal");
        
        Dimension wdim;
        static docstring bracket = from_ascii("[");
@@ -254,7 +254,7 @@ void InsetMathMakebox::draw(PainterInfo & pi, int x, int y) const
 {
        drawMarkers(pi, x, y);
        
-       FontSetChanger dummy(pi.base, "textnormal");
+       Changer dummy = pi.base.changeFontSet("textnormal");
        BufferView const & bv = *pi.base.bv;
        int w = mathed_char_width(pi.base.font, '[');
        
index 2879ac91fccf9a442f70ca07adc63f4052370e4d..813067e08a55bff863821a60885ed335032bd291 100644 (file)
@@ -56,13 +56,13 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
 {
 #if 1
        if (char_ == '=' && has_math_fonts) {
-               FontSetChanger dummy(mi.base, "cmr");
+               Changer dummy = mi.base.changeFontSet("cmr");
                dim = theFontMetrics(mi.base.font).dimension(char_);
        } else if ((char_ == '>' || char_ == '<') && has_math_fonts) {
-               FontSetChanger dummy(mi.base, "cmm");
+               Changer dummy = mi.base.changeFontSet("cmm");
                dim = theFontMetrics(mi.base.font).dimension(char_);
        } else if (!slanted(char_) && mi.base.fontname == "mathnormal") {
-               ShapeChanger dummy(mi.base.font, UP_SHAPE);
+               Changer dummy = mi.base.font.changeShape(UP_SHAPE);
                dim = theFontMetrics(mi.base.font).dimension(char_);
        } else {
                frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
@@ -99,13 +99,13 @@ void InsetMathChar::draw(PainterInfo & pi, int x, int y) const
                x += mathed_thinmuskip(pi.base.font) / 2;
 #if 1
        if (char_ == '=' && has_math_fonts) {
-               FontSetChanger dummy(pi.base, "cmr");
+               Changer dummy = pi.base.changeFontSet("cmr");
                pi.draw(x, y, char_);
        } else if ((char_ == '>' || char_ == '<') && has_math_fonts) {
-               FontSetChanger dummy(pi.base, "cmm");
+               Changer dummy = pi.base.changeFontSet("cmm");
                pi.draw(x, y, char_);
        } else if (!slanted(char_) && pi.base.fontname == "mathnormal") {
-               ShapeChanger dummy(pi.base.font, UP_SHAPE);
+               Changer dummy = pi.base.font.changeShape(UP_SHAPE);
                pi.draw(x, y, char_);
        } else {
                pi.draw(x, y, char_);
index 9e4a338eee30e174d9bb74c4ae7fae60a1bc8c69..438d16153cd1f42d300b2cdf1968f302be26b4b3 100644 (file)
@@ -107,7 +107,7 @@ void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        bool really_change_font = currentMode() == TEXT_MODE
                                && isMathFont(from_ascii(mi.base.fontname));
-       FontSetChanger dummy(mi.base, "textnormal", really_change_font);
+       Changer dummy = mi.base.changeFontSet("textnormal", really_change_font);
 
        cell(0).metrics(mi, dim);
 
@@ -130,7 +130,7 @@ void InsetMathDecoration::draw(PainterInfo & pi, int x, int y) const
 {
        bool really_change_font = currentMode() == TEXT_MODE
                                && isMathFont(from_ascii(pi.base.fontname));
-       FontSetChanger dummy(pi.base, "textnormal", really_change_font);
+       Changer dummy = pi.base.changeFontSet("textnormal", really_change_font);
 
        cell(0).draw(pi, x + 1, y);
        Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
index cab5e7730e053d8ca2b853cd46d5788accde2fbc..1cc9971705415c78d4bafa3424993863677f98a1 100644 (file)
@@ -37,7 +37,7 @@ Inset * InsetMathEnsureMath::clone() const
 void InsetMathEnsureMath::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        bool really_change_font = isTextFont(from_ascii(mi.base.fontname));
-       FontSetChanger dummy(mi.base, "mathnormal", really_change_font);
+       Changer dummy = mi.base.changeFontSet("mathnormal", really_change_font);
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
 }
@@ -46,7 +46,7 @@ void InsetMathEnsureMath::metrics(MetricsInfo & mi, Dimension & dim) const
 void InsetMathEnsureMath::draw(PainterInfo & pi, int x, int y) const
 {
        bool really_change_font = isTextFont(from_ascii(pi.base.fontname));
-       FontSetChanger dummy(pi.base, "mathnormal", really_change_font);
+       Changer dummy = pi.base.changeFontSet("mathnormal", really_change_font);
        cell(0).draw(pi, x, y);
        drawMarkers(pi, x, y);
 }
index 18af75d528b99de0d83f332dc509802e5cfb323f..7c15b82a29f2db0b0a1ca73df60acaaa34ce7a43 100644 (file)
@@ -58,7 +58,7 @@ bool InsetMathFont::lockedMode() const
 
 void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy(mi.base, key_->name);
+       Changer dummy = mi.base.changeFontSet(key_->name);
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
 }
@@ -66,7 +66,7 @@ void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathFont::draw(PainterInfo & pi, int x, int y) const
 {
-       FontSetChanger dummy(pi.base, key_->name);
+       Changer dummy = pi.base.changeFontSet(key_->name);
        cell(0).draw(pi, x + 1, y);
        drawMarkers(pi, x, y);
        setPosCache(pi, x, y);
index 013808d8a79b142c0389234bc5f51559c1e96a20..4c54a97c5b0e3d47db694b8ea038a4ae0e00c27e 100644 (file)
@@ -51,7 +51,7 @@ void InsetMathFontOld::metrics(MetricsInfo & mi, Dimension & dim) const
        // When \cal is used in text mode, the font is not changed
        bool really_change_font = font != "textcal";
 
-       FontSetChanger dummy(mi.base, font, really_change_font);
+       Changer dummy = mi.base.changeFontSet(font, really_change_font);
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
 }
@@ -68,7 +68,7 @@ void InsetMathFontOld::draw(PainterInfo & pi, int x, int y) const
        // When \cal is used in text mode, the font is not changed
        bool really_change_font = font != "textcal";
 
-       FontSetChanger dummy(pi.base, font, really_change_font);
+       Changer dummy = pi.base.changeFontSet(font, really_change_font);
        cell(0).draw(pi, x + 1, y);
        drawMarkers(pi, x, y);
 }
index 467735558cd2d087e35e25e5e8463a8a8dd9e931..ab876e060d86dea0e333a33cef7ca30dad91f390 100644 (file)
 #include "MetricsInfo.h"
 #include "TextPainter.h"
 
-#include "support/lassert.h"
 #include "frontends/Painter.h"
 
+#include "support/lassert.h"
+
 using namespace std;
 
+
 namespace lyx {
 
 /////////////////////////////////////////////////////////////////////
@@ -125,24 +127,26 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        Dimension dim0, dim1, dim2;
 
+       // This could be simplified, including avoiding useless recalculation of
+       // cell metrics
        if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
                if (nargs() == 1) {
-                       ShapeChanger dummy2(mi.base.font, UP_SHAPE);
+                       Changer dummy = mi.base.font.changeShape(UP_SHAPE);
                        cell(0).metrics(mi, dim0);
                        dim.wid = dim0.width()+ 3;
                        dim.asc = dim0.asc;
                        dim.des = dim0.des;
                } else if (nargs() == 2) {
                        cell(0).metrics(mi, dim0);
-                       ShapeChanger dummy2(mi.base.font, UP_SHAPE);
+                       Changer dummy = mi.base.font.changeShape(UP_SHAPE);
                        cell(1).metrics(mi, dim1);
                        dim.wid = dim0.width() + dim1.wid + 5;
                        dim.asc = max(dim0.asc, dim1.asc);
                        dim.des = max(dim0.des, dim1.des);
                } else {
                        cell(2).metrics(mi, dim2);
-                       ShapeChanger dummy2(mi.base.font, UP_SHAPE);
-                       FracChanger dummy(mi.base);
+                       Changer dummy = mi.base.font.changeShape(UP_SHAPE);
+                       Changer dummy2 = mi.base.changeFrac();
                        cell(0).metrics(mi, dim0);
                        cell(1).metrics(mi, dim1);
                        dim.wid = dim0.width() + dim1.wid + dim2.wid + 10;
@@ -151,31 +155,25 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
                }
        } else {
                // general cell metrics used for \frac
-               FracChanger dummy(mi.base);
+               Changer dummy = mi.base.changeFrac();
                cell(0).metrics(mi, dim0);
                cell(1).metrics(mi, dim1);
                if (nargs() == 3)
                        cell(2).metrics(mi, dim2);
                // metrics for special fraction types
-               if (kind_ == NICEFRAC) {
-                       dim.wid = dim0.width() + dim1.wid + 5;
-                       dim.asc = dim0.height() + 5;
-                       dim.des = dim1.height() - 5;
-               } else if (kind_ == UNITFRAC) {
-                       ShapeChanger dummy2(mi.base.font, UP_SHAPE);
+               if (kind_ == NICEFRAC || kind_ == UNITFRAC) {
+                       Changer dummy2 = mi.base.font.changeShape(UP_SHAPE, kind_ == UNITFRAC);
                        dim.wid = dim0.width() + dim1.wid + 5;
                        dim.asc = dim0.height() + 5;
                        dim.des = dim1.height() - 5;
                } else {
-                       if (kind_ == CFRAC || kind_ == CFRACLEFT
-                                 || kind_ == CFRACRIGHT || kind_ == DFRAC) {
+                       if (kind_ == CFRAC || kind_ == CFRACLEFT || kind_ == CFRACRIGHT
+                           || kind_ == DFRAC || kind_ == TFRAC) {
                                // \cfrac and \dfrac are always in display size
-                               StyleChanger dummy2(mi.base, LM_ST_DISPLAY);
-                               cell(0).metrics(mi, dim0);
-                               cell(1).metrics(mi, dim1);
-                       } else if (kind_ == TFRAC) {
-                               // tfrac is in always in text size
-                               StyleChanger dummy2(mi.base, LM_ST_SCRIPT);
+                               // \tfrac is in always in text size
+                               Changer dummy2 = mi.base.changeStyle((kind_ == TFRAC)
+                                                                    ? LM_ST_SCRIPT
+                                                                    : LM_ST_DISPLAY);
                                cell(0).metrics(mi, dim0);
                                cell(1).metrics(mi, dim1);
                        }
@@ -195,16 +193,16 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
        Dimension const dim0 = cell(0).dimension(*pi.base.bv);
        if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
                if (nargs() == 1) {
-                       ShapeChanger dummy2(pi.base.font, UP_SHAPE);
+                       Changer dummy = pi.base.font.changeShape(UP_SHAPE);
                        cell(0).draw(pi, x + 1, y);
                } else if (nargs() == 2) {
                        cell(0).draw(pi, x + 1, y);
-                       ShapeChanger dummy2(pi.base.font, UP_SHAPE);
+                       Changer dummy = pi.base.font.changeShape(UP_SHAPE);
                        cell(1).draw(pi, x + dim0.width() + 5, y);
                } else {
                        cell(2).draw(pi, x + 1, y);
-                       ShapeChanger dummy2(pi.base.font, UP_SHAPE);
-                       FracChanger dummy(pi.base);
+                       Changer dummy = pi.base.font.changeShape(UP_SHAPE);
+                       Changer dummy2 = pi.base.changeFrac();
                        Dimension const dim1 = cell(1).dimension(*pi.base.bv);
                        Dimension const dim2 = cell(2).dimension(*pi.base.bv);
                        int xx = x + dim2.wid + 5;
@@ -214,7 +212,7 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
                                         y + dim1.asc / 2);
                }
        } else {
-               FracChanger dummy(pi.base);
+               Changer dummy = pi.base.changeFrac();
                Dimension const dim1 = cell(1).dimension(*pi.base.bv);
                int m = x + dim.wid / 2;
                if (kind_ == NICEFRAC) {
@@ -223,20 +221,18 @@ void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
                        cell(1).draw(pi, x + dim0.width() + 5,
                                        y + dim1.asc / 2);
                } else if (kind_ == UNITFRAC) {
-                       ShapeChanger dummy2(pi.base.font, UP_SHAPE);
+                       Changer dummy2 = pi.base.font.changeShape(UP_SHAPE);
                        cell(0).draw(pi, x + 2, y - dim0.des - 5);
                        cell(1).draw(pi, x + dim0.width() + 5, y + dim1.asc / 2);
-               } else if (kind_ == FRAC || kind_ == ATOP || kind_ == OVER) {
-                       cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
-                       cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 2 - 5);
-               } else if (kind_ == TFRAC) {
+               } else if (kind_ == FRAC || kind_ == ATOP || kind_ == OVER
+                          || kind_ == TFRAC) {
                        // tfrac is in always in text size
-                       StyleChanger dummy2(pi.base, LM_ST_SCRIPT);
+                       Changer dummy2 = pi.base.changeStyle(LM_ST_SCRIPT, kind_ == TFRAC);
                        cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
                        cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 2 - 5);
                } else {
                        // \cfrac and \dfrac are always in display size
-                       StyleChanger dummy2(pi.base, LM_ST_DISPLAY);
+                       Changer dummy2 = pi.base.changeStyle(LM_ST_DISPLAY);
                        if (kind_ == CFRAC || kind_ == DFRAC)
                                cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
                        else if (kind_ == CFRACLEFT)
@@ -552,22 +548,12 @@ int InsetMathBinom::dw(int height) const
 void InsetMathBinom::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        Dimension dim0, dim1;
-
-       // The cells must be set while the RAII objects (StyleChanger,
-       // FracChanger) do still exist and cannot be set after the if case.
-       if (kind_ == DBINOM) {
-               StyleChanger dummy(mi.base, LM_ST_DISPLAY);
-               cell(0).metrics(mi, dim0);
-               cell(1).metrics(mi, dim1);
-       } else if (kind_ == TBINOM) {
-               StyleChanger dummy(mi.base, LM_ST_SCRIPT);
-               cell(0).metrics(mi, dim0);
-               cell(1).metrics(mi, dim1);
-       } else {
-               FracChanger dummy(mi.base);
-               cell(0).metrics(mi, dim0);
-               cell(1).metrics(mi, dim1);
-       }
+       Changer dummy =
+               (kind_ == DBINOM) ? mi.base.changeStyle(LM_ST_DISPLAY) :
+               (kind_ == TBINOM) ? mi.base.changeStyle(LM_ST_SCRIPT) :
+                                   mi.base.changeFrac();
+       cell(0).metrics(mi, dim0);
+       cell(1).metrics(mi, dim1);
        dim.asc = dim0.height() + 4 + 5;
        dim.des = dim1.height() + 4 - 5;
        dim.wid = max(dim0.wid, dim1.wid) + 2 * dw(dim.height()) + 4;
@@ -587,18 +573,11 @@ void InsetMathBinom::draw(PainterInfo & pi, int x, int y) const
                kind_ == BRACK ? from_ascii("]") : from_ascii(")");
 
        int m = x + dim.width() / 2;
-       // The cells must be drawn while the RAII objects (StyleChanger,
-       // FracChanger) do still exist and cannot be drawn after the if case.
-       if (kind_ == DBINOM) {
-               StyleChanger dummy(pi.base, LM_ST_DISPLAY);
-               cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 3 - 5);
-               cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 3 - 5);
-       } else if (kind_ == TBINOM) {
-               StyleChanger dummy(pi.base, LM_ST_SCRIPT);
-               cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 3 - 5);
-               cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 3 - 5);
-       } else {
-               FracChanger dummy2(pi.base);
+       {
+               Changer dummy =
+                       (kind_ == DBINOM) ? pi.base.changeStyle(LM_ST_DISPLAY) :
+                       (kind_ == TBINOM) ? pi.base.changeStyle(LM_ST_SCRIPT) :
+                                           pi.base.changeFrac();
                cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 3 - 5);
                cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc + 3 - 5);
        }
index e253635f158f29f3e3b04b7da6e06ab9bb71f377..9cb3eefa39f88e42a03c3bced1e35f7bc83153d6 100644 (file)
@@ -487,8 +487,9 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
                return;
        }
 
-       FontSetChanger dummy1(mi.base, standardFont());
-       StyleChanger dummy2(mi.base, display() ? LM_ST_DISPLAY : LM_ST_TEXT);
+       // FIXME: Changing the same object repeatedly is inefficient.
+       Changer dummy1 = mi.base.changeFontSet(standardFont());
+       Changer dummy2 = mi.base.changeStyle(display() ? LM_ST_DISPLAY : LM_ST_TEXT);
 
        // let the cells adjust themselves
        InsetMathGrid::metrics(mi, dim);
@@ -499,7 +500,7 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
        }
 
        if (numberedType()) {
-               FontSetChanger dummy(mi.base, from_ascii("mathbf"));
+               Changer dummy = mi.base.changeFontSet(from_ascii("mathbf"));
                int l = 0;
                for (row_type row = 0; row < nrows(); ++row)
                        l = max(l, mathed_string_width(mi.base.font, nicelabel(row)));
@@ -580,9 +581,9 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
        ColorCode color = pi.selected && lyxrc.use_system_colors
                                ? Color_selectiontext : standardColor();
        bool const really_change_color = pi.base.font.color() == Color_none;
-       ColorChanger dummy0(pi.base.font, color, really_change_color);
-       FontSetChanger dummy1(pi.base, standardFont());
-       StyleChanger dummy2(pi.base, display() ? LM_ST_DISPLAY : LM_ST_TEXT);
+       Changer dummy0 = pi.base.font.changeColor(color, really_change_color);
+       Changer dummy1 = pi.base.changeFontSet(standardFont());
+       Changer dummy2 = pi.base.changeStyle(display() ? LM_ST_DISPLAY : LM_ST_TEXT);
 
        InsetMathGrid::draw(pi, x + 1, y);
 
@@ -590,7 +591,7 @@ void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
                int const xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20;
                for (row_type row = 0; row < nrows(); ++row) {
                        int const yy = y + rowinfo_[row].offset_;
-                       FontSetChanger dummy(pi.base, from_ascii("mathrm"));
+                       Changer dummy = pi.base.changeFontSet(from_ascii("mathrm"));
                        docstring const nl = nicelabel(row);
                        pi.draw(xx, yy, nl);
                }
index 1958471558cf6dea735124fd3aca59f694dd6fd6..d2044a1bec396f35576075dc11082aa779cc1225 100644 (file)
@@ -31,7 +31,7 @@ void InsetMathOverset::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        Dimension dim1;
        cell(1).metrics(mi, dim1);
-       FracChanger dummy(mi.base);
+       Changer dummy = mi.base.changeFrac();
        Dimension dim0;
        cell(0).metrics(mi, dim0);
        dim.wid = max(dim0.width(), dim1.wid) + 4;
@@ -49,7 +49,7 @@ void InsetMathOverset::draw(PainterInfo & pi, int x, int y) const
        int m  = x + dim.wid / 2;
        int yo = y - dim1.asc - dim0.des - 1;
        cell(1).draw(pi, m - dim1.wid / 2, y);
-       FracChanger dummy(pi.base);
+       Changer dummy = pi.base.changeFrac();
        cell(0).draw(pi, m - dim0.width() / 2, yo);
        drawMarkers(pi, x, y);
 }
index 0638b8eb6cfeb7a4371acab33b1e6e24564e42e2..3578399db507c72aaaeac591d354c154f8854d70 100644 (file)
@@ -28,14 +28,14 @@ InsetMathPar::InsetMathPar(Buffer * buf, MathData const & ar)
 
 void InsetMathPar::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy1(mi.base, "textnormal");
+       Changer dummy = mi.base.changeFontSet("textnormal");
        InsetMathGrid::metrics(mi, dim);
 }
 
 
 void InsetMathPar::draw(PainterInfo & pi, int x, int y) const
 {
-       FontSetChanger dummy1(pi.base, "textnormal");
+       Changer dummy = pi.base.changeFontSet("textnormal");
        InsetMathGrid::draw(pi, x, y);
 }
 
index 37f19654b789b289a9ce997cdbb28d94b24a04b7..bfe7d1847f59526d4700e3d094ecbf1a0288d42b 100644 (file)
@@ -277,7 +277,7 @@ void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
        Dimension dim1;
        Dimension dim2;
        cell(0).metrics(mi, dim0);
-       ScriptChanger dummy(mi.base);
+       Changer dummy = mi.base.changeScript();
        if (nargs() > 1)
                cell(1).metrics(mi, dim1);
        if (nargs() > 2)
@@ -332,7 +332,7 @@ void InsetMathScript::draw(PainterInfo & pi, int x, int y) const
                if (editing(&bv))
                        pi.draw(x + dxx(bv), y, char_type('.'));
        }
-       ScriptChanger dummy(pi.base);
+       Changer dummy = pi.base.changeScript();
        if (hasUp())
                up().draw(pi, x + dx1(bv), y - dy1(bv));
        if (hasDown())
index 6ed74e86c8528941fd11480e75fe899ce6628d03..3b364ec0d59d789fc07da0aa4bc031ae3cb087e7 100644 (file)
@@ -197,7 +197,7 @@ void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
                br().metrics(mi, dimbr);
                dimtr = dimbr;
        }
-       ScriptChanger dummy(mi.base);
+       Changer dummy = mi.base.changeScript();
        if (scriptl_) {
                bl().metrics(mi, dimbl);
                tl().metrics(mi, dimtl);
@@ -231,7 +231,7 @@ void InsetMathSideset::draw(PainterInfo & pi, int x, int y) const
                bl().draw(pi, x          , y);
        if (!scriptr_)
                br().draw(pi, x + dxr(bv), y);
-       ScriptChanger dummy(pi.base);
+       Changer dummy = pi.base.changeScript();
        if (scriptl_) {
                bl().draw(pi, x          , y + dyb(bv));
                tl().draw(pi, x          , y - dyt(bv));
index fc7c7bae9ff47629bbfa3fbdf746bc501c30436d..31cdb6a9e8099931f130f8da6a91141769df8c14 100644 (file)
@@ -43,7 +43,7 @@ Inset * InsetMathSize::clone() const
 
 void InsetMathSize::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       StyleChanger dummy(mi.base, style_);
+       Changer dummy = mi.base.changeStyle(style_);
        cell(0).metrics(mi, dim);
        metricsMarkers(dim);
 }
@@ -51,7 +51,7 @@ void InsetMathSize::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathSize::draw(PainterInfo & pi, int x, int y) const
 {
-       StyleChanger dummy(pi.base, style_);
+       Changer dummy = pi.base.changeStyle(style_);
        cell(0).draw(pi, x + 1, y);
        drawMarkers(pi, x, y);
 }
index 32e4c2afbf85151df69c1249b93035a7deb44321..4525ff530933a06af4de75106eb41eb3f34389dc 100644 (file)
@@ -56,7 +56,7 @@ Inset * InsetMathSpecialChar::clone() const
 void InsetMathSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        if (mi.base.fontname == "mathnormal") {
-               ShapeChanger dummy(mi.base.font, UP_SHAPE);
+               Changer dummy = mi.base.font.changeShape(UP_SHAPE);;
                dim = theFontMetrics(mi.base.font).dimension(char_);
        } else {
                frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
@@ -69,7 +69,7 @@ void InsetMathSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
 void InsetMathSpecialChar::draw(PainterInfo & pi, int x, int y) const
 {
        if (pi.base.fontname == "mathnormal") {
-               ShapeChanger dummy(pi.base.font, UP_SHAPE);
+               Changer dummy = pi.base.font.changeShape(UP_SHAPE);
                pi.draw(x, y, char_);
        } else {
                pi.draw(x, y, char_);
index d8b9e97d255c1b69d0c9740260898dbfe70cad04..d43e466964171395f0344bd8a016e6b65ed3e0da 100644 (file)
@@ -54,7 +54,7 @@ void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        Dimension dim1;
        cell(1).metrics(mi, dim1);
-       FracChanger dummy(mi.base);
+       Changer dummy = mi.base.changeFrac();
        Dimension dim0;
        cell(0).metrics(mi, dim0);
        if (nargs() > 2) {
@@ -80,7 +80,7 @@ void InsetMathStackrel::draw(PainterInfo & pi, int x, int y) const
        int m  = x + dim.width() / 2;
        int yo = y - dim1.ascent() - dim0.descent() - 1;
        cell(1).draw(pi, m - dim1.width() / 2, y);
-       FracChanger dummy(pi.base);
+       Changer dummy = pi.base.changeFrac();
        cell(0).draw(pi, m - dim0.width() / 2, yo);
        if (nargs() > 2) {
                Dimension const & dim2 = cell(2).dimension(*pi.base.bv);
index f88f4927e37c177856a489d0d174bb9b1d6a5df3..179d44c3d4c7c7b68a1b07754d61423a1db60ebf 100644 (file)
@@ -44,17 +44,14 @@ Inset * InsetMathSubstack::clone() const
 
 void InsetMathSubstack::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       if (mi.base.style == LM_ST_DISPLAY) {
-               StyleChanger dummy(mi.base, LM_ST_TEXT);
-               InsetMathGrid::metrics(mi, dim);
-       } else {
-               InsetMathGrid::metrics(mi, dim);
-       }
+       Changer dummy = mi.base.changeStyle(LM_ST_TEXT, mi.base.style == LM_ST_DISPLAY);
+       InsetMathGrid::metrics(mi, dim);
 }
 
 
 void InsetMathSubstack::draw(PainterInfo & pi, int x, int y) const
 {
+       Changer dummy = pi.base.changeStyle(LM_ST_TEXT, pi.base.style == LM_ST_DISPLAY);
        InsetMathGrid::draw(pi, x + 1, y);
 }
 
index 5a86536b52296aea9c67c793329770d60b3e6196..bdca11105b0c5d8ecd7ed7f20117d6d0f111e98d 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "support/debug.h"
 #include "support/docstream.h"
+#include "support/lyxlib.h"
 #include "support/textutils.h"
 #include "support/unique_ptr.h"
 
@@ -66,7 +67,7 @@ void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
                                         sym_->extra == "mathalpha" &&
                                         mi.base.fontname == "mathit";
        std::string const font = italic_upcase_greek ? "cmm" : sym_->inset;
-       FontSetChanger dummy(mi.base, from_ascii(font));
+       Changer dummy = mi.base.changeFontSet(from_ascii(font));
        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);
@@ -115,7 +116,7 @@ void InsetMathSymbol::draw(PainterInfo & pi, int x, int y) const
        //else
        //      x += support::iround(0.0833 * em);
 
-       FontSetChanger dummy(pi.base, from_ascii(font));
+       Changer dummy = pi.base.changeFontSet(from_ascii(font));
        pi.draw(x, y - h_, sym_->draw);
 }
 
index 2c814a38c6511ecf654ef5c693dd008dbeca9d29..40cf58d37c58920627bb4fc20e220c14d61469ec 100644 (file)
@@ -43,7 +43,7 @@ Inset * InsetMathTabular::clone() const
 
 void InsetMathTabular::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy(mi.base, "textnormal");
+       Changer dummy = mi.base.changeFontSet("textnormal");
        InsetMathGrid::metrics(mi, dim);
        dim.wid += 6;
 }
@@ -59,7 +59,7 @@ Dimension const InsetMathTabular::dimension(BufferView const & bv) const
 
 void InsetMathTabular::draw(PainterInfo & pi, int x, int y) const
 {
-       FontSetChanger dummy(pi.base, "textnormal");
+       Changer dummy = pi.base.changeFontSet("textnormal");
        InsetMathGrid::drawWithMargin(pi, x, y, 4, 2);
 }
 
index 7632b0c6af2e6e9c1d01906163314a3e8f0560af..3f4d0c49c41841e9ea97c73531fe7988d1a0cd69 100644 (file)
@@ -31,7 +31,7 @@ void InsetMathUnderset::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        Dimension dim1;
        cell(1).metrics(mi, dim1);
-       FracChanger dummy(mi.base);
+       Changer dummy = mi.base.changeFrac();
        Dimension dim0;
        cell(0).metrics(mi, dim0);
        dim.wid = max(dim0.width(), dim1.width()) + 4;
@@ -49,7 +49,7 @@ void InsetMathUnderset::draw(PainterInfo & pi, int x, int y) const
        int m  = x + dim.wid / 2;
        int yo = y + dim1.descent() + dim0.ascent() + 1;
        cell(1).draw(pi, m - dim1.width() / 2, y);
-       FracChanger dummy(pi.base);
+       Changer dummy = pi.base.changeFrac();
        cell(0).draw(pi, m - dim0.width() / 2, yo);
        drawMarkers(pi, x, y);
 }
index 8c8a4970bcd5307d22a6eea03bcf08a629e1da87..fbdac6922f4e00f1d39e2c3b365a7ad435da3e06 100644 (file)
@@ -40,7 +40,7 @@ Inset * InsetMathXArrow::clone() const
 
 void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       ScriptChanger dummy(mi.base);
+       Changer dummy = mi.base.changeScript();
        Dimension dim0;
        cell(0).metrics(mi, dim0);
        Dimension dim1;
@@ -54,7 +54,7 @@ void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathXArrow::draw(PainterInfo & pi, int x, int y) const
 {
-       ScriptChanger dummy(pi.base);
+       Changer dummy = pi.base.changeScript();
        Dimension const dim = dimension(*pi.base.bv);
        Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
        // center the cells with the decoration
index 80aeb7276b5435d9a9119ef808992280b4be32dd..19852e5de1a255d70f61100e6c16844c6f01b5b5 100644 (file)
@@ -82,8 +82,8 @@ MathData const & InsetMathXYArrow::sourceCell() const
 bool InsetMathXYArrow::metrics(MetricsInfo & mi) const
 {
        InsetMathNest::metrics(mi);
-       mi_   = mi;
-       FontSetChanger dummy(mi.base, "textrm");
+       mi_ = mi;
+       Changer dummy = mi.base.changeFontSet(mi.base, "textrm");
 #if 0
        target_ = mi.inset ? mi.inset->asXYMatrixInset() : 0;
 
@@ -105,7 +105,7 @@ bool InsetMathXYArrow::metrics(MetricsInfo & mi) const
 void InsetMathXYArrow::draw(PainterInfo & pi, int x, int y) const
 {
        metrics(mi_);
-       FontSetChanger dummy(pi.base, "textrm");
+       Changer dummy = pi.base.changeFontSet(pi.base, "textrm");
 
        if (editing()) {
 
index 9fe6e15cc46f3728ad9629dfaa7388357d5d479b..80948fd824d755f31f192d4e5df2ab459bf187c5 100644 (file)
@@ -551,10 +551,10 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
        int expy = y;
 
        if (d->displayMode_ == DISPLAY_INIT || d->displayMode_ == DISPLAY_INTERACTIVE_INIT) {
-               FontSetChanger dummy(pi.base, "lyxtex");
+               Changer dummy = pi.base.changeFontSet("lyxtex");
                pi.pain.text(x, y, from_ascii("\\") + name(), pi.base.font);
        } else if (d->displayMode_ == DISPLAY_UNFOLDED) {
-               FontSetChanger dummy(pi.base, "lyxtex");
+               Changer dummy = pi.base.changeFontSet("lyxtex");
                pi.pain.text(x, y, from_ascii("\\"), pi.base.font);
                x += mathed_string_width(pi.base.font, from_ascii("\\")) + 1;
                cell(0).draw(pi, x, y);
index d30fc36b22e6c5168637f0b5c4220e8963ba2a16..4b68626062e59225208915ce1d90545d4a766bb7 100644 (file)
@@ -542,8 +542,8 @@ void MathMacroTemplate::createLook(int args) const
 
 void MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const
 {
-       FontSetChanger dummy1(mi.base, from_ascii("mathnormal"));
-       StyleChanger dummy2(mi.base, LM_ST_TEXT);
+       Changer dummy1 = mi.base.changeFontSet(from_ascii("mathnormal"));
+       Changer dummy2 = mi.base.changeStyle(LM_ST_TEXT);
 
        // valid macro?
        MacroData const * macro = 0;
@@ -584,9 +584,10 @@ void MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void MathMacroTemplate::draw(PainterInfo & pi, int x, int y) const
 {
-       ColorChanger dummy0(pi.base.font, Color_math);
-       FontSetChanger dummy1(pi.base, from_ascii("mathnormal"));
-       StyleChanger dummy2(pi.base, LM_ST_TEXT);
+       // FIXME: Calling Changer on the same object repeatedly is inefficient.
+       Changer dummy0 = pi.base.font.changeColor(Color_math);
+       Changer dummy1 = pi.base.changeFontSet(from_ascii("mathnormal"));
+       Changer dummy2 = pi.base.changeStyle(LM_ST_TEXT);
 
        setPosCache(pi, x, y);
        Dimension const dim = dimension(*pi.base.bv);
diff --git a/src/support/Changer.h b/src/support/Changer.h
new file mode 100644 (file)
index 0000000..8f24ba5
--- /dev/null
@@ -0,0 +1,32 @@
+// -*- C++ -*-
+/**
+ * \file Changer.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Guillaume Munch
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef LYX_CHANGER_H
+#define LYX_CHANGER_H
+
+#include "support/unique_ptr.h"
+
+
+namespace lyx {
+
+// Forward declaration for support/RefChanger.h
+struct Revertible {
+       virtual ~Revertible() {}
+       virtual void revert() {}
+       virtual void keep() {}
+};
+
+using Changer = unique_ptr<Revertible>;
+
+
+}
+
+#endif //LYX_CHANGER_H
index 1487285d69058203428e13030a2715c809109149..5748019bf42a4607858a0bb9a779c91f2c52d421 100644 (file)
@@ -35,6 +35,7 @@ liblyxsupport_a_SOURCES = \
        FileMonitor.cpp \
        RandomAccessList.h \
        bind.h \
+       Change.h \
        ConsoleApplication.cpp \
        ConsoleApplication.h \
        ConsoleApplicationPrivate.h \
@@ -90,6 +91,7 @@ liblyxsupport_a_SOURCES = \
        qstring_helpers.cpp \
        qstring_helpers.h \
        regex.h \
+       RefChanger.h \
        socktools.cpp \
        socktools.h \
        strfwd.h \
diff --git a/src/support/RefChanger.h b/src/support/RefChanger.h
new file mode 100644 (file)
index 0000000..9b9d020
--- /dev/null
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+/**
+ * \file RefChanger.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Guillaume Munch
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef LYX_REFCHANGER_H
+#define LYX_REFCHANGER_H
+
+#include "support/Changer.h"
+
+
+namespace lyx {
+
+/// A RefChanger records the current value of \param ref, allowing to
+/// temporarily assign new values to it.  The original value is restored
+/// automatically when the object is destroyed, unless it is disabled.
+///
+/// RefChanger is movable, and doing so prolongs the duration of the temporary
+/// assignment. This allows classes to supply their own changer methods.
+///
+/// Naturally, be careful not to extend the life of a RefChanger beyond that of
+/// the reference it modifies. The RefChanger can be disabled by calling
+/// ->keep() or ->revert(). Once disabled, the reference is never accessed
+/// again.
+template<typename X>
+class RevertibleRef : public Revertible {
+public:
+       RevertibleRef(X & ref) : ref(ref), old(ref), enabled(true) {}
+       //
+       ~RevertibleRef() { revert(); }
+       //
+       void revert() { if (enabled) { enabled = false; ref = old; } }
+       //
+       void keep() { enabled = false; }
+       //
+       X & ref;
+       X const old;
+private:
+       bool enabled;
+};
+
+template <typename X> using RefChanger = unique_ptr<RevertibleRef<X>>;
+
+
+/// Saves the value of \param ref in a movable object
+template <typename X> RefChanger<X> make_save(X & ref)
+{
+       return make_unique<RevertibleRef<X>>(ref);
+}
+
+/// Temporarily assign value \param val to \param ref. If \param cond is false,
+/// then the assignation does not happen and the RefChanger starts disabled.
+template <typename X>
+RefChanger<X> make_change(X & ref, X const val, bool cond = true)
+{
+       auto rc = make_save(ref);
+       if (!cond)
+               rc->keep();
+       else
+               ref = val;
+       return rc;
+}
+
+
+}
+
+
+#endif //LYX_REFCHANGER_H