mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-27 03:36:39 +00:00
Rewrite handling of macro nesting in math rows
Macro nesting is now recorded into the macro inset itself. This allows the ArgumentProxy inset to determine whether it is editable or not by looking at its macro. Remove code in the metrics and draw methods of ArgumentProxy: this code is AFAICS not active anymore, since arguments are linearized into math rows. Use Changer idiom to change locally the values of MecticsInfo::base.macro_nesting.
This commit is contained in:
parent
58e479527e
commit
0f15dcc698
@ -3556,7 +3556,7 @@ void Buffer::updateMacroInstances(UpdateType utype) const
|
|||||||
MacroContext mc = MacroContext(this, it);
|
MacroContext mc = MacroContext(this, it);
|
||||||
for (DocIterator::idx_type i = 0; i < n; ++i) {
|
for (DocIterator::idx_type i = 0; i < n; ++i) {
|
||||||
MathData & data = minset->cell(i);
|
MathData & data = minset->cell(i);
|
||||||
data.updateMacros(0, mc, utype);
|
data.updateMacros(0, mc, utype, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,9 @@ MathClass InsetMath::mathClass() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & ) const
|
||||||
{
|
{
|
||||||
MathRow::Element e(MathRow::INSET, mi);
|
MathRow::Element e(MathRow::INSET);
|
||||||
e.inset = this;
|
e.inset = this;
|
||||||
e.mclass = mathClass();
|
e.mclass = mathClass();
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
|
@ -222,7 +222,8 @@ bool MathData::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
|||||||
BufferView * bv = mi.base.bv;
|
BufferView * bv = mi.base.bv;
|
||||||
MathData * ar = const_cast<MathData*>(this);
|
MathData * ar = const_cast<MathData*>(this);
|
||||||
ar->updateMacros(&bv->cursor(), mi.macrocontext,
|
ar->updateMacros(&bv->cursor(), mi.macrocontext,
|
||||||
InternalUpdate);
|
InternalUpdate, mi.base.macro_nesting);
|
||||||
|
|
||||||
|
|
||||||
// FIXME: for completion, try to insert the relevant data in the
|
// FIXME: for completion, try to insert the relevant data in the
|
||||||
// mathrow (like is done for text rows). We could add a pair of
|
// mathrow (like is done for text rows). We could add a pair of
|
||||||
@ -341,7 +342,7 @@ void MathData::updateBuffer(ParIterator const & it, UpdateType utype)
|
|||||||
|
|
||||||
|
|
||||||
void MathData::updateMacros(Cursor * cur, MacroContext const & mc,
|
void MathData::updateMacros(Cursor * cur, MacroContext const & mc,
|
||||||
UpdateType utype)
|
UpdateType utype, int nesting)
|
||||||
{
|
{
|
||||||
// If we are editing a macro, we cannot update it immediately,
|
// If we are editing a macro, we cannot update it immediately,
|
||||||
// otherwise wrong undo steps will be recorded (bug 6208).
|
// otherwise wrong undo steps will be recorded (bug 6208).
|
||||||
@ -430,7 +431,7 @@ void MathData::updateMacros(Cursor * cur, MacroContext const & mc,
|
|||||||
if (inset->asScriptInset())
|
if (inset->asScriptInset())
|
||||||
inset = inset->asScriptInset()->nuc()[0].nucleus();
|
inset = inset->asScriptInset()->nuc()[0].nucleus();
|
||||||
LASSERT(inset->asMacro(), continue);
|
LASSERT(inset->asMacro(), continue);
|
||||||
inset->asMacro()->updateRepresentation(cur, mc, utype);
|
inset->asMacro()->updateRepresentation(cur, mc, utype, nesting + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ public:
|
|||||||
|
|
||||||
/// attach/detach arguments to macros, updating the cur to
|
/// attach/detach arguments to macros, updating the cur to
|
||||||
/// stay visually at the same position (cur==0 is allowed)
|
/// stay visually at the same position (cur==0 is allowed)
|
||||||
void updateMacros(Cursor * cur, MacroContext const & mc, UpdateType);
|
void updateMacros(Cursor * cur, MacroContext const & mc, UpdateType, int nesting);
|
||||||
///
|
///
|
||||||
void updateBuffer(ParIterator const &, UpdateType);
|
void updateBuffer(ParIterator const &, UpdateType);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "support/gettext.h"
|
#include "support/gettext.h"
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
#include "support/lstrings.h"
|
#include "support/lstrings.h"
|
||||||
|
#include "support/RefChanger.h"
|
||||||
#include "support/textutils.h"
|
#include "support/textutils.h"
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@ -71,11 +72,11 @@ public:
|
|||||||
bool addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
bool addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
||||||
{
|
{
|
||||||
// macro arguments are in macros
|
// macro arguments are in macros
|
||||||
LATTEST(mi.base.macro_nesting > 0);
|
LATTEST(mathMacro_->nesting() > 0);
|
||||||
if (mi.base.macro_nesting == 1)
|
/// The macro nesting can change display of insets. Change it locally.
|
||||||
mi.base.macro_nesting = 0;
|
Changer chg = make_change(mi.base.macro_nesting, mathMacro_->nesting());
|
||||||
|
|
||||||
MathRow::Element e_beg(MathRow::BEG_ARG, mi);
|
MathRow::Element e_beg(MathRow::BEG_ARG);
|
||||||
e_beg.macro = mathMacro_;
|
e_beg.macro = mathMacro_;
|
||||||
e_beg.ar = &mathMacro_->cell(idx_);
|
e_beg.ar = &mathMacro_->cell(idx_);
|
||||||
mrow.push_back(e_beg);
|
mrow.push_back(e_beg);
|
||||||
@ -92,17 +93,14 @@ public:
|
|||||||
|
|
||||||
// if there was no contents, and the contents is editable,
|
// if there was no contents, and the contents is editable,
|
||||||
// then we insert a box instead.
|
// then we insert a box instead.
|
||||||
if (!has_contents && mi.base.macro_nesting == 0) {
|
if (!has_contents && mathMacro_->nesting() == 1) {
|
||||||
MathRow::Element e(MathRow::BOX, mi);
|
MathRow::Element e(MathRow::BOX);
|
||||||
e.color = Color_mathline;
|
e.color = Color_mathline;
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
has_contents = true;
|
has_contents = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mi.base.macro_nesting == 0)
|
MathRow::Element e_end(MathRow::END_ARG);
|
||||||
mi.base.macro_nesting = 1;
|
|
||||||
|
|
||||||
MathRow::Element e_end(MathRow::END_ARG, mi);
|
|
||||||
e_end.macro = mathMacro_;
|
e_end.macro = mathMacro_;
|
||||||
e_end.ar = &mathMacro_->cell(idx_);
|
e_end.ar = &mathMacro_->cell(idx_);
|
||||||
|
|
||||||
@ -111,22 +109,9 @@ public:
|
|||||||
return has_contents;
|
return has_contents;
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
void metrics(MetricsInfo & mi, Dimension & dim) const {
|
void metrics(MetricsInfo &, Dimension &) const {
|
||||||
// macro arguments are in macros
|
// This should never be invoked, since ArgumentProxy insets are linearized
|
||||||
LATTEST(mi.base.macro_nesting > 0);
|
LATTEST(false);
|
||||||
if (mi.base.macro_nesting == 1)
|
|
||||||
mi.base.macro_nesting = 0;
|
|
||||||
|
|
||||||
mathMacro_->macro()->unlock();
|
|
||||||
mathMacro_->cell(idx_).metrics(mi, dim);
|
|
||||||
|
|
||||||
if (!mathMacro_->editMetrics(mi.base.bv)
|
|
||||||
&& mathMacro_->cell(idx_).empty())
|
|
||||||
def_.metrics(mi, dim);
|
|
||||||
|
|
||||||
mathMacro_->macro()->lock();
|
|
||||||
if (mi.base.macro_nesting == 0)
|
|
||||||
mi.base.macro_nesting = 1;
|
|
||||||
}
|
}
|
||||||
// write(), normalize(), infoize() and infoize2() are not needed since
|
// write(), normalize(), infoize() and infoize2() are not needed since
|
||||||
// MathMacro uses the definition and not the expanded cells.
|
// MathMacro uses the definition and not the expanded cells.
|
||||||
@ -143,31 +128,9 @@ public:
|
|||||||
///
|
///
|
||||||
void octave(OctaveStream & os) const { os << mathMacro_->cell(idx_); }
|
void octave(OctaveStream & os) const { os << mathMacro_->cell(idx_); }
|
||||||
///
|
///
|
||||||
void draw(PainterInfo & pi, int x, int y) const {
|
void draw(PainterInfo &, int, int) const {
|
||||||
LATTEST(pi.base.macro_nesting > 0);
|
// This should never be invoked, since ArgumentProxy insets are linearized
|
||||||
if (pi.base.macro_nesting == 1)
|
LATTEST(false);
|
||||||
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
|
|
||||||
// mode and then, if the macro is edited the monochrome
|
|
||||||
// mode is entered by the MathMacro before calling the cells' draw
|
|
||||||
// method. Then eventually this code is reached and the proxy leaves
|
|
||||||
// monochrome mode temporarely. Hence, if it is not in monochrome
|
|
||||||
// here (and the assert triggers in pain.leaveMonochromeMode())
|
|
||||||
// it's a bug.
|
|
||||||
pi.pain.leaveMonochromeMode();
|
|
||||||
mathMacro_->cell(idx_).draw(pi, x, y);
|
|
||||||
pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend);
|
|
||||||
} else if (mathMacro_->cell(idx_).empty()) {
|
|
||||||
mathMacro_->cell(idx_).setXY(*pi.base.bv, x, y);
|
|
||||||
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_; }
|
size_t idx() const { return idx_; }
|
||||||
@ -244,6 +207,8 @@ public:
|
|||||||
bool isUpdating_;
|
bool isUpdating_;
|
||||||
/// maximal number of arguments the macro is greedy for
|
/// maximal number of arguments the macro is greedy for
|
||||||
size_t appetite_;
|
size_t appetite_;
|
||||||
|
/// Level of nesting in macros (including this one)
|
||||||
|
int nesting_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -329,16 +294,17 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
|||||||
// This is the same as what is done in metrics().
|
// This is the same as what is done in metrics().
|
||||||
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
||||||
|
|
||||||
|
/// The macro nesting can change display of insets. Change it locally.
|
||||||
|
Changer chg = make_change(mi.base.macro_nesting, d->nesting_);
|
||||||
|
|
||||||
if (displayMode() != MathMacro::DISPLAY_NORMAL
|
if (displayMode() != MathMacro::DISPLAY_NORMAL
|
||||||
|| d->editing_[mi.base.bv])
|
|| d->editing_[mi.base.bv])
|
||||||
return InsetMath::addToMathRow(mrow, mi);
|
return InsetMath::addToMathRow(mrow, mi);
|
||||||
|
|
||||||
MathRow::Element e_beg(MathRow::BEG_MACRO, mi);
|
MathRow::Element e_beg(MathRow::BEG_MACRO);
|
||||||
e_beg.macro = this;
|
e_beg.macro = this;
|
||||||
mrow.push_back(e_beg);
|
mrow.push_back(e_beg);
|
||||||
|
|
||||||
++mi.base.macro_nesting;
|
|
||||||
|
|
||||||
d->macro_->lock();
|
d->macro_->lock();
|
||||||
bool has_contents = d->expanded_.addToMathRow(mrow, mi);
|
bool has_contents = d->expanded_.addToMathRow(mrow, mi);
|
||||||
d->macro_->unlock();
|
d->macro_->unlock();
|
||||||
@ -346,15 +312,13 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|
|||||||
// if there was no contents and the array is editable, then we
|
// if there was no contents and the array is editable, then we
|
||||||
// insert a grey box instead.
|
// insert a grey box instead.
|
||||||
if (!has_contents && mi.base.macro_nesting == 1) {
|
if (!has_contents && mi.base.macro_nesting == 1) {
|
||||||
MathRow::Element e(MathRow::BOX, mi);
|
MathRow::Element e(MathRow::BOX);
|
||||||
e.color = Color_mathmacroblend;
|
e.color = Color_mathmacroblend;
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
has_contents = true;
|
has_contents = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
--mi.base.macro_nesting;
|
MathRow::Element e_end(MathRow::END_MACRO);
|
||||||
|
|
||||||
MathRow::Element e_end(MathRow::END_MACRO, mi);
|
|
||||||
e_end.macro = this;
|
e_end.macro = this;
|
||||||
mrow.push_back(e_end);
|
mrow.push_back(e_end);
|
||||||
|
|
||||||
@ -407,6 +371,12 @@ docstring MathMacro::macroName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MathMacro::nesting() const
|
||||||
|
{
|
||||||
|
return d->nesting_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MathMacro::cursorPos(BufferView const & bv,
|
void MathMacro::cursorPos(BufferView const & bv,
|
||||||
CursorSlice const & sl, bool boundary, int & x, int & y) const
|
CursorSlice const & sl, bool boundary, int & x, int & y) const
|
||||||
{
|
{
|
||||||
@ -454,8 +424,8 @@ bool MathMacro::editMetrics(BufferView const * bv) const
|
|||||||
|
|
||||||
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||||
{
|
{
|
||||||
// the macro contents is not editable (except the arguments)
|
/// The macro nesting can change display of insets. Change it locally.
|
||||||
++mi.base.macro_nesting;
|
Changer chg = make_change(mi.base.macro_nesting, d->nesting_);
|
||||||
|
|
||||||
// set edit mode for which we will have calculated metrics. But only
|
// set edit mode for which we will have calculated metrics. But only
|
||||||
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
d->editing_[mi.base.bv] = editMode(mi.base.bv);
|
||||||
@ -551,9 +521,6 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
dim.des += 2;
|
dim.des += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore macro nesting
|
|
||||||
--mi.base.macro_nesting;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -600,7 +567,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
|
void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
|
||||||
UpdateType utype)
|
UpdateType utype, int nesting)
|
||||||
{
|
{
|
||||||
// block recursive calls (bug 8999)
|
// block recursive calls (bug 8999)
|
||||||
if (d->isUpdating_)
|
if (d->isUpdating_)
|
||||||
@ -612,6 +579,9 @@ void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
|
|||||||
if (d->macro_ == 0)
|
if (d->macro_ == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// remember nesting level of this macro
|
||||||
|
d->nesting_ = nesting;
|
||||||
|
|
||||||
// update requires
|
// update requires
|
||||||
d->requires_ = d->macro_->requires();
|
d->requires_ = d->macro_->requires();
|
||||||
|
|
||||||
@ -643,7 +613,7 @@ void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
|
|||||||
// protected by UpdateLocker.
|
// protected by UpdateLocker.
|
||||||
if (d->macro_->expand(values, d->expanded_)) {
|
if (d->macro_->expand(values, d->expanded_)) {
|
||||||
if (utype == OutputUpdate && !d->expanded_.empty())
|
if (utype == OutputUpdate && !d->expanded_.empty())
|
||||||
d->expanded_.updateMacros(cur, mc, utype);
|
d->expanded_.updateMacros(cur, mc, utype, nesting);
|
||||||
}
|
}
|
||||||
// get definition for list edit mode
|
// get definition for list edit mode
|
||||||
docstring const & display = d->macro_->display();
|
docstring const & display = d->macro_->display();
|
||||||
@ -722,9 +692,6 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
|
|||||||
dim.height() - 2, Color_mathmacroframe);
|
dim.height() - 2, Color_mathmacroframe);
|
||||||
drawMarkers2(pi, expx, expy);
|
drawMarkers2(pi, expx, expy);
|
||||||
} else {
|
} 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 drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX;
|
||||||
Changer dummy = (currentMode() == TEXT_MODE)
|
Changer dummy = (currentMode() == TEXT_MODE)
|
||||||
? pi.base.font.changeShape(UP_SHAPE)
|
? pi.base.font.changeShape(UP_SHAPE)
|
||||||
@ -759,8 +726,6 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
|
|||||||
} else
|
} else
|
||||||
d->expanded_.draw(pi, expx, expy);
|
d->expanded_.draw(pi, expx, expy);
|
||||||
|
|
||||||
--pi.base.macro_nesting;
|
|
||||||
|
|
||||||
if (!drawBox)
|
if (!drawBox)
|
||||||
drawMarkers(pi, x, y);
|
drawMarkers(pi, x, y);
|
||||||
|
|
||||||
|
@ -126,6 +126,8 @@ public:
|
|||||||
MacroData const * macro() const;
|
MacroData const * macro() const;
|
||||||
///
|
///
|
||||||
docstring macroName() const;
|
docstring macroName() const;
|
||||||
|
/// Level of nesting in macros (including this one)
|
||||||
|
int nesting() const;
|
||||||
///
|
///
|
||||||
bool validName() const;
|
bool validName() const;
|
||||||
///
|
///
|
||||||
@ -152,7 +154,8 @@ protected:
|
|||||||
/// update macro definition
|
/// update macro definition
|
||||||
void updateMacro(MacroContext const & mc);
|
void updateMacro(MacroContext const & mc);
|
||||||
/// check if macro definition changed, argument changed etc. and adapt
|
/// check if macro definition changed, argument changed etc. and adapt
|
||||||
void updateRepresentation(Cursor * cur, MacroContext const & mc, UpdateType);
|
void updateRepresentation(Cursor * cur, MacroContext const & mc,
|
||||||
|
UpdateType, int nesting);
|
||||||
/// empty macro, put arguments into args, possibly strip arity-attachedArgsNum_ empty ones.
|
/// empty macro, put arguments into args, possibly strip arity-attachedArgsNum_ empty ones.
|
||||||
/// Includes the optional arguments.
|
/// Includes the optional arguments.
|
||||||
void detachArguments(std::vector<MathData> & args, bool strip);
|
void detachArguments(std::vector<MathData> & args, bool strip);
|
||||||
|
@ -36,17 +36,16 @@ using namespace std;
|
|||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
|
|
||||||
MathRow::Element::Element(Type t, MetricsInfo &mi)
|
MathRow::Element::Element(Type t)
|
||||||
: type(t), macro_nesting(mi.base.macro_nesting),
|
: type(t), inset(0), mclass(MC_ORD), before(0), after(0),
|
||||||
inset(0), mclass(MC_ORD), before(0), after(0), compl_unique_to(0),
|
compl_unique_to(0), macro(0), color(Color_red)
|
||||||
macro(0), color(Color_red)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
||||||
{
|
{
|
||||||
// First there is a dummy element of type "open"
|
// First there is a dummy element of type "open"
|
||||||
push_back(Element(BEGIN, mi));
|
push_back(Element(BEGIN));
|
||||||
back().mclass = MC_OPEN;
|
back().mclass = MC_OPEN;
|
||||||
|
|
||||||
// Then insert the MathData argument
|
// Then insert the MathData argument
|
||||||
@ -55,13 +54,13 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
|||||||
// empty arrays are visible when they are editable
|
// empty arrays are visible when they are editable
|
||||||
// we reserve the necessary space anyway (even if nothing gets drawn)
|
// we reserve the necessary space anyway (even if nothing gets drawn)
|
||||||
if (!has_contents) {
|
if (!has_contents) {
|
||||||
Element e(BOX, mi);
|
Element e(BOX);
|
||||||
e.color = Color_mathline;
|
e.color = mi.base.macro_nesting == 0 ? Color_mathline : Color_none;
|
||||||
push_back(e);
|
push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally there is a dummy element of type "close"
|
// Finally there is a dummy element of type "close"
|
||||||
push_back(Element(END, mi));
|
push_back(Element(END));
|
||||||
back().mclass = MC_CLOSE;
|
back().mclass = MC_CLOSE;
|
||||||
|
|
||||||
/* Do spacing only in math mode. This test is a bit clumsy,
|
/* Do spacing only in math mode. This test is a bit clumsy,
|
||||||
@ -127,10 +126,13 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
// arguments, it is necessary to keep track of them.
|
// arguments, it is necessary to keep track of them.
|
||||||
map<MathMacro const *, Dimension> dim_macros;
|
map<MathMacro const *, Dimension> dim_macros;
|
||||||
map<MathData const *, Dimension> dim_arrays;
|
map<MathData const *, Dimension> dim_arrays;
|
||||||
|
// this vector remembers the stack of macro nesting values
|
||||||
|
vector<int> macro_nesting;
|
||||||
|
macro_nesting.push_back(mi.base.macro_nesting);
|
||||||
CoordCache & coords = mi.base.bv->coordCache();
|
CoordCache & coords = mi.base.bv->coordCache();
|
||||||
for (Element const & e : elements_) {
|
for (Element const & e : elements_) {
|
||||||
|
mi.base.macro_nesting = macro_nesting.back();
|
||||||
Dimension d;
|
Dimension d;
|
||||||
mi.base.macro_nesting = e.macro_nesting;
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
case END:
|
case END:
|
||||||
@ -141,12 +143,14 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
coords.insets().add(e.inset, d);
|
coords.insets().add(e.inset, d);
|
||||||
break;
|
break;
|
||||||
case BEG_MACRO:
|
case BEG_MACRO:
|
||||||
|
macro_nesting.push_back(e.macro->nesting());
|
||||||
e.macro->macro()->lock();
|
e.macro->macro()->lock();
|
||||||
// Add a macro to current list
|
// Add a macro to current list
|
||||||
dim_macros[e.macro] = Dimension();
|
dim_macros[e.macro] = Dimension();
|
||||||
break;
|
break;
|
||||||
case END_MACRO:
|
case END_MACRO:
|
||||||
LATTEST(dim_macros.find(e.macro) != dim_macros.end());
|
LATTEST(dim_macros.find(e.macro) != dim_macros.end());
|
||||||
|
macro_nesting.pop_back();
|
||||||
e.macro->macro()->unlock();
|
e.macro->macro()->unlock();
|
||||||
// Cache the dimension of the macro and remove it from
|
// Cache the dimension of the macro and remove it from
|
||||||
// tracking map.
|
// tracking map.
|
||||||
@ -155,14 +159,18 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
break;
|
break;
|
||||||
// This is basically like macros
|
// This is basically like macros
|
||||||
case BEG_ARG:
|
case BEG_ARG:
|
||||||
if (e.macro)
|
if (e.macro) {
|
||||||
|
macro_nesting.push_back(e.macro->nesting());
|
||||||
e.macro->macro()->unlock();
|
e.macro->macro()->unlock();
|
||||||
|
}
|
||||||
dim_arrays[e.ar] = Dimension();
|
dim_arrays[e.ar] = Dimension();
|
||||||
break;
|
break;
|
||||||
case END_ARG:
|
case END_ARG:
|
||||||
LATTEST(dim_arrays.find(e.ar) != dim_arrays.end());
|
LATTEST(dim_arrays.find(e.ar) != dim_arrays.end());
|
||||||
if (e.macro)
|
if (e.macro) {
|
||||||
|
macro_nesting.pop_back();
|
||||||
e.macro->macro()->lock();
|
e.macro->macro()->lock();
|
||||||
|
}
|
||||||
coords.arrays().add(e.ar, dim_arrays[e.ar]);
|
coords.arrays().add(e.ar, dim_arrays[e.ar]);
|
||||||
dim_arrays.erase(e.ar);
|
dim_arrays.erase(e.ar);
|
||||||
break;
|
break;
|
||||||
@ -195,7 +203,6 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
|
|||||||
{
|
{
|
||||||
CoordCache & coords = pi.base.bv->coordCache();
|
CoordCache & coords = pi.base.bv->coordCache();
|
||||||
for (Element const & e : elements_) {
|
for (Element const & e : elements_) {
|
||||||
pi.base.macro_nesting = e.macro_nesting;
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case INSET: {
|
case INSET: {
|
||||||
// This is hackish: the math inset does not know that space
|
// This is hackish: the math inset does not know that space
|
||||||
@ -229,9 +236,9 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
|
|||||||
case BOX: {
|
case BOX: {
|
||||||
Dimension const d = theFontMetrics(pi.base.font).dimension('I');
|
Dimension const d = theFontMetrics(pi.base.font).dimension('I');
|
||||||
// the box is not visible in non-editable context (except for grey macro boxes).
|
// the box is not visible in non-editable context (except for grey macro boxes).
|
||||||
if (e.macro_nesting == 0 || e.color == Color_mathmacroblend)
|
if (e.color != Color_none)
|
||||||
pi.pain.rectangle(x + e.before, y - d.ascent(),
|
pi.pain.rectangle(x + e.before, y - d.ascent(),
|
||||||
d.width(), d.height(), e.color);
|
d.width(), d.height(), e.color);
|
||||||
x += d.wid;
|
x += d.wid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -290,7 +297,8 @@ ostream & operator<<(ostream & os, MathRow::Element const & e)
|
|||||||
<< "-" << e.after << ">";
|
<< "-" << e.after << ">";
|
||||||
break;
|
break;
|
||||||
case MathRow::BEG_MACRO:
|
case MathRow::BEG_MACRO:
|
||||||
os << "\\" << to_utf8(e.macro->name()) << "[";
|
os << "\\" << to_utf8(e.macro->name())
|
||||||
|
<< "^" << e.macro->nesting() << "[";
|
||||||
break;
|
break;
|
||||||
case MathRow::END_MACRO:
|
case MathRow::END_MACRO:
|
||||||
os << "]";
|
os << "]";
|
||||||
|
@ -60,12 +60,10 @@ public:
|
|||||||
struct Element
|
struct Element
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
Element(Type t, MetricsInfo & mi);
|
Element(Type t);
|
||||||
|
|
||||||
/// Classifies the contents of the object
|
/// Classifies the contents of the object
|
||||||
Type type;
|
Type type;
|
||||||
/// count wether the current mathdata is nested in macro(s)
|
|
||||||
int macro_nesting;
|
|
||||||
|
|
||||||
/// When type is INSET
|
/// When type is INSET
|
||||||
/// the math inset
|
/// the math inset
|
||||||
|
Loading…
Reference in New Issue
Block a user