#include "support/debug.h"
#include "support/docstring.h"
#include "support/lstrings.h"
+#include "support/RefChanger.h"
#include <ostream>
#include <sstream>
}
+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)
#include "Color.h"
#include "ColorCode.h"
#include "FontEnums.h"
+
+#include "support/Changer.h"
#include "support/strfwd.h"
+
namespace lyx {
class Lexer;
}
}
+ /// 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);
#include "support/docstring.h"
#include "support/lassert.h"
+#include "support/RefChanger.h"
using namespace std;
{}
+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
}
-/////////////////////////////////////////////////////////////////////////
-//
-// 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);
}
#include "FontInfo.h"
#include "support/strfwd.h"
+#include "support/Changer.h"
+
#include <string>
/// Standard Sizes (mode styles)
+/// note: These values are hard-coded in changeStyle
enum Styles {
///
LM_ST_DISPLAY = 0,
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);
};
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
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;
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);
}
#include "FuncRequest.h"
#include "FuncStatus.h"
-#include "support/gettext.h"
+#include "support/gettext.h"
#include "support/lstrings.h"
#include <sstream>
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;
}
{
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);
}
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;
}
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);
}
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'
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);
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);
}
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);
}
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
}
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);
}
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("[");
{
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, '[');
{
#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);
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_);
{
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);
{
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);
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);
}
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);
}
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);
}
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);
// 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);
}
// 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);
}
#include "MetricsInfo.h"
#include "TextPainter.h"
-#include "support/lassert.h"
#include "frontends/Painter.h"
+#include "support/lassert.h"
+
using namespace std;
+
namespace lyx {
/////////////////////////////////////////////////////////////////////
{
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;
}
} 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);
}
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;
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) {
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)
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;
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);
}
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);
}
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)));
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);
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);
}
{
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;
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);
}
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);
}
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)
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())
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);
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));
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);
}
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);
}
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);
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_);
{
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) {
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);
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);
}
#include "support/debug.h"
#include "support/docstream.h"
+#include "support/lyxlib.h"
#include "support/textutils.h"
#include "support/unique_ptr.h"
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);
//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);
}
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;
}
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);
}
{
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;
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);
}
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;
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
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;
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()) {
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);
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;
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);
--- /dev/null
+// -*- 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
FileMonitor.cpp \
RandomAccessList.h \
bind.h \
+ Change.h \
ConsoleApplication.cpp \
ConsoleApplication.h \
ConsoleApplicationPrivate.h \
qstring_helpers.cpp \
qstring_helpers.h \
regex.h \
+ RefChanger.h \
socktools.cpp \
socktools.h \
strfwd.h \
--- /dev/null
+// -*- 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