Avoid full metrics computation with Update:FitCursor

The handling of Update::FitCursor traditionnally recomputes all
metrics once or twice. Now that updateMetrics(false) ensures that all
paragraphs that require it have a metrics, we might as well use that.

Take this occasion to move handling of Update::SinglePar earlier,
before the check for Update::ForceDraw.
This commit is contained in:
Jean-Marc Lasgouttes 2024-04-30 15:02:16 +02:00
parent 527984ed2e
commit a4d9315bc4

View File

@ -556,36 +556,40 @@ void BufferView::processUpdateFlags(Update::flags flags)
updateMetrics(true); updateMetrics(true);
// metrics is done, full drawing is necessary now // metrics is done, full drawing is necessary now
flags = (flags & ~Update::Force) | Update::ForceDraw; flags = (flags & ~Update::Force) | Update::ForceDraw;
} else if (flags & Update::ForceDraw) }
/* If a single paragraph update has been requested and we are not
* already repainting all, check whether this update changes the
* paragraph metrics. If it does, then compute all metrics (in
* case the paragraph is in an inset)
*
* We handle this before FitCursor because the later will require
* correct metrics at cursor position.
*/
else if ((flags & Update::SinglePar) && !(flags & Update::ForceDraw)) {
if (!singleParUpdate())
updateMetrics(true);
}
else if (flags & Update::ForceDraw)
// This will compute only the needed metrics and update positions. // This will compute only the needed metrics and update positions.
updateMetrics(false); updateMetrics(false);
// Detect whether we can only repaint a single paragraph (if we
// are not already redrawing all).
// We handle this before FitCursor because the later will require
// correct metrics at cursor position.
if (!(flags & Update::ForceDraw)
&& (flags & Update::SinglePar)
&& !singleParUpdate())
updateMetrics(true);
// Then make sure that the screen contains the cursor if needed // Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) { if (flags & Update::FitCursor) {
if (needsFitCursor()) { if (needsFitCursor()) {
// First try to make the selection start visible // First try to make the selection start visible
// (which is just the cursor when there is no selection) // (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), SCROLL_VISIBLE); scrollToCursor(d->cursor_.selectionBegin(), SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again) // Metrics have to be updated
updateMetrics(true); updateMetrics(false);
// Is the cursor visible? (only useful if cursor is at end of selection) // Is the cursor visible? (only useful if cursor is at end of selection)
if (needsFitCursor()) { if (needsFitCursor()) {
// then try to make cursor visible instead // then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE); scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again) // Metrics have to be recomputed (maybe again)
updateMetrics(true); updateMetrics(false);
} }
} }
flags = flags & ~Update::FitCursor; flags = (flags & ~Update::FitCursor) | Update::ForceDraw;
} }
// Add flags to the the update flags. These will be reset to None // Add flags to the the update flags. These will be reset to None