Le 17/07/2023 à 18:00, Scott Kostyshak a écrit :
On Mon, Jul 17, 2023 at 04:03:32PM +0200, Jean-Marc Lasgouttes wrote:
Hello,

This patch tries to address #12297, where typing in the big branch in the
attached big-inset.23.lyx file is painfully slow.

Works well! I just did some brief testing.

It worked well until one tries to use mathed %-] Updated patch below is better in this respect.

Works well! I just did some brief testing. Scrolling is still slow, but with your patch 
typing and returns are much faster, and even "workable" (in the sense that if 
there were no scrolling issue I could imagine editing the document without too much 
frustration).

Indeed. The good news is that in principle LyX has already (painfully) computed all the needed metrics for scrolling, so in principle it should not be impossible to fix.

What I cannot fix easily, though is that if I insert characters just before the branch (in same paragraph), things are ugly again because the whole branch has to be typeset again and again.

JMarc
From c48f313d27b0bede0829877fb65100ad388ca3e3 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Mon, 17 Jul 2023 14:43:29 +0200
Subject: [PATCH] Enable Update::SinglePar in nested insets too

The idea of single par update is to try to re-break only the paragraph
containing the cursor (if this paragraph contains insets etc.,
re-breaking will recursively descend).

The existing single paragraph update mechanism was tailored to work
only at top level. Indeed changing a paragraph nested into an inset may
lead to larger changes.

This commit tries a rather naive approach that seems to work well: we
need a full redraw if either

1/ the height has changed
or
2/ the width has changed and it was equal to the text metrics width;
   the goal is to catch the case of a one-row inset that grows with
   its contents, but optimize the case of typing in a short paragraph
   part of a larger inset.

NOTE: if only the height has changed, then it should be
  possible to update all metrics at minimal cost. However,
  since this is risky, we do not try that right now.

Part of bug #12297.
---
 src/BufferView.cpp | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 15911e8ff3..f30e656477 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3023,24 +3023,35 @@ Cursor const & BufferView::cursor() const
 
 bool BufferView::singleParUpdate()
 {
-	Text & buftext = buffer_.text();
-	pit_type const bottom_pit = d->cursor_.bottom().pit();
-	TextMetrics & tm = textMetrics(&buftext);
-	Dimension const old_dim = tm.parMetrics(bottom_pit).dim();
+	pit_type const pit = d->cursor_.pit();
+	TextMetrics & tm = textMetrics(d->cursor_.text());
+	Dimension const old_dim = tm.parMetrics(pit).dim();
 
 	// make sure inline completion pointer is ok
 	if (d->inlineCompletionPos_.fixIfBroken())
 		d->inlineCompletionPos_ = DocIterator();
 
-	// In Single Paragraph mode, rebreak only
-	// the (main text, not inset!) paragraph containing the cursor.
-	// (if this paragraph contains insets etc., rebreaking will
-	// recursively descend)
-	tm.redoParagraph(bottom_pit);
-	ParagraphMetrics & pm = tm.parMetrics(bottom_pit);
-	if (pm.height() != old_dim.height()) {
-		// Paragraph height has changed so we cannot proceed to
-		// the singlePar optimisation.
+	/* 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
+	 * 1/ the height has changed
+	 * or
+	 * 2/ the width has changed and it was equal to the textmetrics
+	 *    width; the goal is to catch the case of a one-row inset that
+	 *    grows with its contents, but optimize the case of typing at
+	 *    the end of a mmultiple-row paragraph.
+	 *
+	 * NOTE: if only the height has changed, then it should be
+	 *   possible to update all metrics at minimal cost. However,
+	 *   since this is risky, we do not try that right now.
+	 */
+	tm.redoParagraph(pit);
+	ParagraphMetrics & pm = tm.parMetrics(pit);
+	if (pm.height() != old_dim.height()
+		|| (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.");
 		return false;
 	}
 	// Since position() points to the baseline of the first row, we
@@ -3048,11 +3059,11 @@ bool BufferView::singleParUpdate()
 	// the height does not change but the ascent does.
 	pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
 
-	tm.updatePosCache(bottom_pit);
+	tm.updatePosCache(pit);
 
 	LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
 		<< " y2: " << pm.position() + pm.descent()
-		<< " pit: " << bottom_pit
+		<< " pit: " << pit
 		<< " singlepar: 1");
 	return true;
 }
-- 
2.39.2

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to