Bug 559230 - [Regression] Opening a file is extremely slow

Revert "Bug 343086 - [StyledText] Horizontal scroll bar vanishes when
line gets shorter"
This reverts commit 218f92e3b9fda0f48cc2d06401f180d5098121e3.

Revert "Bug 553377 - StyledTextRenderer max width can be invalid"
This reverts commit 795aeac59686647adf9dd0ea194583482609ac01.

Change-Id: I67c865393678af4ff777e8b7724e24ed3dfa8703
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index 5e3537c..1a1f1fa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -6389,7 +6389,7 @@
 	if (lastTextChangeReplaceLineCount > 0 || wordWrap || visualWrap) {
 		claimBottomFreeSpace();
 	}
-	if (lastTextChangeReplaceCharCount > 0 || lastTextChangeNewLineCount > 0) {
+	if (lastTextChangeReplaceCharCount > 0) {
 		claimRightFreeSpace();
 	}
 
@@ -8088,8 +8088,12 @@
 }
 void resetCache(SortedSet<Integer> lines) {
 	if (lines == null || lines.isEmpty()) return;
+	int maxLineIndex = renderer.maxWidthLineIndex;
 	renderer.reset(lines);
 	renderer.calculateClientArea();
+	if (0 <= maxLineIndex && maxLineIndex < content.getLineCount()) {
+		renderer.calculate(maxLineIndex, 1);
+	}
 	setScrollBars(true);
 	if (!isFixedLineHeight()) {
 		if (topIndex > lines.iterator().next()) {
@@ -8099,8 +8103,12 @@
 	}
 }
 void resetCache(int firstLine, int count) {
+	int maxLineIndex = renderer.maxWidthLineIndex;
 	renderer.reset(firstLine, count);
 	renderer.calculateClientArea();
+	if (0 <= maxLineIndex && maxLineIndex < content.getLineCount()) {
+		renderer.calculate(maxLineIndex, 1);
+	}
 	setScrollBars(true);
 	if (!isFixedLineHeight()) {
 		if (topIndex > firstLine) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
index 360ae0a..20eec0a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -12,7 +12,6 @@
  *     IBM Corporation - initial API and implementation
  *     Anton Leherbauer (Wind River Systems) - Bug 439419
  *     Angelo Zerr <angelo.zerr@gmail.com> - Customize different line spacing of StyledText - Bug 522020
- *     Paul Pazderski - Bug 553377: wrong max width after content change
  *******************************************************************************/
 package org.eclipse.swt.custom;
 
@@ -50,7 +49,8 @@
 	int lineCount;
 	LineSizeInfo[] lineSizes;
 	LineInfo[] lines;
-	int maxWidthLineIndex = -1; // index of longest line or -1 if currently unknown
+	int maxWidth;
+	int maxWidthLineIndex;
 	boolean idleRunning;
 
 	/* Bullet */
@@ -147,11 +147,6 @@
 		boolean needsRecalculateHeight() {
 			return height == RESETED_SIZE;
 		}
-
-		@Override
-		public String toString() {
-			return "width: " + width + ", height: " + height; //$NON-NLS-1$ //$NON-NLS-2$
-		}
 	}
 
 	static class LineInfo {
@@ -304,10 +299,8 @@
 			line.height = rect.height;
 			disposeTextLayout(layout);
 		}
-		// Do not update longest line if not already known. If calculate is only called for
-		// a part of all lines the max index would point to the longest calculated line which
-		// is not necessary the longest of all lines.
-		if (maxWidthLineIndex >= 0 && line.width > getLineSize(maxWidthLineIndex).width) {
+		if (line.width > maxWidth) {
+			maxWidth = line.width;
 			maxWidthLineIndex = i;
 		}
 	}
@@ -1295,21 +1288,7 @@
 	return layout;
 }
 int getWidth() {
-	// In some cases (e.g. line spacing provider) it can happen that caches are reset while
-	// calculated and therefore the max width line is unknown even after calculating all lines.
-	// Workaround is to calculate bounds until it has stabilized. To prevent endless loops
-	// the max number of iterations is limited.
-	int loops = 2;
-	while (maxWidthLineIndex < 0 && loops-- > 0) {
-		// calculate will update max width index only if the current max width is >= 0
-		// but not if longest line is currently unknown. At this point we must know
-		// the actual max line width. So we set first line as the max so that calculate
-		// will update it to the actual max width line after all line widths are checked.
-		// See also https://bugs.eclipse.org/553377
-		maxWidthLineIndex = 0;
-		calculate(0, lineCount);
-	}
-	return getLineSize(maxWidthLineIndex).width;
+	return maxWidth;
 }
 void reset() {
 	if (layouts != null) {
@@ -1325,7 +1304,6 @@
 	stylesSet = null;
 	lines = null;
 	lineSizes = null;
-	maxWidthLineIndex = -1;
 	bullets = null;
 	bulletsIndices = null;
 	redrawLines = null;
@@ -1342,13 +1320,25 @@
 }
 void reset(Set<Integer> lines) {
 	if (lines == null || lines.isEmpty()) return;
+	int resetLineCount = 0;
 	for (Integer line : lines) {
 		if (line >= 0 || line < lineCount) {
+			resetLineCount++;
 			getLineSize(line.intValue()).resetSize();
 		}
 	}
 	if (lines.contains(Integer.valueOf(maxWidthLineIndex))) {
+		maxWidth = 0;
 		maxWidthLineIndex = -1;
+		if (resetLineCount != this.lineCount) {
+			for (int i = 0; i < this.lineCount; i++) {
+				LineSizeInfo lineSize = getLineSize(i);
+				if (lineSize.width > maxWidth) {
+					maxWidth = lineSize.width;
+					maxWidthLineIndex = i;
+				}
+			}
+		}
 	}
 }
 void setContent(StyledTextContent content) {
@@ -1356,6 +1346,7 @@
 	this.content = content;
 	lineCount = content.getLineCount();
 	lineSizes = new LineSizeInfo[lineCount];
+	maxWidth = 0;
 	maxWidthLineIndex = -1;
 	reset(0, lineCount);
 }
@@ -1675,13 +1666,13 @@
 	}
 }
 void textChanging(TextChangingEvent event) {
-	final int start = event.start;
-	final int newCharCount = event.newCharCount, replaceCharCount = event.replaceCharCount;
-	final int newLineCount = event.newLineCount, replaceLineCount = event.replaceLineCount;
+	int start = event.start;
+	int newCharCount = event.newCharCount, replaceCharCount = event.replaceCharCount;
+	int newLineCount = event.newLineCount, replaceLineCount = event.replaceLineCount;
 
 	updateRanges(start, replaceCharCount, newCharCount);
 
-	final int startLine = content.getLineAtOffset(start);
+	int startLine = content.getLineAtOffset(start);
 	if (replaceCharCount == content.getCharCount()) lines = null;
 	if (replaceLineCount == lineCount) {
 		lineCount = newLineCount;
@@ -1696,7 +1687,7 @@
 		if(lineCount < startIndex) {
 			SWT.error(SWT.ERROR_INVALID_RANGE, null, "bug 478020: lineCount < startIndex: " + lineCount + ":" + startIndex);
 		}
-		final int delta = newLineCount - replaceLineCount;
+		int delta = newLineCount - replaceLineCount;
 		if (lineCount + delta > lineSizes.length) {
 			LineSizeInfo[] newLineSizes = new LineSizeInfo[lineCount + delta + GROW];
 			System.arraycopy(lineSizes, 0, newLineSizes, 0, lineCount);
@@ -1716,9 +1707,6 @@
 		for (int i = lineCount + delta; i < lineCount; i++) {
 			lineSizes[i] = null;
 		}
-		if (maxWidthLineIndex >= 0 && (maxWidthLineIndex >= lineSizes.length || lineSizes[maxWidthLineIndex] == null)) {
-			maxWidthLineIndex = -1;
-		}
 		if (layouts != null) {
 			int layoutStartLine = startLine - topIndex;
 			int layoutEndLine = layoutStartLine + replaceLineCount + 1;
@@ -1770,15 +1758,14 @@
 			}
 		}
 		if (replaceLineCount != 0 || newLineCount != 0) {
-			int bulletStartLine = startLine;
-			int startLineOffset = content.getOffsetAtLine(bulletStartLine);
-			if (startLineOffset != start) bulletStartLine++;
-			updateBullets(bulletStartLine, replaceLineCount, newLineCount, true);
+			int startLineOffset = content.getOffsetAtLine(startLine);
+			if (startLineOffset != start) startLine++;
+			updateBullets(startLine, replaceLineCount, newLineCount, true);
 			if (lines != null) {
-				startIndex = bulletStartLine + replaceLineCount;
-				endIndex = bulletStartLine + newLineCount;
+				startIndex = startLine + replaceLineCount;
+				endIndex = startLine + newLineCount;
 				System.arraycopy(lines, startIndex, lines, endIndex, lineCount - startIndex);
-				for (int i = bulletStartLine; i < endIndex; i++) {
+				for (int i = startLine; i < endIndex; i++) {
 					lines[i] = null;
 				}
 				for (int i = lineCount + delta; i < lineCount; i++) {
@@ -1787,6 +1774,17 @@
 			}
 		}
 		lineCount += delta;
+		if (maxWidthLineIndex != -1 && startLine <= maxWidthLineIndex && maxWidthLineIndex <= startLine + replaceLineCount) {
+			maxWidth = 0;
+			maxWidthLineIndex = -1;
+			for (int i = 0; i < lineCount; i++) {
+				LineSizeInfo lineSize = getLineSize(i);
+				if (lineSize.width > maxWidth) {
+					maxWidth = lineSize.width;
+					maxWidthLineIndex = i;
+				}
+			}
+		}
 	}
 }
 void updateBullets(int startLine, int replaceLineCount, int newLineCount, boolean update) {
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
index 72d7232..b84c518 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_custom_StyledText.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -17,7 +17,6 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -5802,60 +5801,4 @@
 	String clipboardText = (String) clipboard.getContents(rtfTranfer);
 	assertTrue("RTF copy failed", clipboardText.length() > 0);
 }
-
-/**
- * Test for:
- * Bug 553377 - StyledTextRenderer max width can be invalid
- * Bug 343086 - Horizontal scroll bar vanishes when line gets shorter
- */
-@Test
-public void test_claimRightFreeSpace() {
-	text.dispose();
-	text = new StyledText(shell, SWT.H_SCROLL);
-	setWidget(text);
-	text.setAlwaysShowScrollBars(true);
-	text.setSize(200, 500);
-	String content = "######################################################";
-	int n = content.length();
-	text.setText(content);
-	text.setCaretOffset(n);
-	text.showSelection();
-	shell.pack();
-	shell.open();
-
-	int lastScrollIndex = text.getHorizontalIndex();
-	assertNotEquals("Widget must be scrolled for test", 0, lastScrollIndex);
-
-	// test if widget reclaims horizontal space when characters are removed
-	int cutLenght = 3;
-	text.getContent().replaceTextRange(n - cutLenght, cutLenght, "");
-	assertTrue("Free horizontal space not reclaimed on character remove",
-			text.getHorizontalIndex() < lastScrollIndex && text.getHorizontalIndex() > 0);
-	n -= cutLenght;
-
-	// test if widget reclaims horizontal space if longest line is shortened because line get split
-	int newlineOffset = n - 5;
-	text.setCaretOffset(newlineOffset - 2);
-	lastScrollIndex = text.getHorizontalIndex();
-	text.getContent().replaceTextRange(newlineOffset, 0, "\n");
-	assertTrue("Free horizontal space not reclaimed on splitting line",
-			text.getHorizontalIndex() < lastScrollIndex && text.getHorizontalIndex() > 0);
-
-	// similar to previous test but this time the second half of the split is the new max length line
-	text.setCaretOffset(0);
-	text.setHorizontalIndex(100);
-	lastScrollIndex = text.getHorizontalIndex();
-	assertNotEquals("Widget must be scrolled for test", 0, lastScrollIndex);
-	text.getContent().replaceTextRange(10, 5, "~~\n~~");
-	assertTrue("Free horizontal space not reclaimed on splitting line",
-			text.getHorizontalIndex() < lastScrollIndex && text.getHorizontalIndex() > 0);
-
-	text.setText(content);
-	text.setHorizontalIndex(content.length());
-	lastScrollIndex = text.getHorizontalIndex();
-	assertNotEquals("Widget must be scrolled for test", 0, lastScrollIndex);
-	text.getContent().replaceTextRange(0, content.length(), "\n" + content.substring(5));
-	assertTrue("Free horizontal space not reclaimed replace",
-			text.getHorizontalIndex() < lastScrollIndex && text.getHorizontalIndex() > 0);
-}
 }