Set caret height correctly for cells inside math rows

The code in 90cfe4ec3 only handled the cells which metrics are
computed directly, and missed those who were linearized inside a MathRow.

To fix this, we use the fact that all the positions in a math row have
the same height and make MathRow::metrics return a boolean indicating
whether it contains a caret for a given bufferview.

Fixes bug #11153.
This commit is contained in:
Jean-Marc Lasgouttes 2018-05-24 11:10:25 +02:00
parent 429edc0a59
commit a3868e40a4
4 changed files with 22 additions and 7 deletions

View File

@ -259,6 +259,13 @@ bool isInside(DocIterator const & it, MathData const & ar,
#endif #endif
bool MathData::hasCaret(BufferView * bv) const
{
Cursor & cur = bv->cursor();
return cur.inMathed() && &cur.cell() == this;
}
void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
{ {
frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
@ -273,7 +280,7 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
sshift_ = xascent / 4; sshift_ = xascent / 4;
MathRow mrow(mi, this); MathRow mrow(mi, this);
mrow.metrics(mi, dim); bool has_caret = mrow.metrics(mi, dim);
mrow_cache_[bv] = mrow; mrow_cache_[bv] = mrow;
kerning_ = mrow.kerning(bv); kerning_ = mrow.kerning(bv);
@ -289,8 +296,8 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim, bool tight) const
// This is one of the the few points where the drawing font is known, // This is one of the the few points where the drawing font is known,
// so that we can set the caret vertical dimensions. // so that we can set the caret vertical dimensions.
Cursor & cur = bv->cursor(); has_caret |= hasCaret(bv);
if (cur.inMathed() && &cur.cell() == this) if (has_caret)
bv->setCaretAscentDescent(min(dim.asc, fm.maxAscent()), bv->setCaretAscentDescent(min(dim.asc, fm.maxAscent()),
min(dim.des, fm.maxDescent())); min(dim.des, fm.maxDescent()));

View File

@ -124,6 +124,9 @@ public:
/// Add this array to a math row. Return true if contents got added /// Add this array to a math row. Return true if contents got added
bool addToMathRow(MathRow &, MetricsInfo & mi) const; bool addToMathRow(MathRow &, MetricsInfo & mi) const;
// return true if caret is in this cell in this buffer view
bool hasCaret(BufferView * bv) const;
/// rebuild cached metrics information /// rebuild cached metrics information
/** When \c tight is true, the height of the cell will be at least /** When \c tight is true, the height of the cell will be at least
* that of 'x'. Otherwise, it will be the max height of the font. * that of 'x'. Otherwise, it will be the max height of the font.

View File

@ -234,8 +234,10 @@ int MathRow::after(int i) const
} }
void MathRow::metrics(MetricsInfo & mi, Dimension & dim) bool MathRow::metrics(MetricsInfo & mi, Dimension & dim)
{ {
bool has_caret = false;
dim.wid = 0; dim.wid = 0;
// In order to compute the dimension of macros and their // In order to compute the dimension of macros and their
// arguments, it is necessary to keep track of them. // arguments, it is necessary to keep track of them.
@ -260,8 +262,10 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim)
d.wid = e.before + e.after; d.wid = e.before + e.after;
e.inset->beforeMetrics(); e.inset->beforeMetrics();
} }
if (e.ar) if (e.ar) {
dim_arrays.push_back(make_pair(e.ar, Dimension())); dim_arrays.push_back(make_pair(e.ar, Dimension()));
has_caret |= e.ar->hasCaret(mi.base.bv);
}
break; break;
case END: case END:
if (e.inset) { if (e.inset) {
@ -310,6 +314,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim)
dim.wid += mathed_string_width(font, e.compl_text); dim.wid += mathed_string_width(font, e.compl_text);
} }
LATTEST(dim_insets.empty() && dim_arrays.empty()); LATTEST(dim_insets.empty() && dim_arrays.empty());
return has_caret;
} }

View File

@ -110,8 +110,8 @@ public:
// compute the spacings. // compute the spacings.
MathRow(MetricsInfo & mi, MathData const * ar); MathRow(MetricsInfo & mi, MathData const * ar);
// // this returns true if the caret is here
void metrics(MetricsInfo & mi, Dimension & dim); bool metrics(MetricsInfo & mi, Dimension & dim);
// //
void draw(PainterInfo & pi, int const x, int const y) const; void draw(PainterInfo & pi, int const x, int const y) const;