diff options
author | Thomas Wolf | 2019-08-23 22:36:22 +0000 |
---|---|---|
committer | Paul Pazderski | 2019-09-10 17:40:47 +0000 |
commit | 95b3ff3beb9bbaf6e68933385ade1fb721b2a30a (patch) | |
tree | 018e38e95beb8876c16cb3c62f28fee3d5a16f1b | |
parent | 6b4bb0e33734ae1fb2efed9038d137d387e80658 (diff) | |
download | eclipse.platform.text-95b3ff3beb9bbaf6e68933385ade1fb721b2a30a.tar.gz eclipse.platform.text-95b3ff3beb9bbaf6e68933385ade1fb721b2a30a.tar.xz eclipse.platform.text-95b3ff3beb9bbaf6e68933385ade1fb721b2a30a.zip |
Bug 550396 - Speed up OverviewRuler
OverviewRuler computed the full pixel height of the full text,
which is expensive if the widget doesn't have a fixed line height,
for instance when word-wrapping is enabled.
However, OverviewRuler is interested in this value only if it is
strictly smaller than the height of the editor canvas. Speed up
the computation by stopping if the summed pixel height of lines
becomes larger than the height of the canvas.
Includes of 4.14 version update
Change-Id: Iace27158689a4ffb4a345124cfa46cc4c4260f06
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
7 files changed, 153 insertions, 9 deletions
diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF index 76b5e7be1a9..861f47e4ad5 100644 --- a/org.eclipse.jface.text/META-INF/MANIFEST.MF +++ b/org.eclipse.jface.text/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jface.text -Bundle-Version: 3.15.300.qualifier +Bundle-Version: 3.15.400.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: diff --git a/org.eclipse.jface.text/pom.xml b/org.eclipse.jface.text/pom.xml index 2baaf2e1e5f..ddbe958b909 100644 --- a/org.eclipse.jface.text/pom.xml +++ b/org.eclipse.jface.text/pom.xml @@ -18,6 +18,6 @@ </parent> <groupId>org.eclipse.jface</groupId> <artifactId>org.eclipse.jface.text</artifactId> - <version>3.15.300-SNAPSHOT</version> + <version>3.15.400-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java index a086fa2661e..3544a55abb8 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java @@ -308,7 +308,7 @@ public class OverviewRuler implements IOverviewRulerExtension, IOverviewRuler { * * @since 3.7 */ - static class WidgetInfos { + private static class WidgetInfos { /** * the text widget line count */ @@ -329,8 +329,10 @@ public class OverviewRuler implements IOverviewRulerExtension, IOverviewRuler { * the bounds of {@link OverviewRuler#fCanvas} */ Rectangle bounds; + /** - * the writable area in the text widget (height of all lines in pixels) + * the writable area in the text widget (height of all lines in pixels), if smaller than + * bounds.height; otherwise an unspecified value >= bounds.height */ int writable; @@ -343,7 +345,12 @@ public class OverviewRuler implements IOverviewRulerExtension, IOverviewRuler { public WidgetInfos(StyledText textWidget, Canvas canvas) { maxLines= textWidget.getLineCount(); bounds= canvas.getBounds(); - writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines); + // writeable is of interest only if it is smaller than bounds.height. + int w= 0; + for (int i= 0; i < maxLines && w < bounds.height; i++) { + w+= JFaceTextUtil.computeLineHeight(textWidget, i); + } + writable= w; ScrollBar verticalBar= textWidget.getVerticalBar(); if (verticalBar != null && !verticalBar.getVisible()) { diff --git a/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF b/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF index 45167ad0970..721d6de0de3 100644 --- a/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.ui.editors.tests;singleton:=true -Bundle-Version: 3.11.500.qualifier +Bundle-Version: 3.11.600.qualifier Bundle-Vendor: %Plugin.providerName Bundle-Localization: plugin Export-Package: org.eclipse.ui.editors.tests diff --git a/org.eclipse.ui.editors.tests/pom.xml b/org.eclipse.ui.editors.tests/pom.xml index e510b8aadef..01097588eeb 100644 --- a/org.eclipse.ui.editors.tests/pom.xml +++ b/org.eclipse.ui.editors.tests/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.ui</groupId> <artifactId>org.eclipse.ui.editors.tests</artifactId> - <version>3.11.500-SNAPSHOT</version> + <version>3.11.600-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <properties> <testSuite>${project.artifactId}</testSuite> diff --git a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java index adb8c5598f7..5438fe54a0f 100644 --- a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java +++ b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 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 @@ -34,7 +34,8 @@ import org.junit.runners.Suite.SuiteClasses; ZoomTest.class, FileDocumentProviderTest.class, TextFileDocumentProviderTest.class, - StatusEditorTest.class + StatusEditorTest.class, + LargeFileTest.class }) public class EditorsTestSuite { // see @SuiteClasses diff --git a/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/LargeFileTest.java b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/LargeFileTest.java new file mode 100644 index 00000000000..2f06ebef453 --- /dev/null +++ b/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/LargeFileTest.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2019 Thomas Wolf and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.ui.editors.tests; + +import static org.junit.Assert.assertTrue; + +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.eclipse.swt.widgets.Display; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; + +import org.eclipse.core.filebuffers.tests.ResourceHelper; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.internal.editors.text.EditorsPlugin; +import org.eclipse.ui.intro.IIntroPart; + +import org.eclipse.ui.texteditor.AbstractTextEditor; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Tests opening large files in a text editor. + */ +public class LargeFileTest { + + private IFile fLargeFile; + + private IPreferenceStore preferenceStore; + + boolean initialWordWrap; + + @Before + public void setUp() throws Exception { + IIntroPart intro = PlatformUI.getWorkbench().getIntroManager().getIntro(); + if (intro != null) { + PlatformUI.getWorkbench().getIntroManager().closeIntro(intro); + } + IFolder folder = ResourceHelper.createFolder("LargeFileTestProject/test/"); + fLargeFile = ResourceHelper.createFile(folder, "large.txt", ""); + IFileStore store = EFS.getLocalFileSystem().getStore(fLargeFile.getLocationURI()); + try (BufferedWriter writer = new BufferedWriter( + new OutputStreamWriter(store.openOutputStream(EFS.NONE, null), StandardCharsets.UTF_8))) { + for (int i = 1; i <= 40000; i++) { + writer.write("This is line # " + i); + writer.newLine(); + } + } + fLargeFile.refreshLocal(IResource.DEPTH_ZERO, null); + preferenceStore = EditorsPlugin.getDefault().getPreferenceStore(); + initialWordWrap = preferenceStore.getBoolean(AbstractTextEditor.PREFERENCE_WORD_WRAP_ENABLED); + } + + @After + public void tearDown() throws Exception { + fLargeFile.deleteMarkers(IMarker.BOOKMARK, true, IResource.DEPTH_INFINITE); + ResourceHelper.deleteProject("LargeFileTestProject"); + fLargeFile= null; + preferenceStore.setValue(AbstractTextEditor.PREFERENCE_WORD_WRAP_ENABLED, initialWordWrap); + TestUtil.cleanUp(); + } + + @Test + public void openLargeFileWithAnnotation() throws Exception { + IWorkbench workbench= PlatformUI.getWorkbench(); + Display display = workbench.getDisplay(); + IWorkbenchPage page= workbench.getActiveWorkbenchWindow().getActivePage(); + // Set word-wrap (makes the StyledText have variable line height) + preferenceStore.setValue(AbstractTextEditor.PREFERENCE_WORD_WRAP_ENABLED, true); + // Let's get an idea how long it takes to open the file at all. Open the + // file twice; the first time takes longer. + long[] baseline = new long[1]; + for (int i = 0; i < 2; i++) { + baseline[0] = System.nanoTime(); + IEditorPart part = IDE.openEditor(page, fLargeFile); + display.asyncExec(() -> { + baseline[0] = System.nanoTime() - baseline[0]; + }); + TestUtil.runEventLoop(); + assertTrue("Expected a text editor", part instanceof ITextEditor); + page.closeEditor(part, false); + TestUtil.runEventLoop(); + } + // Create a marker on the file + IMarker marker = fLargeFile.createMarker(IMarker.BOOKMARK); + marker.setAttribute(IMarker.LOCATION, "line 1"); + marker.setAttribute(IMarker.MESSAGE, "Just a test marker"); + marker.setAttribute(IMarker.LINE_NUMBER, 1); + marker.setAttribute(IMarker.CHAR_START, 8); + marker.setAttribute(IMarker.CHAR_END, 12); + marker.setAttribute(IMarker.USER_EDITABLE, false); + TestUtil.runEventLoop(); + // Open it again + long[] withMarker = { System.nanoTime() }; + IEditorPart part = IDE.openEditor(page, fLargeFile); + display.asyncExec(() -> { + withMarker[0] = System.nanoTime() - withMarker[0]; + }); + TestUtil.runEventLoop(); + assertTrue("Expected a text editor", part instanceof ITextEditor); + page.closeEditor(part, false); + TestUtil.runEventLoop(); + // Be generous here; all this timing is approximate. Fail if the attempt + // with the marker takes more than twice as long. If the OverviewRuler + // is badly implemented, opening with the marker will take much longer. + assertTrue("Opening large file took too long: " + (withMarker[0] / 1000000.0f) + "ms with marker vs. " + + (baseline[0] / 1000000.0f) + "ms without", + withMarker[0] / 2 <= baseline[0]); + } +} |