(almost) Proper fix for caret droppings

Try to find the most inner row that is overwritten by the caret. This
allows to replace the hack in TextMetrics::draw, which did not really
work.

Note that there are still issues with emphasized caret at the
beginning of inset, which will require some code reorganisation.

Fixes current recipe of bug #12024.
This commit is contained in:
Jean-Marc Lasgouttes 2020-11-21 20:00:26 +01:00
parent d53b44273c
commit 7a28258d32
2 changed files with 19 additions and 12 deletions

View File

@ -3295,8 +3295,23 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret)
* move at all
*/
if (paint_caret) {
Row const & caret_row = d->cursor_.textRow();
caret_row.changed(true);
Cursor cur(d->cursor_);
Point p;
Dimension dim;
caretPosAndDim(p, dim);
while (cur.depth() > 1) {
if (cur.inTexted()) {
TextMetrics const & tm = textMetrics(cur.text());
if (p.x_ >= tm.origin().x_
&& p.x_ + dim.width() <= tm.origin().x_ + tm.dim().width())
break;
} else {
// in mathed
break;
}
cur.pop();
}
cur.textRow().changed(true);
}
}

View File

@ -1918,16 +1918,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
LYXERR(Debug::PAINTING, "Clear rect@("
<< max(row_x, 0) << ", " << y - row.ascent() << ")="
<< width() << " x " << row.height());
// FIXME: this is a hack. We clear an amount equal to
// cursor width. This will not work if the caret has a
// ridiculous width like 6. (see ticket #10797)
// This is the same formula as in GuiWorkArea.
int const caret_width = lyxrc.cursor_width
? lyxrc.cursor_width
: 1 + int((lyxrc.currentZoom + 50) / 200.0);
pi.pain.fillRectangle(max(row_x, 0), y - row.ascent(),
width() + caret_width,
row.height(), pi.background_color);
pi.pain.fillRectangle(row_x, y - row.ascent(),
width(), row.height(), pi.background_color);
}
// Instrumentation for testing row cache (see also