[LyX/master] Make BufferView::singeParUpdate more robust

Jean-Marc Lasgouttes lasgouttes at lyx.org
Wed Jul 3 15:45:23 UTC 2024


commit 89ab9eb569ec0eea87d9a8c269eb87507934e1c5
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Mon Jul 1 23:56:33 2024 +0200

    Make BufferView::singeParUpdate more robust
    
    In some cases, it might happen that this method is called in cases
    where no metrics is know for the current paragraph or where its
    position is not set.
    
    Take care of these cases to avoid assertions.
    
    Remove setting of inset positions in the method, but make sure that
    updateMetrics(false) is always called to get everything right.
    
    In the new code, updateMetrics(bool) os the method that sets
    everything right with minimal effort.
---
 src/BufferView.cpp | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 67aa4944f6..ce315a6f49 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -567,7 +567,9 @@ void BufferView::processUpdateFlags(Update::flags flags)
 	 * correct metrics at cursor position.
 	 */
 	else if ((flags & Update::SinglePar) && !(flags & Update::ForceDraw)) {
-		if (!singleParUpdate())
+		if (singleParUpdate())
+			updateMetrics(false);
+		else
 			updateMetrics(true);
 	}
 	else if (flags & Update::ForceDraw)
@@ -3150,6 +3152,10 @@ bool BufferView::singleParUpdate()
 	if (d->inlineCompletionPos_.fixIfBroken())
 		d->inlineCompletionPos_ = DocIterator();
 
+	if (!tm.contains(pit)) {
+		LYXERR(Debug::PAINTING, "SinglePar optimization failed: no known metrics");
+		return false;
+	}
 	/* Try to rebreak only the paragraph containing the cursor (if
 	 * this paragraph contains insets etc., rebreaking will
 	 * recursively descend). We need a full redraw if either
@@ -3167,18 +3173,19 @@ bool BufferView::singleParUpdate()
 	tm.redoParagraph(pit);
 	ParagraphMetrics & pm = tm.parMetrics(pit);
 	if (pm.height() != old_dim.height()
-		|| (pm.width() != old_dim.width() && old_dim.width() == tm.width())) {
+	     || (pm.width() != old_dim.width() && old_dim.width() == tm.width())) {
 		// Paragraph height or width has changed so we cannot proceed
 		// to the singlePar optimisation.
-		LYXERR(Debug::PAINTING, "SinglePar optimization failed.");
+		LYXERR(Debug::PAINTING, "SinglePar optimization failed: paragraph metrics changed");
 		return false;
 	}
 	// Since position() points to the baseline of the first row, we
 	// may have to update it. See ticket #11601 for an example where
 	// the height does not change but the ascent does.
-	pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
-
-	tm.updatePosCache(pit);
+	if (pm.hasPosition())
+		pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
+	else
+		LYXERR0("SinglePar optimization succeeded, but no position to update");
 
 	LYXERR(Debug::PAINTING, "\ny1: " << pm.top() << " y2: " << pm.bottom()
 		<< " pit: " << pit << " singlepar: 1");


More information about the lyx-cvs mailing list