Hi!

While debugging some display oddities of math macros in connection to multiple bufferviews, I came across the atom_dim_ array in MathData. This caches the dimensions of the atoms as the name suggests, and later uses this data also for other things like cursor positioning.

At least if atoms have different sizes in different BufferViews the atoms might "jump around" sometimes. This is caused by invalid atom_dims_ values because the current view does not get new metrics (it's only drawn), but the other views do get them. Hence the current view drawing might depend on atom_dims_ of another view.

Below is a patch to change this by making it dependent on the buffer view.

Any comments?

Stefan

diff --git a/src/mathed/InsetMathFrac.cpp b/src/mathed/InsetMathFrac.cpp
index ff05962..a30f0bb 100644
--- a/src/mathed/InsetMathFrac.cpp
+++ b/src/mathed/InsetMathFrac.cpp
@@ -45,7 +45,7 @@ bool InsetMathFracBase::idxUpDown(Cursor & cur, bool up) const
        if (cur.idx() == target)
                return false;
        cur.idx() = target;
-       cur.pos() = cell(target).x2pos(cur.x_target());
+       cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
        return true;
 }

@@ -94,7 +94,7 @@ bool InsetMathFrac::idxForward(Cursor & cur) const
        if (cur.idx() == target)
                return false;
        cur.idx() = target;
-       cur.pos() = cell(target).x2pos(cur.x_target());
+       cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
        return true;
 }

@@ -112,7 +112,7 @@ bool InsetMathFrac::idxBackward(Cursor & cur) const
        if (cur.idx() == target)
                return false;
        cur.idx() = target;
-       cur.pos() = cell(target).x2pos(cur.x_target());
+       cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
        return true;
 }

diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp
index cc54239..214ca7e 100644
--- a/src/mathed/InsetMathGrid.cpp
+++ b/src/mathed/InsetMathGrid.cpp
@@ -813,7 +813,7 @@ bool InsetMathGrid::idxUpDown(Cursor & cur, bool up) const
                        return false;
                cur.idx() += ncols();
        }
- cur.pos() = cur.cell().x2pos(cur.x_target() - cur.cell().xo(cur.bv())); + cur.pos() = cur.cell().x2pos(&cur.bv(), cur.x_target() - cur.cell().xo(cur.bv()));
        return true;
 }

diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp
index 00d4e2a..77c3c82 100644
--- a/src/mathed/InsetMathNest.cpp
+++ b/src/mathed/InsetMathNest.cpp
@@ -131,7 +131,7 @@ void InsetMathNest::cursorPos(BufferView const & bv,
        Point const pt2 = coord_cache.getInsets().xy(this);
        //lyxerr << "retrieving position cache for MathData "
        //      << pt.x_ << ' ' << pt.y_ << endl;
-       x = pt.x_ - pt2.x_ + ar.pos2x(sl.pos());
+       x = pt.x_ - pt2.x_ + ar.pos2x(&bv, sl.pos());
        y = pt.y_ - pt2.y_;
 //     lyxerr << "pt.y_ : " << pt.y_ << " pt2_.y_ : " << pt2.y_
 //             << " asc: " << ascent() << "  des: " << descent()
@@ -257,9 +257,9 @@ void InsetMathNest::drawSelection(PainterInfo & pi, int x, int y) const
        if (s1.idx() == s2.idx()) {
                MathData const & c = cell(s1.idx());
                Geometry const & g = bv.coordCache().getArrays().geometry(&c);
-               int x1 = g.pos.x_ + c.pos2x(s1.pos());
+               int x1 = g.pos.x_ + c.pos2x(pi.base.bv, s1.pos());
                int y1 = g.pos.y_ - g.dim.ascent();
-               int x2 = g.pos.x_ + c.pos2x(s2.pos());
+               int x2 = g.pos.x_ + c.pos2x(pi.base.bv, s2.pos());
                int y2 = g.pos.y_ + g.dim.descent();
                pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, 
Color_selection);
        //lyxerr << "InsetMathNest::drawing selection 3: "
@@ -1231,7 +1231,7 @@ Inset * InsetMathNest::editXY(Cursor & cur, int x, int y)
        MathData & ar = cell(idx_min);
        cur.push(*this);
        cur.idx() = idx_min;
-       cur.pos() = ar.x2pos(x - ar.xo(cur.bv()));
+       cur.pos() = ar.x2pos(&cur.bv(), x - ar.xo(cur.bv()));

//lyxerr << "found cell : " << idx_min << " pos: " << cur.pos() << endl;
        if (dist_min == 0) {
diff --git a/src/mathed/InsetMathUnderset.cpp b/src/mathed/ InsetMathUnderset.cpp
index d342604..b6200e1 100644
--- a/src/mathed/InsetMathUnderset.cpp
+++ b/src/mathed/InsetMathUnderset.cpp
@@ -79,7 +79,7 @@ bool InsetMathUnderset::idxUpDown(Cursor & cur, bool up) const
        if (cur.idx() == target)
                return false;
        cur.idx() = target;
-       cur.pos() = cur.cell().x2pos(cur.x_target());
+       cur.pos() = cur.cell().x2pos(&cur.bv(), cur.x_target());
        return true;
 }

diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index e579ece..9944d6d 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -253,11 +253,11 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const
        dim.asc = 0;
        dim.wid = 0;
        Dimension d;
-       atom_dims_.clear();
+       atom_dims_[mi.base.bv].clear();
        for (size_t i = 0, n = size(); i != n; ++i) {
                MathAtom const & at = operator[](i);
                at->metrics(mi, d);
-               atom_dims_.push_back(d);
+               atom_dims_[mi.base.bv].push_back(d);
                dim += d;
                if (i == n - 1)
                        kerning_ = at->kerning(mi.base.bv);
@@ -292,7 +292,7 @@ void MathData::draw(PainterInfo & pi, int x, int y) const
                bv.coordCache().insets().add(at.nucleus(), x, y);
                at->drawSelection(pi, x, y);
                at->draw(pi, x, y);
-               x += atom_dims_[i].wid;
+               x += atom_dims_[pi.base.bv][i].wid;
        }
 }

@@ -733,13 +733,13 @@ void MathData::collectParameters(Cursor * cur,
 }


-int MathData::pos2x(size_type pos) const
+int MathData::pos2x(BufferView const * bv, size_type pos) const
 {
-       return pos2x(pos, 0);
+       return pos2x(bv, pos, 0);
 }


-int MathData::pos2x(size_type pos, int glue) const
+int MathData::pos2x(BufferView const * bv, size_type pos, int glue) const
 {
        int x = 0;
        size_type target = min(pos, size());
@@ -749,19 +749,19 @@ int MathData::pos2x(size_type pos, int glue) const
                        x += glue;
                //lyxerr << "char: " << (*it)->getChar()
                //      << "width: " << (*it)->width() << endl;
-               x += atom_dims_[i].wid;
+               x += atom_dims_[bv][i].wid;
        }
        return x;
 }


-MathData::size_type MathData::x2pos(int targetx) const
+MathData::size_type MathData::x2pos(BufferView const * bv, int targetx) const
 {
-       return x2pos(targetx, 0);
+       return x2pos(bv, targetx, 0);
 }


-MathData::size_type MathData::x2pos(int targetx, int glue) const
+MathData::size_type MathData::x2pos(BufferView const * bv, int targetx, int glue) const
 {
        const_iterator it = begin();
        int lastx = 0;
@@ -771,7 +771,7 @@ MathData::size_type MathData::x2pos(int targetx, int glue) const
                lastx = currx;
                if ((*it)->getChar() == ' ')
                        currx += glue;
-               currx += atom_dims_[it - begin()].wid;
+               currx += atom_dims_[bv][it - begin()].wid;
        }

        /**
diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h
index c0388aa..ed7edb1 100644
--- a/src/mathed/MathData.h
+++ b/src/mathed/MathData.h
@@ -21,6 +21,7 @@
 #include "support/strfwd.h"

 #include <vector>
+#include <map>


 namespace lyx {
@@ -132,13 +133,13 @@ public:
        /// write access to coordinate;
        void setXY(BufferView & bv, int x, int y) const;
        /// returns x coordinate of given position in the array
-       int pos2x(size_type pos) const;
+       int pos2x(BufferView const * bv, size_type pos) const;
        /// returns position of given x coordinate
-       int pos2x(size_type pos, int glue) const;
+       int pos2x(BufferView const * bv, size_type pos, int glue) const;
        /// returns position of given x coordinate
-       size_type x2pos(int pos) const;
+       size_type x2pos(BufferView const * bv, int pos) const;
/// returns position of given x coordinate fstarting from a certain pos
-       size_type x2pos(int targetx, int glue) const;
+       size_type x2pos(BufferView const * bv, int targetx, int glue) const;
        /// returns distance of this cell to the point given by x and y
        // assumes valid position and size cache
        int dist(BufferView const & bv, int x, int y) const;
@@ -188,7 +189,7 @@ private:
                size_t & pos, MathAtom & scriptToPutAround,
                const pos_type macroPos, const int thisPos, const int 
thisSlice);
        ///
-       mutable std::vector<Dimension> atom_dims_;
+ mutable std::map<BufferView const *, std::vector<Dimension> > atom_dims_;
 };

 ///

Reply via email to