]> git.lyx.org Git - lyx.git/commitdiff
Improve spacing of BOX elements
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 2 Dec 2016 14:58:39 +0000 (15:58 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 2 Dec 2016 15:14:12 +0000 (16:14 +0100)
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).

src/mathed/InsetMath.cpp
src/mathed/MathMacro.cpp
src/mathed/MathRow.cpp
src/mathed/MathRow.h

index e22adb686df688ef79144a5fbc6ea874f135de6f..ba559e7eb6b4888080cc140c303526125602a65a 100644 (file)
@@ -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);
        return true;
 }
        mrow.push_back(e);
        return true;
 }
index 0a47aa2e9fd4731b43225e0fa82b99471155ec8c..104d1199139746806918d9939b98013f348a39e5 100644 (file)
@@ -96,7 +96,8 @@ public:
                // 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;
@@ -310,6 +311,7 @@ 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.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);
index b8132fae06ea2aec05c9edfa6451a38d57e17d17..703d25e60f7e74d6ad3206fc54834d5dbff364f0 100644 (file)
@@ -36,8 +36,8 @@ using namespace std;
 namespace lyx {
 
 
 namespace lyx {
 
 
-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)
 {}
 
@@ -45,8 +45,7 @@ MathRow::Element::Element(Type t)
 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);
@@ -54,14 +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) {
        // 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);
+               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.
@@ -71,7 +69,7 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
 
        // 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);
@@ -80,7 +78,7 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar)
        // 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);
@@ -100,8 +98,7 @@ int MathRow::before(int i) const
 {
        do
                --i;
 {
        do
                --i;
-       while (elements_[i].type != BEGIN
-                  && elements_[i].type != INSET);
+       while (elements_[i].mclass == MC_UNKNOWN);
 
        return i;
 }
 
        return i;
 }
@@ -111,8 +108,7 @@ int MathRow::after(int i) const
 {
        do
                ++i;
 {
        do
                ++i;
-       while (elements_[i].type != END
-                  && elements_[i].type != INSET);
+       while (elements_[i].mclass == MC_UNKNOWN);
 
        return i;
 }
 
        return i;
 }
@@ -134,8 +130,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const
                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:
+               case DUMMY:
                        break;
                case INSET:
                        e.inset->metrics(mi, d);
                        break;
                case INSET:
                        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)
                                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;
+                       x += d.wid + e.before + e.after;
                        break;
                }
                        break;
                }
-               case BEGIN:
-               case END:
+               case DUMMY:
                case END_MACRO:
                        break;
                }
                case END_MACRO:
                        break;
                }
@@ -285,11 +279,8 @@ int MathRow::kerning(BufferView const * bv) const
 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 << "-"
@@ -310,7 +301,7 @@ ostream & operator<<(ostream & os, MathRow::Element const & e)
                os << ")";
                break;
        case MathRow::BOX:
                os << ")";
                break;
        case MathRow::BOX:
-               os << "@";
+               os << "<" << e.before << "-[]-" << e.after << ">";
                break;
        }
        return os;
                break;
        }
        return os;
index 95786b23b4e398768fae2800797fac8d54e48169..f7f156c135ecc5b1e5646df135a89e15a413fc3d 100644 (file)
@@ -47,31 +47,30 @@ public:
        // 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
+               BOX, // an empty box
                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);
+               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.