diff --git a/src/FontInfo.cpp b/src/FontInfo.cpp index e611288ff4..9edf97e52e 100644 --- a/src/FontInfo.cpp +++ b/src/FontInfo.cpp @@ -21,6 +21,7 @@ #include "support/debug.h" #include "support/docstring.h" #include "support/lstrings.h" +#include "support/RefChanger.h" #include #include @@ -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) diff --git a/src/FontInfo.h b/src/FontInfo.h index c31c7fac77..370610c84e 100644 --- a/src/FontInfo.h +++ b/src/FontInfo.h @@ -18,8 +18,11 @@ #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); diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp index 2b954d3ed9..3808da6a24 100644 --- a/src/MetricsInfo.cpp +++ b/src/MetricsInfo.cpp @@ -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 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(font, font.shape()) -{ - orig_.setShape(shape); -} - - -ShapeChanger::~ShapeChanger() -{ - orig_.setShape(save_); -} - - -///////////////////////////////////////////////////////////////////////// -// -// StyleChanger -// -///////////////////////////////////////////////////////////////////////// - -StyleChanger::StyleChanger(MetricsBase & mb, Styles style) - : Changer(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(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); + int t = diff[style][new_style]; + RefChanger rc = make_save(*this); + if (!cond) + rc->keep(); + else { + if (t > 0) + while (t--) + font.incSize(); + else + while (t++) + font.decSize(); + style = new_style; } -} - - -FontSetChanger::FontSetChanger(MetricsBase & mb, docstring const & name, - bool really_change_font) - : Changer(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(mb) -{ - mb.textwidth = w; -} - - -WidthChanger::~WidthChanger() -{ - orig_ = save_; -} - - -///////////////////////////////////////////////////////////////////////// -// -// ColorChanger -// -///////////////////////////////////////////////////////////////////////// - -ColorChanger::ColorChanger(FontInfo & font, ColorCode color, - bool really_change_color) - : Changer(font, font.color()), change_(really_change_color) -{ - if (change_) { - font.setColor(color); - } -} - - -ColorChanger::~ColorChanger() -{ - if (change_) - orig_.setColor(save_); + return move(rc); } diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h index 195d705459..3f18724cb7 100644 --- a/src/MetricsInfo.h +++ b/src/MetricsInfo.h @@ -18,6 +18,8 @@ #include "FontInfo.h" #include "support/strfwd.h" +#include "support/Changer.h" + #include @@ -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 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 { -public: - /// - FontChanger(FontInfo & orig, docstring const & font); - FontChanger(MetricsBase & mb, char const * const font); - /// - ~FontChanger(); -}; - - -// temporarily change a full font -class FontSetChanger : public Changer { -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 { -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 { -public: - /// - ShapeChanger(FontInfo & font, FontShape shape); - /// - ~ShapeChanger(); -}; - - -// temporarily change the available text width -class WidthChanger : public Changer -{ -public: - /// - WidthChanger(MetricsBase & mb, int width); - /// - ~WidthChanger(); -}; - - -// temporarily change the used color -class ColorChanger : public Changer { -public: - /// - ColorChanger(FontInfo & font, ColorCode color, - bool really_change_color = true); - /// - ~ColorChanger(); -private: - /// - bool change_; -}; - } // namespace lyx #endif diff --git a/src/insets/InsetScript.cpp b/src/insets/InsetScript.cpp index bee4c541cf..fec226fe3a 100644 --- a/src/insets/InsetScript.cpp +++ b/src/insets/InsetScript.cpp @@ -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); } diff --git a/src/mathed/InsetMathAMSArray.cpp b/src/mathed/InsetMathAMSArray.cpp index 13d7a9425e..426362dfd7 100644 --- a/src/mathed/InsetMathAMSArray.cpp +++ b/src/mathed/InsetMathAMSArray.cpp @@ -20,8 +20,8 @@ #include "FuncRequest.h" #include "FuncStatus.h" -#include "support/gettext.h" +#include "support/gettext.h" #include "support/lstrings.h" #include @@ -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); } diff --git a/src/mathed/InsetMathArray.cpp b/src/mathed/InsetMathArray.cpp index d5f9164273..22f8471bfe 100644 --- a/src/mathed/InsetMathArray.cpp +++ b/src/mathed/InsetMathArray.cpp @@ -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); } diff --git a/src/mathed/InsetMathBoldSymbol.cpp b/src/mathed/InsetMathBoldSymbol.cpp index 465a7bf77a..215bd5ff30 100644 --- a/src/mathed/InsetMathBoldSymbol.cpp +++ b/src/mathed/InsetMathBoldSymbol.cpp @@ -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); diff --git a/src/mathed/InsetMathBox.cpp b/src/mathed/InsetMathBox.cpp index aee9381cd7..e9e483c29f 100644 --- a/src/mathed/InsetMathBox.cpp +++ b/src/mathed/InsetMathBox.cpp @@ -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, '['); diff --git a/src/mathed/InsetMathChar.cpp b/src/mathed/InsetMathChar.cpp index 2879ac91fc..813067e08a 100644 --- a/src/mathed/InsetMathChar.cpp +++ b/src/mathed/InsetMathChar.cpp @@ -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_); diff --git a/src/mathed/InsetMathDecoration.cpp b/src/mathed/InsetMathDecoration.cpp index 9e4a338eee..438d16153c 100644 --- a/src/mathed/InsetMathDecoration.cpp +++ b/src/mathed/InsetMathDecoration.cpp @@ -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); diff --git a/src/mathed/InsetMathEnsureMath.cpp b/src/mathed/InsetMathEnsureMath.cpp index cab5e7730e..1cc9971705 100644 --- a/src/mathed/InsetMathEnsureMath.cpp +++ b/src/mathed/InsetMathEnsureMath.cpp @@ -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); } diff --git a/src/mathed/InsetMathFont.cpp b/src/mathed/InsetMathFont.cpp index 18af75d528..7c15b82a29 100644 --- a/src/mathed/InsetMathFont.cpp +++ b/src/mathed/InsetMathFont.cpp @@ -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); diff --git a/src/mathed/InsetMathFontOld.cpp b/src/mathed/InsetMathFontOld.cpp index 013808d8a7..4c54a97c5b 100644 --- a/src/mathed/InsetMathFontOld.cpp +++ b/src/mathed/InsetMathFontOld.cpp @@ -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); } diff --git a/src/mathed/InsetMathFrac.cpp b/src/mathed/InsetMathFrac.cpp index 467735558c..ab876e060d 100644 --- a/src/mathed/InsetMathFrac.cpp +++ b/src/mathed/InsetMathFrac.cpp @@ -22,11 +22,13 @@ #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); } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index e253635f15..9cb3eefa39 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -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); } diff --git a/src/mathed/InsetMathOverset.cpp b/src/mathed/InsetMathOverset.cpp index 1958471558..d2044a1bec 100644 --- a/src/mathed/InsetMathOverset.cpp +++ b/src/mathed/InsetMathOverset.cpp @@ -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); } diff --git a/src/mathed/InsetMathPar.cpp b/src/mathed/InsetMathPar.cpp index 0638b8eb6c..3578399db5 100644 --- a/src/mathed/InsetMathPar.cpp +++ b/src/mathed/InsetMathPar.cpp @@ -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); } diff --git a/src/mathed/InsetMathScript.cpp b/src/mathed/InsetMathScript.cpp index 37f19654b7..bfe7d1847f 100644 --- a/src/mathed/InsetMathScript.cpp +++ b/src/mathed/InsetMathScript.cpp @@ -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()) diff --git a/src/mathed/InsetMathSideset.cpp b/src/mathed/InsetMathSideset.cpp index 6ed74e86c8..3b364ec0d5 100644 --- a/src/mathed/InsetMathSideset.cpp +++ b/src/mathed/InsetMathSideset.cpp @@ -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)); diff --git a/src/mathed/InsetMathSize.cpp b/src/mathed/InsetMathSize.cpp index fc7c7bae9f..31cdb6a9e8 100644 --- a/src/mathed/InsetMathSize.cpp +++ b/src/mathed/InsetMathSize.cpp @@ -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); } diff --git a/src/mathed/InsetMathSpecialChar.cpp b/src/mathed/InsetMathSpecialChar.cpp index 32e4c2afbf..4525ff5309 100644 --- a/src/mathed/InsetMathSpecialChar.cpp +++ b/src/mathed/InsetMathSpecialChar.cpp @@ -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_); diff --git a/src/mathed/InsetMathStackrel.cpp b/src/mathed/InsetMathStackrel.cpp index d8b9e97d25..d43e466964 100644 --- a/src/mathed/InsetMathStackrel.cpp +++ b/src/mathed/InsetMathStackrel.cpp @@ -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); diff --git a/src/mathed/InsetMathSubstack.cpp b/src/mathed/InsetMathSubstack.cpp index f88f4927e3..179d44c3d4 100644 --- a/src/mathed/InsetMathSubstack.cpp +++ b/src/mathed/InsetMathSubstack.cpp @@ -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); } diff --git a/src/mathed/InsetMathSymbol.cpp b/src/mathed/InsetMathSymbol.cpp index 5a86536b52..bdca11105b 100644 --- a/src/mathed/InsetMathSymbol.cpp +++ b/src/mathed/InsetMathSymbol.cpp @@ -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); } diff --git a/src/mathed/InsetMathTabular.cpp b/src/mathed/InsetMathTabular.cpp index 2c814a38c6..40cf58d37c 100644 --- a/src/mathed/InsetMathTabular.cpp +++ b/src/mathed/InsetMathTabular.cpp @@ -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); } diff --git a/src/mathed/InsetMathUnderset.cpp b/src/mathed/InsetMathUnderset.cpp index 7632b0c6af..3f4d0c49c4 100644 --- a/src/mathed/InsetMathUnderset.cpp +++ b/src/mathed/InsetMathUnderset.cpp @@ -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); } diff --git a/src/mathed/InsetMathXArrow.cpp b/src/mathed/InsetMathXArrow.cpp index 8c8a4970bc..fbdac6922f 100644 --- a/src/mathed/InsetMathXArrow.cpp +++ b/src/mathed/InsetMathXArrow.cpp @@ -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 diff --git a/src/mathed/InsetMathXYArrow.cpp b/src/mathed/InsetMathXYArrow.cpp index 80aeb7276b..19852e5de1 100644 --- a/src/mathed/InsetMathXYArrow.cpp +++ b/src/mathed/InsetMathXYArrow.cpp @@ -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()) { diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index 9fe6e15cc4..80948fd824 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -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); diff --git a/src/mathed/MathMacroTemplate.cpp b/src/mathed/MathMacroTemplate.cpp index d30fc36b22..4b68626062 100644 --- a/src/mathed/MathMacroTemplate.cpp +++ b/src/mathed/MathMacroTemplate.cpp @@ -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 index 0000000000..8f24ba5c89 --- /dev/null +++ b/src/support/Changer.h @@ -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; + + +} + +#endif //LYX_CHANGER_H diff --git a/src/support/Makefile.am b/src/support/Makefile.am index 1487285d69..5748019bf4 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -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 index 0000000000..9b9d020a41 --- /dev/null +++ b/src/support/RefChanger.h @@ -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 +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 using RefChanger = unique_ptr>; + + +/// Saves the value of \param ref in a movable object +template RefChanger make_save(X & ref) +{ + return make_unique>(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 +RefChanger 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