Fix issues with macro_nesting handling

The rewrite of macro_nesting done at 0f15dcc6 was faulty, in
particular since the information should be available also at draw
time. To this end, we revert the patch of the said commit that removes
macro nesting information from MathRow::Element. In the next commit,
we will change the marker code so that MathRow::draw does not need the
nesting information.

Actually the code is now cleaner since the macro nesting stack of
MathRow::metrics can be removed.
This commit is contained in:
Jean-Marc Lasgouttes 2017-01-05 13:25:28 +01:00
parent 30da554e59
commit 605438f26d
4 changed files with 20 additions and 27 deletions

View File

@ -58,9 +58,9 @@ MathClass InsetMath::mathClass() const
}
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & ) const
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
{
MathRow::Element e(MathRow::INSET, mathClass());
MathRow::Element e(mi, MathRow::INSET, mathClass());
e.inset = this;
mrow.push_back(e);
return true;

View File

@ -85,7 +85,7 @@ public:
Changer chg = make_change(mi.base.macro_nesting,
mathMacro_->nesting() == 1 ? 0 : mathMacro_->nesting());
MathRow::Element e_beg(MathRow::BEG_ARG);
MathRow::Element e_beg(mi, MathRow::BEG_ARG);
e_beg.macro = mathMacro_;
e_beg.ar = &mathMacro_->cell(idx_);
mrow.push_back(e_beg);
@ -98,13 +98,13 @@ public:
// then we insert a box instead.
if (!has_contents && mathMacro_->nesting() == 1) {
// mathclass is ord because it should be spaced as a normal atom
MathRow::Element e(MathRow::BOX, MC_ORD);
MathRow::Element e(mi, MathRow::BOX, MC_ORD);
e.color = Color_mathline;
mrow.push_back(e);
has_contents = true;
}
MathRow::Element e_end(MathRow::END_ARG);
MathRow::Element e_end(mi, MathRow::END_ARG);
e_end.macro = mathMacro_;
e_end.ar = &mathMacro_->cell(idx_);
@ -308,7 +308,7 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
|| d->editing_[mi.base.bv])
return InsetMath::addToMathRow(mrow, mi);
MathRow::Element e_beg(MathRow::BEG_MACRO);
MathRow::Element e_beg(mi, MathRow::BEG_MACRO);
e_beg.macro = this;
mrow.push_back(e_beg);
@ -320,13 +320,13 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
// insert a grey box instead.
if (!has_contents && mi.base.macro_nesting == 1) {
// mathclass is unknown because it is irrelevant for spacing
MathRow::Element e(MathRow::BOX);
MathRow::Element e(mi, MathRow::BOX);
e.color = Color_mathmacroblend;
mrow.push_back(e);
has_contents = true;
}
MathRow::Element e_end(MathRow::END_MACRO);
MathRow::Element e_end(mi, MathRow::END_MACRO);
e_end.macro = this;
mrow.push_back(e_end);

View File

@ -36,16 +36,16 @@ using namespace std;
namespace lyx {
MathRow::Element::Element(Type t, MathClass mc)
: type(t), mclass(mc), before(0), after(0), inset(0),
compl_unique_to(0), macro(0), color(Color_red)
MathRow::Element::Element(MetricsInfo const & mi, Type t, MathClass mc)
: type(t), mclass(mc), before(0), after(0), macro_nesting(mi.base.macro_nesting),
inset(0), compl_unique_to(0), macro(0), color(Color_red)
{}
MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
{
// First there is a dummy element of type "open"
push_back(Element(DUMMY, MC_OPEN));
push_back(Element(mi, DUMMY, MC_OPEN));
// Then insert the MathData argument
bool const has_contents = ar->addToMathRow(*this, mi);
@ -53,13 +53,13 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
// empty arrays are visible when they are editable
// we reserve the necessary space anyway (even if nothing gets drawn)
if (!has_contents) {
Element e(BOX, MC_ORD);
Element e(mi, BOX, MC_ORD);
e.color = mi.base.macro_nesting == 0 ? Color_mathline : Color_none;
push_back(e);
}
// Finally there is a dummy element of type "close"
push_back(Element(DUMMY, MC_CLOSE));
push_back(Element(mi, DUMMY, MC_CLOSE));
/* Do spacing only in math mode. This test is a bit clumsy,
* but it is used in other places for guessing the current mode.
@ -122,12 +122,9 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
// arguments, it is necessary to keep track of them.
map<MathMacro const *, Dimension> dim_macros;
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();
for (Element const & e : elements_) {
mi.base.macro_nesting = macro_nesting.back();
mi.base.macro_nesting = e.macro_nesting;
Dimension d;
switch (e.type) {
case DUMMY:
@ -138,14 +135,12 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
coords.insets().add(e.inset, d);
break;
case BEG_MACRO:
macro_nesting.push_back(e.macro->nesting());
e.macro->macro()->lock();
// Add a macro to current list
dim_macros[e.macro] = Dimension();
break;
case END_MACRO:
LATTEST(dim_macros.find(e.macro) != dim_macros.end());
macro_nesting.pop_back();
e.macro->macro()->unlock();
// Cache the dimension of the macro and remove it from
// tracking map.
@ -154,18 +149,14 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
break;
// This is basically like macros
case BEG_ARG:
if (e.macro) {
macro_nesting.push_back(e.macro->nesting());
if (e.macro)
e.macro->macro()->unlock();
}
dim_arrays[e.ar] = Dimension();
break;
case END_ARG:
LATTEST(dim_arrays.find(e.ar) != dim_arrays.end());
if (e.macro) {
macro_nesting.pop_back();
if (e.macro)
e.macro->macro()->lock();
}
coords.arrays().add(e.ar, dim_arrays[e.ar]);
dim_arrays.erase(e.ar);
break;

View File

@ -59,7 +59,7 @@ public:
struct Element
{
///
Element(Type t, MathClass mc = MC_UNKNOWN);
Element(MetricsInfo const & mi, Type t, MathClass mc = MC_UNKNOWN);
/// Classifies the contents of the object
Type type;
@ -67,6 +67,8 @@ public:
MathClass mclass;
/// the spacing around the element
int before, after;
/// count wether the current mathdata is nested in macro(s)
int macro_nesting;
/// When type is INSET
/// the math inset