Le 27/04/2018 à 00:13, Jean-Marc Lasgouttes a écrit :
commit 90cfe4ec3b4ff22ef798a63e98ca70d0d33a1656
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Fri Apr 27 00:03:48 2018 +0200

     Adapt caret height to context in mathed.
Compute a height from current font and current cell vertical
     dimensions in MathData::metrics(), because this is where current font
     is known.
Introduce BufferView::setCaretAscentDescent to remember this value. This mechanism is not used for text because Cursor::current_font is
     restored by undo, and the caret height would not be changed then. But
     in principle it is doable.

Pavel, please test this new code. It should get the cursor size right without crashing of changing bizarrely the current font.

Riki, if this works, I will probably propose to backport to 2.3.2.

JMarc

---
  src/BufferView.cpp      |   33 +++++++++++++++++++++++++++------
  src/BufferView.h        |    2 ++
  src/mathed/MathData.cpp |   14 +++++++++++---
  3 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 8e49f3f..ed559b1 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -230,7 +230,8 @@ enum ScreenUpdateStrategy {
struct BufferView::Private
  {
-       Private(BufferView & bv) : update_strategy_(FullScreenUpdate),
+       Private(BufferView & bv) :
+               update_strategy_(FullScreenUpdate),
                update_flags_(Update::Force),
                wh_(0), cursor_(bv),
                anchor_pit_(0), anchor_ypos_(0),
@@ -238,7 +239,8 @@ struct BufferView::Private
                last_inset_(0), clickable_inset_(false),
                mouse_position_cache_(),
                bookmark_edit_position_(-1), gui_(0),
-               horiz_scroll_offset_(0)
+               horiz_scroll_offset_(0),
+               caret_ascent_(0), caret_descent_(0)
        {
                xsel_cache_.set = false;
        }
@@ -317,6 +319,12 @@ struct BufferView::Private
        /// a slice pointing to the start of the row where cursor was
        /// at previous draw event
        CursorSlice last_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_;
  };
@@ -2982,13 +2990,26 @@ 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();
-       Font const font = cur.real_current_font;
-       frontend::FontMetrics const & fm = theFontMetrics(font);
-       int const asc = fm.maxAscent();
-       int const des = fm.maxDescent();
+       if (cur.inMathed()) {
+               asc = d->caret_ascent_;
+               des = d->caret_descent_;
+       } else {
+               Font const font = cur.real_current_font;
+               frontend::FontMetrics const & fm = theFontMetrics(font);
+               asc = fm.maxAscent();
+               des = fm.maxDescent();
+       }
        h = asc + des;
        p = getPos(cur);
        p.y_ -= asc;
diff --git a/src/BufferView.h b/src/BufferView.h
index 0381b6b..2478e60 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -307,6 +307,8 @@ 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;
diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 719065d..482d506 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -262,6 +262,7 @@ bool isInside(DocIterator const & it, MathData const & ar,
  void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
  {
        frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
+       BufferView * bv = mi.base.bv;
        int const Iascent = fm.dimension('I').ascent();
        int xascent = fm.dimension('x').ascent();
        if (xascent >= Iascent)
@@ -273,8 +274,8 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, 
bool tight) const
MathRow mrow(mi, this);
        mrow.metrics(mi, dim);
-       mrow_cache_[mi.base.bv] = mrow;
-       kerning_ = mrow.kerning(mi.base.bv);
+       mrow_cache_[bv] = mrow;
+       kerning_ = mrow.kerning(bv);
// Set a minimal ascent/descent for the cell
        if (tight)
@@ -286,8 +287,15 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, 
bool tight) const
                dim.des = max(dim.des, fm.maxDescent());
        }
+ // This is one of the the few points where the drawing font is known,
+       // so that we can set the caret vertical dimensions.
+       Cursor & cur = bv->cursor();
+       if (cur.inMathed() && &cur.cell() == this)
+               bv->setCaretAscentDescent(min(dim.asc, fm.maxAscent()),
+                                         min(dim.des, fm.maxDescent()));
+
        // Cache the dimension.
-       mi.base.bv->coordCache().arrays().add(this, dim);
+       bv->coordCache().arrays().add(this, dim);
  }

Reply via email to