Skip drawing of markers in non-editable math data

There is no reason to reserve pixel space in macros replacement text,
which is not editable. This makes macros more compact and eases the
writing of lib/symbols.

* introduce new InsetMath::drawMarkers and friends that do nothing
  when nested inside a macro. This required to move macro_nesting
  inside MetricsBase, and to pass MetricsInfo & to metricsMarkers.

* keep track of nesting when drawing rows or macros.
This commit is contained in:
Jean-Marc Lasgouttes 2016-11-14 18:01:56 +01:00
parent f3f9b083d1
commit 9a9a6a8c8f
33 changed files with 112 additions and 57 deletions

View File

@ -38,8 +38,8 @@ namespace lyx {
MetricsBase::MetricsBase(BufferView * b, FontInfo f, int w)
: bv(b), font(move(f)), style(LM_ST_TEXT), fontname("mathnormal"),
textwidth(w), solid_line_thickness_(1), solid_line_offset_(1),
dotted_line_thickness_(1)
textwidth(w), macro_nesting(0),
solid_line_thickness_(1), solid_line_offset_(1), dotted_line_thickness_(1)
{
if (lyxrc.zoom >= 200) {
// derive the line thickness from zoom factor
@ -88,7 +88,7 @@ Changer MetricsBase::changeFontSet(string const & name, bool cond)
MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
MacroContext const & mc)
: base(bv, font, textwidth), macro_nesting(0), macrocontext(mc)
: base(bv, font, textwidth), macrocontext(mc)
{}

View File

@ -65,6 +65,8 @@ public:
std::string fontname;
/// This is the width available in pixels
int textwidth;
/// count wether the current mathdata is nested in macro(s)
int macro_nesting;
/// Temporarily change a full font.
Changer changeFontSet(std::string const & font, bool cond = true);
@ -101,8 +103,6 @@ public:
///
MetricsBase base;
/// count wether the current mathdata is nested in macro(s)
int macro_nesting;
/// The context to resolve macros
MacroContext const & macrocontext;
};

View File

@ -16,13 +16,15 @@
#include "MathRow.h"
#include "MathStream.h"
#include "MetricsInfo.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/textutils.h"
#include "support/lassert.h"
using namespace std;
@ -65,6 +67,36 @@ bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
return true;
}
void InsetMath::metricsMarkers(MetricsInfo & mi, Dimension & dim,
int framesize) const
{
if (!mi.base.macro_nesting)
Inset::metricsMarkers(dim, framesize);
}
void InsetMath::metricsMarkers2(MetricsInfo & mi, Dimension & dim,
int framesize) const
{
if (!mi.base.macro_nesting)
Inset::metricsMarkers2(dim, framesize);
}
void InsetMath::drawMarkers(PainterInfo & pi, int x, int y) const
{
if (!pi.base.macro_nesting)
Inset::drawMarkers(pi, x, y);
}
void InsetMath::drawMarkers2(PainterInfo & pi, int x, int y) const
{
if (!pi.base.macro_nesting)
Inset::drawMarkers2(pi, x, y);
}
void InsetMath::dump() const
{

View File

@ -169,6 +169,15 @@ public:
/// Add this inset to a math row. Return true if contents got added
virtual bool addToMathRow(MathRow &, MetricsInfo & mi) const;
/// draw four angular markers
void drawMarkers(PainterInfo & pi, int x, int y) const;
/// draw two angular markers
void drawMarkers2(PainterInfo & pi, int x, int y) const;
/// add space for markers
void metricsMarkers(MetricsInfo & mi, Dimension & dim, int framesize = 1) const;
/// add space for markers
void metricsMarkers2(MetricsInfo & mi, Dimension & dim, int framesize = 1) const;
/// identifies things that can get scripts
virtual bool isScriptable() const { return false; }
/// will this get written as a single block in {..}

View File

@ -51,7 +51,7 @@ void InsetMathBoldSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
{
//Changer dummy = mi.base.changeFontSet("mathbf");
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
++dim.wid; // for 'double stroke'
}

View File

@ -83,7 +83,7 @@ void InsetMathBox::metrics(MetricsInfo & mi, Dimension & dim) const
{
Changer dummy = mi.base.changeFontSet("textnormal");
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}
@ -135,7 +135,7 @@ void InsetMathFBox::metrics(MetricsInfo & mi, Dimension & dim) const
{
Changer dummy = mi.base.changeFontSet("textnormal");
cell(0).metrics(mi, dim);
metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
metricsMarkers2(mi, dim, 3); // 1 pixel space, 1 frame, 1 space
}
@ -246,7 +246,7 @@ void InsetMathMakebox::metrics(MetricsInfo & mi, Dimension & dim) const
dim.des += 1;
}
metricsMarkers(dim);
metricsMarkers(mi, dim);
}
@ -360,7 +360,7 @@ InsetMathBoxed::InsetMathBoxed(Buffer * buf)
void InsetMathBoxed::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
metricsMarkers2(mi, dim, 3); // 1 pixel space, 1 frame, 1 space
}

View File

@ -55,7 +55,7 @@ void InsetMathBrace::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = max(dim0.asc, t.asc);
dim.des = max(dim0.des, t.des);
dim.wid = dim0.width() + 2 * t.wid;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -38,7 +38,7 @@ Inset * InsetMathCancel::clone() const
void InsetMathCancel::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -47,7 +47,7 @@ void InsetMathCancelto::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = max(dim0.ascent() + 2, dim0.ascent() + dim1.ascent()) + 2 + 8;
dim.des = max(dim0.descent() - 2, dim1.descent()) + 2;
dim.wid = dim0.width() + dim1.width() + 10;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -31,7 +31,7 @@ Inset * InsetMathClass::clone() const
void InsetMathClass::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -49,7 +49,7 @@ Inset * InsetMathColor::clone() const
void InsetMathColor::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -50,7 +50,7 @@ Inset * InsetMathComment::clone() const
void InsetMathComment::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -122,7 +122,7 @@ void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const
dim.des += dh_ + 2;
}
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -41,7 +41,7 @@ void InsetMathEnsureMath::metrics(MetricsInfo & mi, Dimension & dim) const
bool really_change_font = isTextFont(mi.base.fontname);
Changer dummy = mi.base.changeFontSet("mathnormal", really_change_font);
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -39,7 +39,7 @@ Inset * InsetMathEnv::clone() const
void InsetMathEnv::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -86,7 +86,7 @@ void InsetMathFont::metrics(MetricsInfo & mi, Dimension & dim) const
{
Changer dummy = mi.base.changeFontSet(font());
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -61,7 +61,7 @@ void InsetMathFontOld::metrics(MetricsInfo & mi, Dimension & dim) const
Changer dummy = mi.base.changeFontSet(fontname, really_change_font);
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -207,7 +207,7 @@ void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
dim.des = dim1.height() + 2 - 5;
}
}
metricsMarkers(dim);
metricsMarkers(mi, dim);
}
@ -582,7 +582,7 @@ void InsetMathBinom::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = dim0.height() + 4 + 5;
dim.des = dim1.height() + 4 - 5;
dim.wid = max(dim0.wid, dim1.wid) + 2 * dw(dim.height()) + 4;
metricsMarkers2(dim);
metricsMarkers2(mi, dim);
}

View File

@ -588,7 +588,7 @@ void InsetMathGrid::metrics(MetricsInfo & mi, Dimension & dim) const
}
*/
dim.wid += leftMargin() + rightMargin();
metricsMarkers2(dim);
metricsMarkers2(mi, dim);
// Cache the inset dimension.
setDimCache(mi, dim);
}

View File

@ -34,7 +34,7 @@ void InsetMathLefteqn::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc += 2;
dim.des += 2;
dim.wid = 4;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -39,7 +39,7 @@ void InsetMathOverset::metrics(MetricsInfo & mi, Dimension & dim) const
dim.wid = max(dim0.width(), dim1.wid) + 4;
dim.asc = dim1.asc + dim0.height() + 4;
dim.des = dim1.des;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -39,7 +39,7 @@ Inset * InsetMathPhantom::clone() const
void InsetMathPhantom::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -47,7 +47,7 @@ void InsetMathRoot::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = max(dim0.ascent() + 5, dim1.ascent()) + 2;
dim.des = max(dim0.descent() - 5, dim1.descent()) + 2;
dim.wid = dim0.width() + dim1.width() + 10;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -333,7 +333,7 @@ void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
dim.des = max(nd, des);
} else
dim.des = nd;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -221,7 +221,7 @@ void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
int nd = ndes(bv);
int des = dyb(bv) + max(dimbl.descent(), dimbr.descent());
dim.des = max(nd, des);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -45,7 +45,7 @@ void InsetMathSize::metrics(MetricsInfo & mi, Dimension & dim) const
{
Changer dummy = mi.base.changeStyle(style_);
cell(0).metrics(mi, dim);
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -41,7 +41,7 @@ void InsetMathSqrt::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc += 4;
dim.des += 2;
dim.wid += 12;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -77,7 +77,7 @@ void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc = dim1.ascent() + dim0.height() + 4;
dim.des = dim1.descent();
}
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -40,7 +40,7 @@ void InsetMathUnderset::metrics(MetricsInfo & mi, Dimension & dim) const
dim.wid = max(dim0.width(), dim1.width()) + 4;
dim.asc = dim1.ascent();
dim.des = dim1.descent() + dim0.height() + 4;
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -51,7 +51,7 @@ void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
dim.wid = max(dim0.width(), dim1.width()) + 10;
dim.asc = dim0.height() + 10;
dim.des = dim1.height();
metricsMarkers(dim);
metricsMarkers(mi, dim);
}

View File

@ -71,9 +71,9 @@ public:
bool addToMathRow(MathRow & mrow, MetricsInfo & mi) const
{
// macro arguments are in macros
LATTEST(mi.macro_nesting > 0);
if (mi.macro_nesting == 1)
mi.macro_nesting = 0;
LATTEST(mi.base.macro_nesting > 0);
if (mi.base.macro_nesting == 1)
mi.base.macro_nesting = 0;
MathRow::Element e_beg(MathRow::BEG_ARG, mi);
e_beg.macro = mathMacro_;
@ -86,15 +86,15 @@ public:
// if there was no contents, and the contents is editable,
// then we insert a box instead.
if (!has_contents && mi.macro_nesting == 0) {
if (!has_contents && mi.base.macro_nesting == 0) {
MathRow::Element e(MathRow::BOX, mi);
e.color = Color_mathline;
mrow.push_back(e);
has_contents = true;
}
if (mi.macro_nesting == 0)
mi.macro_nesting = 1;
if (mi.base.macro_nesting == 0)
mi.base.macro_nesting = 1;
MathRow::Element e_end(MathRow::END_ARG, mi);
e_end.macro = mathMacro_;
@ -107,9 +107,9 @@ public:
///
void metrics(MetricsInfo & mi, Dimension & dim) const {
// macro arguments are in macros
LATTEST(mi.macro_nesting > 0);
if (mi.macro_nesting == 1)
mi.macro_nesting = 0;
LATTEST(mi.base.macro_nesting > 0);
if (mi.base.macro_nesting == 1)
mi.base.macro_nesting = 0;
mathMacro_->macro()->unlock();
mathMacro_->cell(idx_).metrics(mi, dim);
@ -119,8 +119,8 @@ public:
def_.metrics(mi, dim);
mathMacro_->macro()->lock();
if (mi.macro_nesting == 0)
mi.macro_nesting = 1;
if (mi.base.macro_nesting == 0)
mi.base.macro_nesting = 1;
}
// write(), normalize(), infoize() and infoize2() are not needed since
// MathMacro uses the definition and not the expanded cells.
@ -138,6 +138,10 @@ public:
void octave(OctaveStream & os) const { os << mathMacro_->cell(idx_); }
///
void draw(PainterInfo & pi, int x, int y) const {
LATTEST(pi.base.macro_nesting > 0);
if (pi.base.macro_nesting == 1)
pi.base.macro_nesting = 0;
if (mathMacro_->editMetrics(pi.base.bv)) {
// The only way a ArgumentProxy can appear is in a cell of the
// MathMacro. Moreover the cells are only drawn in the DISPLAY_FOLDED
@ -155,6 +159,9 @@ public:
def_.draw(pi, x, y);
} else
mathMacro_->cell(idx_).draw(pi, x, y);
if (pi.base.macro_nesting == 0)
pi.base.macro_nesting = 1;
}
///
size_t idx() const { return idx_; }
@ -324,7 +331,7 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
e_beg.macro = this;
mrow.push_back(e_beg);
++mi.macro_nesting;
++mi.base.macro_nesting;
d->macro_->lock();
bool has_contents = d->expanded_.addToMathRow(mrow, mi);
@ -332,14 +339,14 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
// if there was no contents and the array is editable, then we
// insert a grey box instead.
if (!has_contents && mi.macro_nesting == 1) {
if (!has_contents && mi.base.macro_nesting == 1) {
MathRow::Element e(MathRow::BOX, mi);
e.color = Color_mathmacroblend;
mrow.push_back(e);
has_contents = true;
}
--mi.macro_nesting;
--mi.base.macro_nesting;
MathRow::Element e_end(MathRow::END_MACRO, mi);
e_end.macro = this;
@ -442,7 +449,7 @@ bool MathMacro::editMetrics(BufferView const * bv) const
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
{
// the macro contents is not editable (except the arguments)
++mi.macro_nesting;
++mi.base.macro_nesting;
// set edit mode for which we will have calculated metrics. But only
d->editing_[mi.base.bv] = editMode(mi.base.bv);
@ -457,7 +464,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
dim.wid += bsdim.width() + 1;
dim.asc = max(bsdim.ascent(), dim.ascent());
dim.des = max(bsdim.descent(), dim.descent());
metricsMarkers(dim);
metricsMarkers(mi, dim);
} else if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST
&& d->editing_[mi.base.bv]) {
// Macro will be edited in a old-style list mode here:
@ -497,7 +504,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
dim.asc += 1;
dim.des += 1;
dim.wid += 2;
metricsMarkers2(dim);
metricsMarkers2(mi, dim);
} else {
LBUFERR(d->macro_);
@ -534,7 +541,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
}
// restore macro nesting
--mi.macro_nesting;
--mi.base.macro_nesting;
}
@ -703,6 +710,9 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
dim.height() - 2, Color_mathmacroframe);
drawMarkers2(pi, expx, expy);
} else {
// the macro contents is not editable (except the arguments)
++pi.base.macro_nesting;
bool drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX;
bool upshape = currentMode() == TEXT_MODE;
Changer dummy = pi.base.font.changeShape(upshape ? UP_SHAPE
@ -737,8 +747,11 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
} else
d->expanded_.draw(pi, expx, expy);
--pi.base.macro_nesting;
if (!drawBox)
drawMarkers(pi, x, y);
}
// edit mode changed?

View File

@ -269,7 +269,7 @@ Inset * InsetMathWrapper::clone() const
void InsetMathWrapper::metrics(MetricsInfo & mi, Dimension & dim) const
{
value_->metrics(mi, dim);
//metricsMarkers2(dim);
//metricsMarkers2(mi, dim);
}

View File

@ -37,7 +37,7 @@ namespace lyx {
MathRow::Element::Element(Type t, MetricsInfo &mi)
: type(t), macro_nesting(mi.macro_nesting),
: type(t), macro_nesting(mi.base.macro_nesting),
inset(0), mclass(MC_ORD), before(0), after(0), compl_unique_to(0),
macro(0), color(Color_red)
{}
@ -130,7 +130,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
CoordCache & coords = mi.base.bv->coordCache();
for (Element const & e : elements_) {
Dimension d;
mi.macro_nesting = e.macro_nesting;
mi.base.macro_nesting = e.macro_nesting;
switch (e.type) {
case BEGIN:
case END:
@ -195,6 +195,7 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
{
CoordCache & coords = pi.base.bv->coordCache();
for (Element const & e : elements_) {
pi.base.macro_nesting = e.macro_nesting;
switch (e.type) {
case INSET: {
// This is hackish: the math inset does not know that space