diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java index a768997e447..0355c8671a5 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java @@ -266,6 +266,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl fCachedTextWidget= null; }); + fCanvas.addListener(SWT.ZoomChanged, e -> { + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + }); + fMouseListener= new MouseListener() { @Override public void mouseUp(MouseEvent event) { @@ -517,24 +524,28 @@ private void doubleBufferPaint(GC dest) { fBuffer= null; } } - if (fBuffer == null) - fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + if (fBuffer == null) { + fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y); + } else { + GC gc= new GC(fBuffer); + try { + doPaint(gc, size.x, size.y); + } finally { + gc.dispose(); + } + } + dest.drawImage(fBuffer, 0, 0); + } - GC gc= new GC(fBuffer); + private void doPaint(GC gc, int width, int height) { gc.setFont(fCachedTextWidget.getFont()); - try { - gc.setBackground(fCanvas.getBackground()); - gc.fillRectangle(0, 0, size.x, size.y); - - if (fCachedTextViewer instanceof ITextViewerExtension5) - doPaint1(gc); - else - doPaint(gc); - } finally { - gc.dispose(); - } + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, width, height); - dest.drawImage(fBuffer, 0, 0); + if (fCachedTextViewer instanceof ITextViewerExtension5) + doPaint1(gc); + else + doPaint(gc); } /** diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.java index 99b4a093158..f57208b417d 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.java @@ -199,6 +199,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl fCachedTextWidget= null; }); + fCanvas.addListener(SWT.ZoomChanged, e -> { + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + }); + fCanvas.addMouseListener(fMouseHandler); fCanvas.addMouseMoveListener(fMouseHandler); @@ -249,19 +256,15 @@ private void doubleBufferPaint(GC dest) { fBuffer= null; } } - if (fBuffer == null) - fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); - - GC gc= new GC(fBuffer); - gc.setFont(fCanvas.getFont()); - - try { - gc.setBackground(getBackground()); - gc.fillRectangle(0, 0, size.x, size.y); - - doPaint(gc); - } finally { - gc.dispose(); + if (fBuffer == null) { + fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y); + } else { + GC gc= new GC(fBuffer); + try { + doPaint(gc, size.x, size.y); + } finally { + gc.dispose(); + } } dest.drawImage(fBuffer, 0, 0); @@ -291,6 +294,14 @@ protected final boolean isViewerCompletelyShown() { return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget); } + private void doPaint(GC gc, int width, int height) { + gc.setFont(fCanvas.getFont()); + gc.setBackground(getBackground()); + gc.fillRectangle(0, 0, width, height); + + doPaint(gc); + } + /** * Draws the ruler column. * diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java index 0060369d027..5f658f5ce89 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java @@ -34,6 +34,7 @@ import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageGcDrawer; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; @@ -616,7 +617,13 @@ public void addMouseListener(MouseListener listener) { fCachedTextWidget= null; }); - fCanvas.addListener(SWT.ZoomChanged, e -> computeIndentations()); + fCanvas.addListener(SWT.ZoomChanged, e -> { + computeIndentations(); + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + }); fMouseHandler= new MouseHandler(); fCanvas.addMouseListener(fMouseHandler); @@ -679,10 +686,28 @@ private void doubleBufferPaint(GC dest) { return; } - boolean bufferStillValid = fBuffer != null; if (fBuffer == null) { - fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); + fBuffer= newFullBufferImage(size); + } else { + doPaint(visibleLines, size); } + dest.drawImage(fBuffer, 0, 0); + } + + private Image newFullBufferImage(Point size) { + ImageGcDrawer imageGcDrawer= (gc, imageWidth, imageHeight) -> { + ILineRange lines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer); + if (lines == null) { + return; + } + // We redraw everything; paint directly into the buffer + initializeGC(gc, 0, 0, imageWidth, imageHeight); + doPaint(gc, lines); + }; + return new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y); + } + + private void doPaint(ILineRange visibleLines, Point size) { GC bufferGC= new GC(fBuffer); Image newBuffer= null; try { @@ -696,7 +721,7 @@ private void doubleBufferPaint(GC dest) { int bottomWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, bottomModelLine); boolean atEnd= bottomWidgetLine + 1 >= fCachedTextWidget.getLineCount(); int height= size.y; - if (dy != 0 && !atEnd && bufferStillValid && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) { + if (dy != 0 && !atEnd && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) { int bottomPixel= fCachedTextWidget.getLinePixel(bottomWidgetLine + 1); if (dy > 0 && bottomPixel < size.y) { // Can occur on GTK with static scrollbars; see bug 551320. @@ -745,16 +770,7 @@ private void doubleBufferPaint(GC dest) { fLastBottomModelLine= bottomModelLine; fLastHeight= height; if (dy != 0) { - // Some rulers may paint outside the line region. Let them paint in a new image, - // the copy the wanted bits. - newBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); - GC localGC= new GC(newBuffer); - try { - initializeGC(localGC, 0, bufferY, size.x, bufferH); - doPaint(localGC, visibleLines); - } finally { - localGC.dispose(); - } + newBuffer= newBufferImage(size, bufferY, bufferH, visibleLines); bufferGC.drawImage(newBuffer, 0, bufferY, size.x, bufferH, 0, bufferY, size.x, bufferH); if (dy > 0 && bufferY + bufferH < size.y) { // Scrolled down in the text, but didn't use the full height of the Canvas: clear @@ -774,7 +790,16 @@ private void doubleBufferPaint(GC dest) { newBuffer.dispose(); } } - dest.drawImage(fBuffer, 0, 0); + } + + private Image newBufferImage(Point size, int bufferY, int bufferH, final ILineRange visibleLines) { + ImageGcDrawer imageGcDrawer= (localGC, imageWidth, imageHeight) -> { + // Some rulers may paint outside the line region. Let them paint in a new image, + // the copy the wanted bits. + initializeGC(localGC, 0, bufferY, imageWidth, bufferH); + doPaint(localGC, visibleLines); + }; + return new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y); } private void initializeGC(GC gc, int x, int y, int width, int height) { diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java index 4eb1ef04d72..2b3fd2fb8c6 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java @@ -597,6 +597,13 @@ public void mouseEnter(MouseEvent e) { fTextViewer= null; }); + fCanvas.addListener(SWT.ZoomChanged, e -> { + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + }); + fCanvas.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent event) { @@ -676,23 +683,27 @@ private void doubleBufferPaint(GC dest) { fBuffer= null; } } - if (fBuffer == null) - fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); - - GC gc= new GC(fBuffer); - try { - gc.setBackground(fCanvas.getBackground()); - gc.fillRectangle(0, 0, size.x, size.y); + if (fBuffer == null) { + fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y); + } else { + GC gc= new GC(fBuffer); + try { + doPaint(gc, size.x, size.y); + } finally { + gc.dispose(); + } + } - cacheAnnotations(); + dest.drawImage(fBuffer, 0, 0); + } - doPaint(gc); + private void doPaint(GC gc, int width, int height) { + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, width, height); - } finally { - gc.dispose(); - } + cacheAnnotations(); - dest.drawImage(fBuffer, 0, 0); + doPaint(gc); } private void cacheAnnotations() { diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java index c63e6a45c1e..bc98e5a3e26 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java @@ -159,6 +159,13 @@ public Control createControl(Composite parent, ITextViewer textViewer) { fTextViewer= null; }); + fCanvas.addListener(SWT.ZoomChanged, e -> { + if (fBuffer != null) { + fBuffer.dispose(); + fBuffer= null; + } + }); + fCanvas.addMouseListener(new MouseListener() { @Override public void mouseUp(MouseEvent event) { @@ -223,27 +230,31 @@ private void doubleBufferPaint(GC dest) { fBuffer= null; } } - if (fBuffer == null) - fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); - - GC gc= new GC(fBuffer); - gc.setFont(fTextViewer.getTextWidget().getFont()); - try { - gc.setBackground(fCanvas.getBackground()); - gc.fillRectangle(0, 0, size.x, size.y); - - if (fTextViewer instanceof ITextViewerExtension5) - doPaint1(gc); - else - doPaint(gc); - } finally { - gc.dispose(); + if (fBuffer == null) { + fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y); + } else { + GC gc= new GC(fBuffer); + try { + doPaint(gc, size.x, size.y); + } finally { + gc.dispose(); + } } - dest.drawImage(fBuffer, 0, 0); } + private void doPaint(GC gc, int width, int height) { + gc.setFont(fTextViewer.getTextWidget().getFont()); + gc.setBackground(fCanvas.getBackground()); + gc.fillRectangle(0, 0, width, height); + + if (fTextViewer instanceof ITextViewerExtension5) + doPaint1(gc); + else + doPaint(gc); + } + /** * Returns the document offset of the upper left corner of the * widgets view port, possibly including partially visible lines.