]> git.lyx.org Git - features.git/commitdiff
Rewrite the code that sets caret height in mathed
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 16 Apr 2019 13:58:51 +0000 (15:58 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 13:48:25 +0000 (15:48 +0200)
Instead of remembering the caret ascent and descent for the cell that contains the cursor, the new code remembers caret dimension for each MathRow object. This makes the code much less fragile (ans slightly smaller).

This fixes caret size issues when the Update::SinglePar flag is active.

Fixes bug #11541.

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

index ba8c768ca4b1d0120eae5a35b54fd45b57b2f2f8..ac6aa6ba76b66e04fc3bb70b2e4eb5e55c69db16 100644 (file)
@@ -239,8 +239,7 @@ struct BufferView::Private
                last_inset_(0), clickable_inset_(false),
                mouse_position_cache_(),
                bookmark_edit_position_(-1), gui_(0),
-               horiz_scroll_offset_(0),
-               caret_ascent_(0), caret_descent_(0)
+               horiz_scroll_offset_(0)
        {
                xsel_cache_.set = false;
        }
@@ -316,12 +315,6 @@ struct BufferView::Private
        /// a slice pointing to the start of the row where the cursor
        /// is (at last draw time)
        CursorSlice current_row_slice_;
-
-       // The vertical size of the blinking caret. Only used for math
-       // Using it for text could be bad when undo restores the cursor
-       // current font, since the caret size could become wrong.
-       int caret_ascent_;
-       int caret_descent_;
 };
 
 
@@ -3013,20 +3006,13 @@ bool BufferView::paragraphVisible(DocIterator const & dit) const
 }
 
 
-void BufferView::setCaretAscentDescent(int asc, int des)
-{
-       d->caret_ascent_ = asc;
-       d->caret_descent_ = des;
-}
-
-
 void BufferView::caretPosAndHeight(Point & p, int & h) const
 {
        int asc, des;
        Cursor const & cur = cursor();
        if (cur.inMathed()) {
-               asc = d->caret_ascent_;
-               des = d->caret_descent_;
+               asc = cur.cell().caretAscent(this);
+               des = cur.cell().caretDescent(this);
        } else {
                Font const font = cur.real_current_font;
                frontend::FontMetrics const & fm = theFontMetrics(font);
index 520ecdb0d571b76b328a7e2c43996fd9125d79f4..0d1a1bba31f1906aa16087e79c9f1d0e35601fcb 100644 (file)
@@ -302,8 +302,6 @@ public:
        bool paragraphVisible(DocIterator const & dit) const;
        /// is the cursor currently visible in the view
        bool cursorInView(Point const & p, int h) const;
-       /// set the ascent and descent of the caret
-       void setCaretAscentDescent(int asc, int des);
        /// get the position and height of the caret
        void caretPosAndHeight(Point & p, int & h) const;
 
index 1c7eaccfa4c73470bd891c2d0a41a1fcf165944f..c3b3faa2395f38731b74031ca11dc9be3929047f 100644 (file)
@@ -267,10 +267,15 @@ bool isInside(DocIterator const & it, MathData const & ar,
 #endif
 
 
-bool MathData::hasCaret(BufferView * bv) const
+int MathData::caretAscent(BufferView const * bv) const
 {
-       Cursor & cur = bv->cursor();
-       return cur.inMathed() && &cur.cell() == this;
+       return mrow_cache_[bv].caret_ascent;
+}
+
+
+int MathData::caretDescent(BufferView const * bv) const
+{
+       return mrow_cache_[bv].caret_descent;
 }
 
 
@@ -288,8 +293,7 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
        sshift_ = xascent / 4;
 
        MathRow mrow(mi, this);
-       bool has_caret = mrow.metrics(mi, dim);
-       mrow_cache_[bv] = mrow;
+       mrow.metrics(mi, dim);
        kerning_ = mrow.kerning(bv);
 
        // Set a minimal ascent/descent for the cell
@@ -304,12 +308,11 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
 
        // This is one of the the few points where the drawing font is known,
        // so that we can set the caret vertical dimensions.
-       has_caret |= hasCaret(bv);
-       if (has_caret)
-               bv->setCaretAscentDescent(min(dim.asc, fm.maxAscent()),
-                                         min(dim.des, fm.maxDescent()));
+       mrow.caret_ascent = min(dim.asc, fm.maxAscent());
+       mrow.caret_descent = min(dim.des, fm.maxDescent());
 
-       // Cache the dimension.
+       // Cache row and dimension.
+       mrow_cache_[bv] = mrow;
        bv->coordCache().arrays().add(this, dim);
 }
 
index 1558000bdc6131865802349d99828dbf157af2dc..0e6c97747fb4f722ff1ec252209e3b2ccfe3d828 100644 (file)
@@ -124,8 +124,10 @@ public:
        /// Add this array to a math row. Return true if contents got added
        bool addToMathRow(MathRow &, MetricsInfo & mi) const;
 
-       // return true if caret is in this cell in this buffer view
-       bool hasCaret(BufferView * bv) 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
@@ -196,7 +198,7 @@ protected:
        Buffer * buffer_;
 
        /// cached object that describes typeset data
-       mutable std::map<BufferView*, MathRow> mrow_cache_;
+       mutable std::map<BufferView const *, MathRow> mrow_cache_;
 
 private:
        /// is this an exact match at this position?
index 472b6db927ad476bdf49605da12f7ba9d2abd2c4..b3a3b340ed1f49ec2ccb531cbd2ad944d786f8ef 100644 (file)
@@ -234,10 +234,8 @@ int MathRow::after(int i) const
 }
 
 
-bool MathRow::metrics(MetricsInfo & mi, Dimension & dim)
+void MathRow::metrics(MetricsInfo & mi, Dimension & dim)
 {
-       bool has_caret = false;
-
        dim.wid = 0;
        // In order to compute the dimension of macros and their
        // arguments, it is necessary to keep track of them.
@@ -262,10 +260,8 @@ bool MathRow::metrics(MetricsInfo & mi, Dimension & dim)
                                d.wid = e.before + e.after;
                                e.inset->beforeMetrics();
                        }
-                       if (e.ar) {
+                       if (e.ar)
                                dim_arrays.push_back(make_pair(e.ar, Dimension()));
-                               has_caret |= e.ar->hasCaret(mi.base.bv);
-                       }
                        break;
                case END:
                        if (e.inset) {
@@ -314,7 +310,6 @@ bool MathRow::metrics(MetricsInfo & mi, Dimension & dim)
                dim.wid += mathed_string_width(font, e.compl_text);
        }
        LATTEST(dim_insets.empty() && dim_arrays.empty());
-       return has_caret;
 }
 
 
index cb4c8614cd38f5993cc31a8821ce5cf501634724..08f56128dea095974f68baf253aec8eec2a8c0eb 100644 (file)
@@ -86,7 +86,7 @@ public:
        };
 
        ///
-       MathRow() {};
+       MathRow() : caret_ascent(0), caret_descent(0) {};
        ///
        typedef std::vector<Element> Elements;
        ///
@@ -110,14 +110,18 @@ public:
        // compute the spacings.
        MathRow(MetricsInfo & mi, MathData const * ar);
 
-       // this returns true if the caret is here
-       bool metrics(MetricsInfo & mi, Dimension & dim);
+       //
+       void metrics(MetricsInfo & mi, Dimension & dim);
        //
        void draw(PainterInfo & pi, int const x, int const y) const;
 
        /// superscript kerning
        int kerning(BufferView const *) const;
 
+       /// useful when the caret visits this cell
+       int caret_ascent, caret_descent;
+
+
 private:
        // Index of the first inset element before position i
        int before(int i) const;