mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-27 03:36:39 +00:00
Improve spacing of BOX elements
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).
This commit is contained in:
parent
190d312e35
commit
2acc4fc54c
@ -60,9 +60,8 @@ MathClass InsetMath::mathClass() const
|
|||||||
|
|
||||||
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.inset = this;
|
e.inset = this;
|
||||||
e.mclass = mathClass();
|
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,8 @@ 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 && mathMacro_->nesting() == 1) {
|
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;
|
e.color = Color_mathline;
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
has_contents = true;
|
has_contents = true;
|
||||||
@ -310,6 +311,7 @@ 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) {
|
||||||
|
// mathclass is unknown because it is irrelevant for spacing
|
||||||
MathRow::Element e(MathRow::BOX);
|
MathRow::Element e(MathRow::BOX);
|
||||||
e.color = Color_mathmacroblend;
|
e.color = Color_mathmacroblend;
|
||||||
mrow.push_back(e);
|
mrow.push_back(e);
|
||||||
|
@ -36,8 +36,8 @@ using namespace std;
|
|||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
|
|
||||||
MathRow::Element::Element(Type t)
|
MathRow::Element::Element(Type t, MathClass mc)
|
||||||
: type(t), inset(0), mclass(MC_ORD), before(0), after(0),
|
: 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)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -45,8 +45,7 @@ MathRow::Element::Element(Type t)
|
|||||||
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));
|
push_back(Element(DUMMY, MC_OPEN));
|
||||||
back().mclass = MC_OPEN;
|
|
||||||
|
|
||||||
// Then insert the MathData argument
|
// Then insert the MathData argument
|
||||||
bool const has_contents = ar->addToMathRow(*this, mi);
|
bool const has_contents = ar->addToMathRow(*this, mi);
|
||||||
@ -54,14 +53,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);
|
Element e(BOX, MC_ORD);
|
||||||
e.color = mi.base.macro_nesting == 0 ? Color_mathline : Color_none;
|
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));
|
push_back(Element(DUMMY, 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,
|
||||||
* but it is used in other places for guessing the current mode.
|
* but it is used in other places for guessing the current mode.
|
||||||
@ -71,7 +69,7 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
|||||||
|
|
||||||
// update classes
|
// update classes
|
||||||
for (int i = 1 ; i != static_cast<int>(elements_.size()) - 1 ; ++i) {
|
for (int i = 1 ; i != static_cast<int>(elements_.size()) - 1 ; ++i) {
|
||||||
if (elements_[i].type != INSET)
|
if (elements_[i].mclass == MC_UNKNOWN)
|
||||||
continue;
|
continue;
|
||||||
update_class(elements_[i].mclass, elements_[before(i)].mclass,
|
update_class(elements_[i].mclass, elements_[before(i)].mclass,
|
||||||
elements_[after(i)].mclass);
|
elements_[after(i)].mclass);
|
||||||
@ -80,7 +78,7 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
|
|||||||
// set spacing
|
// set spacing
|
||||||
// We go to the end to handle spacing at the end of equation
|
// We go to the end to handle spacing at the end of equation
|
||||||
for (int i = 1 ; i != static_cast<int>(elements_.size()) ; ++i) {
|
for (int i = 1 ; i != static_cast<int>(elements_.size()) ; ++i) {
|
||||||
if (elements_[i].type != INSET)
|
if (elements_[i].mclass == MC_UNKNOWN)
|
||||||
continue;
|
continue;
|
||||||
Element & bef = elements_[before(i)];
|
Element & bef = elements_[before(i)];
|
||||||
int spc = class_spacing(bef.mclass, elements_[i].mclass, mi.base);
|
int spc = class_spacing(bef.mclass, elements_[i].mclass, mi.base);
|
||||||
@ -100,8 +98,7 @@ int MathRow::before(int i) const
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
--i;
|
--i;
|
||||||
while (elements_[i].type != BEGIN
|
while (elements_[i].mclass == MC_UNKNOWN);
|
||||||
&& elements_[i].type != INSET);
|
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -111,8 +108,7 @@ int MathRow::after(int i) const
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
++i;
|
++i;
|
||||||
while (elements_[i].type != END
|
while (elements_[i].mclass == MC_UNKNOWN);
|
||||||
&& elements_[i].type != INSET);
|
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -134,8 +130,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
mi.base.macro_nesting = macro_nesting.back();
|
mi.base.macro_nesting = macro_nesting.back();
|
||||||
Dimension d;
|
Dimension d;
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case BEGIN:
|
case DUMMY:
|
||||||
case END:
|
|
||||||
break;
|
break;
|
||||||
case INSET:
|
case INSET:
|
||||||
e.inset->metrics(mi, d);
|
e.inset->metrics(mi, d);
|
||||||
@ -239,11 +234,10 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
|
|||||||
if (e.color != Color_none)
|
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 + e.before + e.after;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BEGIN:
|
case DUMMY:
|
||||||
case END:
|
|
||||||
case END_MACRO:
|
case END_MACRO:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -285,11 +279,8 @@ int MathRow::kerning(BufferView const * bv) const
|
|||||||
ostream & operator<<(ostream & os, MathRow::Element const & e)
|
ostream & operator<<(ostream & os, MathRow::Element const & e)
|
||||||
{
|
{
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case MathRow::BEGIN:
|
case MathRow::DUMMY:
|
||||||
os << "{";
|
os << (e.mclass == MC_OPEN ? "{" : "}");
|
||||||
break;
|
|
||||||
case MathRow::END:
|
|
||||||
os << "}";
|
|
||||||
break;
|
break;
|
||||||
case MathRow::INSET:
|
case MathRow::INSET:
|
||||||
os << "<" << e.before << "-"
|
os << "<" << e.before << "-"
|
||||||
@ -310,7 +301,7 @@ ostream & operator<<(ostream & os, MathRow::Element const & e)
|
|||||||
os << ")";
|
os << ")";
|
||||||
break;
|
break;
|
||||||
case MathRow::BOX:
|
case MathRow::BOX:
|
||||||
os << "@";
|
os << "<" << e.before << "-[]-" << e.after << ">";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
|
@ -47,31 +47,30 @@ public:
|
|||||||
// What row elements can be
|
// What row elements can be
|
||||||
enum Type {
|
enum Type {
|
||||||
INSET, // this element is a plain inset
|
INSET, // this element is a plain inset
|
||||||
|
BOX, // an empty box
|
||||||
BEG_MACRO, // a macro begins here
|
BEG_MACRO, // a macro begins here
|
||||||
END_MACRO, // a macro ends here
|
END_MACRO, // a macro ends here
|
||||||
BEG_ARG, // a macro argument begins here
|
BEG_ARG, // a macro argument begins here
|
||||||
END_ARG, // a macro argument ends here
|
END_ARG, // a macro argument ends here
|
||||||
BEGIN, // dummy element before row
|
DUMMY // a dummy element (used before or after row)
|
||||||
END, // dummy element after row
|
|
||||||
BOX // an empty box
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// An elements, together with its spacing
|
// An elements, together with its spacing
|
||||||
struct Element
|
struct Element
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
Element(Type t);
|
Element(Type t, MathClass mc = MC_UNKNOWN);
|
||||||
|
|
||||||
/// Classifies the contents of the object
|
/// Classifies the contents of the object
|
||||||
Type type;
|
Type type;
|
||||||
|
/// the class of the element
|
||||||
|
MathClass mclass;
|
||||||
|
/// the spacing around the element
|
||||||
|
int before, after;
|
||||||
|
|
||||||
/// When type is INSET
|
/// When type is INSET
|
||||||
/// the math inset
|
/// the math inset
|
||||||
InsetMath const * 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
|
// Non empty when there is a completion to draw
|
||||||
docstring compl_text;
|
docstring compl_text;
|
||||||
// the number of characters forming the unique part.
|
// the number of characters forming the unique part.
|
||||||
|
Loading…
Reference in New Issue
Block a user