Tweak the algorithm so that a BOX math row element can have some
spacing. To this end, MathRow::before/after do not look at the type of
an element for deciding when to skip it, but rather to its math class.
In the new setting, the spacing algorithm works on all elements, but
skips the MC_UNKNOWN elements as if they were not present. As a
consequence, the two element types BEGIN and END have been replaced by
a single DUMMY (they can be recognized from their class).
To simply the code, add a new `mclass' argument to the
MathRow::Element constructor (default is MC_UNKNOWN).
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & ) const
{
bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & ) const
{
- MathRow::Element e(MathRow::INSET);
+ MathRow::Element e(MathRow::INSET, mathClass());
- e.mclass = mathClass();
mrow.push_back(e);
return true;
}
mrow.push_back(e);
return true;
}
// if there was no contents, and the contents is editable,
// then we insert a box instead.
if (!has_contents && mathMacro_->nesting() == 1) {
// if there was no contents, and the contents is editable,
// then we insert a box instead.
if (!has_contents && mathMacro_->nesting() == 1) {
- MathRow::Element e(MathRow::BOX);
+ // mathclass is ord because it should be spaced as a normal atom
+ MathRow::Element e(MathRow::BOX, MC_ORD);
e.color = Color_mathline;
mrow.push_back(e);
has_contents = true;
e.color = Color_mathline;
mrow.push_back(e);
has_contents = true;
// if there was no contents and the array is editable, then we
// insert a grey box instead.
if (!has_contents && mi.base.macro_nesting == 1) {
// if there was no contents and the array is editable, then we
// 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);
e.color = Color_mathmacroblend;
mrow.push_back(e);
MathRow::Element e(MathRow::BOX);
e.color = Color_mathmacroblend;
mrow.push_back(e);
-MathRow::Element::Element(Type t)
- : type(t), inset(0), mclass(MC_ORD), before(0), after(0),
+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)
{}
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"
MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
{
// First there is a dummy element of type "open"
- push_back(Element(BEGIN));
- back().mclass = MC_OPEN;
+ push_back(Element(DUMMY, MC_OPEN));
// Then insert the MathData argument
bool const has_contents = ar->addToMathRow(*this, mi);
// Then insert the MathData argument
bool const has_contents = ar->addToMathRow(*this, mi);
// empty arrays are visible when they are editable
// we reserve the necessary space anyway (even if nothing gets drawn)
if (!has_contents) {
// 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);
e.color = mi.base.macro_nesting == 0 ? Color_mathline : Color_none;
push_back(e);
}
// Finally there is a dummy element of type "close"
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(END));
- back().mclass = MC_CLOSE;
+ push_back(Element(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.
/* Do spacing only in math mode. This test is a bit clumsy,
* but it is used in other places for guessing the current mode.
// update classes
for (int i = 1 ; i != static_cast<int>(elements_.size()) - 1 ; ++i) {
// update classes
for (int i = 1 ; i != static_cast<int>(elements_.size()) - 1 ; ++i) {
- if (elements_[i].type != INSET)
+ if (elements_[i].mclass == MC_UNKNOWN)
continue;
update_class(elements_[i].mclass, elements_[before(i)].mclass,
elements_[after(i)].mclass);
continue;
update_class(elements_[i].mclass, elements_[before(i)].mclass,
elements_[after(i)].mclass);
// set spacing
// We go to the end to handle spacing at the end of equation
for (int i = 1 ; i != static_cast<int>(elements_.size()) ; ++i) {
// set spacing
// We go to the end to handle spacing at the end of equation
for (int i = 1 ; i != static_cast<int>(elements_.size()) ; ++i) {
- if (elements_[i].type != INSET)
+ if (elements_[i].mclass == MC_UNKNOWN)
continue;
Element & bef = elements_[before(i)];
int spc = class_spacing(bef.mclass, elements_[i].mclass, mi.base);
continue;
Element & bef = elements_[before(i)];
int spc = class_spacing(bef.mclass, elements_[i].mclass, mi.base);
- while (elements_[i].type != BEGIN
- && elements_[i].type != INSET);
+ while (elements_[i].mclass == MC_UNKNOWN);
- while (elements_[i].type != END
- && elements_[i].type != INSET);
+ while (elements_[i].mclass == MC_UNKNOWN);
mi.base.macro_nesting = macro_nesting.back();
Dimension d;
switch (e.type) {
mi.base.macro_nesting = macro_nesting.back();
Dimension d;
switch (e.type) {
- case BEGIN:
- case END:
break;
case INSET:
e.inset->metrics(mi, d);
break;
case INSET:
e.inset->metrics(mi, d);
if (e.color != Color_none)
pi.pain.rectangle(x + e.before, y - d.ascent(),
d.width(), d.height(), e.color);
if (e.color != Color_none)
pi.pain.rectangle(x + e.before, y - d.ascent(),
d.width(), d.height(), e.color);
+ x += d.wid + e.before + e.after;
- case BEGIN:
- case END:
ostream & operator<<(ostream & os, MathRow::Element const & e)
{
switch (e.type) {
ostream & operator<<(ostream & os, MathRow::Element const & e)
{
switch (e.type) {
- case MathRow::BEGIN:
- os << "{";
- break;
- case MathRow::END:
- os << "}";
+ case MathRow::DUMMY:
+ os << (e.mclass == MC_OPEN ? "{" : "}");
break;
case MathRow::INSET:
os << "<" << e.before << "-"
break;
case MathRow::INSET:
os << "<" << e.before << "-"
os << ")";
break;
case MathRow::BOX:
os << ")";
break;
case MathRow::BOX:
+ os << "<" << e.before << "-[]-" << e.after << ">";
// What row elements can be
enum Type {
INSET, // this element is a plain inset
// What row elements can be
enum Type {
INSET, // this element is a plain inset
BEG_MACRO, // a macro begins here
END_MACRO, // a macro ends here
BEG_ARG, // a macro argument begins here
END_ARG, // a macro argument ends here
BEG_MACRO, // a macro begins here
END_MACRO, // a macro ends here
BEG_ARG, // a macro argument begins here
END_ARG, // a macro argument ends here
- BEGIN, // dummy element before row
- END, // dummy element after row
- BOX // an empty box
+ DUMMY // a dummy element (used before or after row)
};
// An elements, together with its spacing
struct Element
{
///
};
// An elements, together with its spacing
struct Element
{
///
+ Element(Type t, MathClass mc = MC_UNKNOWN);
/// Classifies the contents of the object
Type type;
/// Classifies the contents of the object
Type type;
+ /// the class of the element
+ MathClass mclass;
+ /// the spacing around the element
+ int before, after;
/// When type is INSET
/// the math inset
InsetMath const * inset;
/// When type is INSET
/// the math inset
InsetMath const * inset;
- /// the class of the inset
- MathClass mclass;
- /// the spacing around the inset
- int before, after;
// Non empty when there is a completion to draw
docstring compl_text;
// the number of characters forming the unique part.
// Non empty when there is a completion to draw
docstring compl_text;
// the number of characters forming the unique part.