From a4d9315bc49445e4419b3b59fd238a13c5f7be31 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Tue, 30 Apr 2024 15:02:16 +0200 Subject: [PATCH] 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. --- src/BufferView.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 3c35d75ec8..317a276cdd 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -556,36 +556,40 @@ void BufferView::processUpdateFlags(Update::flags flags) updateMetrics(true); // metrics is done, full drawing is necessary now 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. 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 if (flags & Update::FitCursor) { if (needsFitCursor()) { // First try to make the selection start visible // (which is just the cursor when there is no selection) scrollToCursor(d->cursor_.selectionBegin(), SCROLL_VISIBLE); - // Metrics have to be recomputed (maybe again) - updateMetrics(true); + // Metrics have to be updated + updateMetrics(false); // Is the cursor visible? (only useful if cursor is at end of selection) if (needsFitCursor()) { // then try to make cursor visible instead scrollToCursor(d->cursor_, SCROLL_VISIBLE); // 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