]> git.lyx.org Git - features.git/commitdiff
Make caret visible inside math macros arguments
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 3 Jun 2019 14:22:44 +0000 (16:22 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 13:48:32 +0000 (15:48 +0200)
The first step is to move the MathRow cache to BufferView, alongside
coordCache. This was on the todo list anyway, since it allows to let
go the math row information when the math equation is not on the
screen anymore. With the old scheme, it would always remain in memory.

Then, when computing caret size in MathData::metrics, make sure that
the mathrow of the elements that are linearized in the MathRow object
get their caret size information initialized too.

Fixes bug #11587.

src/BufferView.cpp
src/BufferView.h
src/mathed/MathData.cpp
src/mathed/MathData.h
src/mathed/MathRow.h

index ac6aa6ba76b66e04fc3bb70b2e4eb5e55c69db16..2068f050cfeddf283516763aecc57adab3c6a8e6 100644 (file)
@@ -252,6 +252,9 @@ struct BufferView::Private
        Update::flags update_flags_;
        ///
        CoordCache coord_cache_;
+       ///
+       typedef map<MathData const *, MathRow> MathRows;
+       MathRows math_rows_;
 
        /// Estimated average par height for scrollbar.
        int wh_;
@@ -430,6 +433,20 @@ CoordCache const & BufferView::coordCache() const
 }
 
 
+MathRow const & BufferView::mathRow(MathData const * cell) const
+{
+       auto it = d->math_rows_.find(cell);
+       LATTEST(it != d->math_rows_.end());
+       return it->second;
+}
+
+
+void BufferView::setMathRow(MathData const * cell, MathRow const & mrow)
+{
+       d->math_rows_[cell] = mrow;
+}
+
+
 Buffer & BufferView::buffer()
 {
        return buffer_;
@@ -2771,6 +2788,7 @@ void BufferView::updateMetrics(Update::flags & update_flags)
 
        // Clear out the position cache in case of full screen redraw,
        d->coord_cache_.clear();
+       d->math_rows_.clear();
 
        // Clear out paragraph metrics to avoid having invalid metrics
        // in the cache from paragraphs not relayouted below
@@ -3011,8 +3029,9 @@ void BufferView::caretPosAndHeight(Point & p, int & h) const
        int asc, des;
        Cursor const & cur = cursor();
        if (cur.inMathed()) {
-               asc = cur.cell().caretAscent(this);
-               des = cur.cell().caretDescent(this);
+               MathRow const & mrow = mathRow(&cur.cell());
+               asc = mrow.caret_ascent;
+               des = mrow.caret_descent;
        } else {
                Font const font = cur.real_current_font;
                frontend::FontMetrics const & fm = theFontMetrics(font);
index 0d1a1bba31f1906aa16087e79c9f1d0e35601fcb..45928f256ee44f720b28282eef1057d3cd248eaf 100644 (file)
@@ -42,6 +42,8 @@ class FuncStatus;
 class Intl;
 class Inset;
 class Length;
+class MathData;
+class MathRow;
 class ParIterator;
 class ParagraphMetrics;
 class Point;
@@ -296,6 +298,11 @@ public:
        ///
        CoordCache const & coordCache() const;
 
+       ///
+       MathRow const & mathRow(MathData const * cell) const;
+       ///
+       void setMathRow(MathData const * cell, MathRow const & mrow);
+
        ///
        Point getPos(DocIterator const & dit) const;
        /// is the paragraph of the cursor visible ?
index c3b3faa2395f38731b74031ca11dc9be3929047f..0676dc732a7b72490c428331f12ec669f4931a93 100644 (file)
@@ -267,18 +267,6 @@ bool isInside(DocIterator const & it, MathData const & ar,
 #endif
 
 
-int MathData::caretAscent(BufferView const * bv) const
-{
-       return mrow_cache_[bv].caret_ascent;
-}
-
-
-int MathData::caretDescent(BufferView const * bv) const
-{
-       return mrow_cache_[bv].caret_descent;
-}
-
-
 void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
 {
        frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
@@ -310,9 +298,14 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
        // so that we can set the caret vertical dimensions.
        mrow.caret_ascent = min(dim.asc, fm.maxAscent());
        mrow.caret_descent = min(dim.des, fm.maxDescent());
+       /// do the same for math cells linearized in the row
+       MathRow caret_row = MathRow(mrow.caret_ascent, mrow.caret_descent);
+       for (auto const & e : mrow)
+               if (e.type == MathRow::BEGIN && e.ar)
+                       bv->setMathRow(e.ar, caret_row);
 
        // Cache row and dimension.
-       mrow_cache_[bv] = mrow;
+       bv->setMathRow(this, mrow);
        bv->coordCache().arrays().add(this, dim);
 }
 
@@ -357,7 +350,7 @@ void MathData::draw(PainterInfo & pi, int const x, int const y) const
        setXY(*pi.base.bv, x, y);
 
        drawSelection(pi, x, y);
-       MathRow const & mrow = mrow_cache_[pi.base.bv];
+       MathRow const & mrow = pi.base.bv->mathRow(this);
        mrow.draw(pi, x, y);
 }
 
index 0e6c97747fb4f722ff1ec252209e3b2ccfe3d828..b118d6c41f2d412cae1fa22c3054196bb108dc4f 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <cstddef>
 #include <vector>
-#include <map>
 
 
 namespace lyx {
@@ -124,11 +123,6 @@ public:
        /// Add this array to a math row. Return true if contents got added
        bool addToMathRow(MathRow &, MetricsInfo & mi) const;
 
-       // ascent of caret in this cell
-       int caretAscent(BufferView const * bv) const;
-       /// descent of caret in this cell
-       int caretDescent(BufferView const * bv) const;
-
        /// rebuild cached metrics information
        /** When \c tight is true, the height of the cell will be at least
         *  the x height of the font. Otherwise, it will be the max height
@@ -197,9 +191,6 @@ protected:
        mutable int kerning_;
        Buffer * buffer_;
 
-       /// cached object that describes typeset data
-       mutable std::map<BufferView const *, MathRow> mrow_cache_;
-
 private:
        /// is this an exact match at this position?
        bool find1(MathData const & ar, size_type pos) const;
index 08f56128dea095974f68baf253aec8eec2a8c0eb..e009b90d567979385a082a0caddda7367402bd98 100644 (file)
@@ -86,7 +86,7 @@ public:
        };
 
        ///
-       MathRow() : caret_ascent(0), caret_descent(0) {};
+       MathRow(int asc = 0, int des = 0) : caret_ascent(asc), caret_descent(des) {};
        ///
        typedef std::vector<Element> Elements;
        ///