Skip to content

Commit 3eaaeb6

Browse files
akoch-yattaHeikoKlare
authored andcommitted
Adapt double buffering use cases for multi-zoom
This commit replaces three use cases where GC together with Images where used to draw double buffered images. With new multi-zoom-setting in Windows this leads to desctructive scaling and fragments caused by the double buffering of Images/GCs created with different zoom. The changes utilize the newly added ImageGcDrawer to provide a dynamic callback to draw on a correctly initialized GC on demand.
1 parent 8029b47 commit 3eaaeb6

File tree

5 files changed

+141
-72
lines changed

5 files changed

+141
-72
lines changed

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl
266266
fCachedTextWidget= null;
267267
});
268268

269+
fCanvas.addListener(SWT.ZoomChanged, e -> {
270+
if (fBuffer != null) {
271+
fBuffer.dispose();
272+
fBuffer= null;
273+
}
274+
});
275+
269276
fMouseListener= new MouseListener() {
270277
@Override
271278
public void mouseUp(MouseEvent event) {
@@ -517,24 +524,28 @@ private void doubleBufferPaint(GC dest) {
517524
fBuffer= null;
518525
}
519526
}
520-
if (fBuffer == null)
521-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
527+
if (fBuffer == null) {
528+
fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y);
529+
} else {
530+
GC gc= new GC(fBuffer);
531+
try {
532+
doPaint(gc, size.x, size.y);
533+
} finally {
534+
gc.dispose();
535+
}
536+
}
537+
dest.drawImage(fBuffer, 0, 0);
538+
}
522539

523-
GC gc= new GC(fBuffer);
540+
private void doPaint(GC gc, int width, int height) {
524541
gc.setFont(fCachedTextWidget.getFont());
525-
try {
526-
gc.setBackground(fCanvas.getBackground());
527-
gc.fillRectangle(0, 0, size.x, size.y);
528-
529-
if (fCachedTextViewer instanceof ITextViewerExtension5)
530-
doPaint1(gc);
531-
else
532-
doPaint(gc);
533-
} finally {
534-
gc.dispose();
535-
}
542+
gc.setBackground(fCanvas.getBackground());
543+
gc.fillRectangle(0, 0, width, height);
536544

537-
dest.drawImage(fBuffer, 0, 0);
545+
if (fCachedTextViewer instanceof ITextViewerExtension5)
546+
doPaint1(gc);
547+
else
548+
doPaint(gc);
538549
}
539550

540551
/**

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ChangeRulerColumn.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl
199199
fCachedTextWidget= null;
200200
});
201201

202+
fCanvas.addListener(SWT.ZoomChanged, e -> {
203+
if (fBuffer != null) {
204+
fBuffer.dispose();
205+
fBuffer= null;
206+
}
207+
});
208+
202209
fCanvas.addMouseListener(fMouseHandler);
203210
fCanvas.addMouseMoveListener(fMouseHandler);
204211

@@ -249,19 +256,15 @@ private void doubleBufferPaint(GC dest) {
249256
fBuffer= null;
250257
}
251258
}
252-
if (fBuffer == null)
253-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
254-
255-
GC gc= new GC(fBuffer);
256-
gc.setFont(fCanvas.getFont());
257-
258-
try {
259-
gc.setBackground(getBackground());
260-
gc.fillRectangle(0, 0, size.x, size.y);
261-
262-
doPaint(gc);
263-
} finally {
264-
gc.dispose();
259+
if (fBuffer == null) {
260+
fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y);
261+
} else {
262+
GC gc= new GC(fBuffer);
263+
try {
264+
doPaint(gc, size.x, size.y);
265+
} finally {
266+
gc.dispose();
267+
}
265268
}
266269

267270
dest.drawImage(fBuffer, 0, 0);
@@ -291,6 +294,14 @@ protected final boolean isViewerCompletelyShown() {
291294
return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget);
292295
}
293296

297+
private void doPaint(GC gc, int width, int height) {
298+
gc.setFont(fCanvas.getFont());
299+
gc.setBackground(getBackground());
300+
gc.fillRectangle(0, 0, width, height);
301+
302+
doPaint(gc);
303+
}
304+
294305
/**
295306
* Draws the ruler column.
296307
*

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.eclipse.swt.graphics.FontMetrics;
3535
import org.eclipse.swt.graphics.GC;
3636
import org.eclipse.swt.graphics.Image;
37+
import org.eclipse.swt.graphics.ImageGcDrawer;
3738
import org.eclipse.swt.graphics.Point;
3839
import org.eclipse.swt.graphics.Rectangle;
3940
import org.eclipse.swt.widgets.Canvas;
@@ -616,7 +617,13 @@ public void addMouseListener(MouseListener listener) {
616617
fCachedTextWidget= null;
617618
});
618619

619-
fCanvas.addListener(SWT.ZoomChanged, e -> computeIndentations());
620+
fCanvas.addListener(SWT.ZoomChanged, e -> {
621+
computeIndentations();
622+
if (fBuffer != null) {
623+
fBuffer.dispose();
624+
fBuffer= null;
625+
}
626+
});
620627

621628
fMouseHandler= new MouseHandler();
622629
fCanvas.addMouseListener(fMouseHandler);
@@ -679,10 +686,28 @@ private void doubleBufferPaint(GC dest) {
679686
return;
680687
}
681688

682-
boolean bufferStillValid = fBuffer != null;
683689
if (fBuffer == null) {
684-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
690+
fBuffer= newFullBufferImage(size);
691+
} else {
692+
doPaint(visibleLines, size);
685693
}
694+
dest.drawImage(fBuffer, 0, 0);
695+
}
696+
697+
private Image newFullBufferImage(Point size) {
698+
ImageGcDrawer imageGcDrawer= (gc, imageWidth, imageHeight) -> {
699+
ILineRange lines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer);
700+
if (lines == null) {
701+
return;
702+
}
703+
// We redraw everything; paint directly into the buffer
704+
initializeGC(gc, 0, 0, imageWidth, imageHeight);
705+
doPaint(gc, lines);
706+
};
707+
return new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
708+
}
709+
710+
private void doPaint(ILineRange visibleLines, Point size) {
686711
GC bufferGC= new GC(fBuffer);
687712
Image newBuffer= null;
688713
try {
@@ -696,7 +721,7 @@ private void doubleBufferPaint(GC dest) {
696721
int bottomWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, bottomModelLine);
697722
boolean atEnd= bottomWidgetLine + 1 >= fCachedTextWidget.getLineCount();
698723
int height= size.y;
699-
if (dy != 0 && !atEnd && bufferStillValid && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) {
724+
if (dy != 0 && !atEnd && fLastTopPixel >= 0 && numberOfLines > 1 && numberOfLines == fLastNumberOfLines) {
700725
int bottomPixel= fCachedTextWidget.getLinePixel(bottomWidgetLine + 1);
701726
if (dy > 0 && bottomPixel < size.y) {
702727
// Can occur on GTK with static scrollbars; see bug 551320.
@@ -745,16 +770,7 @@ private void doubleBufferPaint(GC dest) {
745770
fLastBottomModelLine= bottomModelLine;
746771
fLastHeight= height;
747772
if (dy != 0) {
748-
// Some rulers may paint outside the line region. Let them paint in a new image,
749-
// the copy the wanted bits.
750-
newBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
751-
GC localGC= new GC(newBuffer);
752-
try {
753-
initializeGC(localGC, 0, bufferY, size.x, bufferH);
754-
doPaint(localGC, visibleLines);
755-
} finally {
756-
localGC.dispose();
757-
}
773+
newBuffer= newBufferImage(size, bufferY, bufferH, visibleLines);
758774
bufferGC.drawImage(newBuffer, 0, bufferY, size.x, bufferH, 0, bufferY, size.x, bufferH);
759775
if (dy > 0 && bufferY + bufferH < size.y) {
760776
// 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) {
774790
newBuffer.dispose();
775791
}
776792
}
777-
dest.drawImage(fBuffer, 0, 0);
793+
}
794+
795+
private Image newBufferImage(Point size, int bufferY, int bufferH, final ILineRange visibleLines) {
796+
ImageGcDrawer imageGcDrawer= (localGC, imageWidth, imageHeight) -> {
797+
// Some rulers may paint outside the line region. Let them paint in a new image,
798+
// the copy the wanted bits.
799+
initializeGC(localGC, 0, bufferY, imageWidth, bufferH);
800+
doPaint(localGC, visibleLines);
801+
};
802+
return new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
778803
}
779804

780805
private void initializeGC(GC gc, int x, int y, int width, int height) {

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,13 @@ public void mouseEnter(MouseEvent e) {
597597
fTextViewer= null;
598598
});
599599

600+
fCanvas.addListener(SWT.ZoomChanged, e -> {
601+
if (fBuffer != null) {
602+
fBuffer.dispose();
603+
fBuffer= null;
604+
}
605+
});
606+
600607
fCanvas.addMouseListener(new MouseAdapter() {
601608
@Override
602609
public void mouseDown(MouseEvent event) {
@@ -676,23 +683,27 @@ private void doubleBufferPaint(GC dest) {
676683
fBuffer= null;
677684
}
678685
}
679-
if (fBuffer == null)
680-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
681-
682-
GC gc= new GC(fBuffer);
683-
try {
684-
gc.setBackground(fCanvas.getBackground());
685-
gc.fillRectangle(0, 0, size.x, size.y);
686+
if (fBuffer == null) {
687+
fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y);
688+
} else {
689+
GC gc= new GC(fBuffer);
690+
try {
691+
doPaint(gc, size.x, size.y);
692+
} finally {
693+
gc.dispose();
694+
}
695+
}
686696

687-
cacheAnnotations();
697+
dest.drawImage(fBuffer, 0, 0);
698+
}
688699

689-
doPaint(gc);
700+
private void doPaint(GC gc, int width, int height) {
701+
gc.setBackground(fCanvas.getBackground());
702+
gc.fillRectangle(0, 0, width, height);
690703

691-
} finally {
692-
gc.dispose();
693-
}
704+
cacheAnnotations();
694705

695-
dest.drawImage(fBuffer, 0, 0);
706+
doPaint(gc);
696707
}
697708

698709
private void cacheAnnotations() {

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,13 @@ public Control createControl(Composite parent, ITextViewer textViewer) {
159159
fTextViewer= null;
160160
});
161161

162+
fCanvas.addListener(SWT.ZoomChanged, e -> {
163+
if (fBuffer != null) {
164+
fBuffer.dispose();
165+
fBuffer= null;
166+
}
167+
});
168+
162169
fCanvas.addMouseListener(new MouseListener() {
163170
@Override
164171
public void mouseUp(MouseEvent event) {
@@ -223,27 +230,31 @@ private void doubleBufferPaint(GC dest) {
223230
fBuffer= null;
224231
}
225232
}
226-
if (fBuffer == null)
227-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
228-
229-
GC gc= new GC(fBuffer);
230-
gc.setFont(fTextViewer.getTextWidget().getFont());
231-
try {
232-
gc.setBackground(fCanvas.getBackground());
233-
gc.fillRectangle(0, 0, size.x, size.y);
234-
235-
if (fTextViewer instanceof ITextViewerExtension5)
236-
doPaint1(gc);
237-
else
238-
doPaint(gc);
239233

240-
} finally {
241-
gc.dispose();
234+
if (fBuffer == null) {
235+
fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y);
236+
} else {
237+
GC gc= new GC(fBuffer);
238+
try {
239+
doPaint(gc, size.x, size.y);
240+
} finally {
241+
gc.dispose();
242+
}
242243
}
243-
244244
dest.drawImage(fBuffer, 0, 0);
245245
}
246246

247+
private void doPaint(GC gc, int width, int height) {
248+
gc.setFont(fTextViewer.getTextWidget().getFont());
249+
gc.setBackground(fCanvas.getBackground());
250+
gc.fillRectangle(0, 0, width, height);
251+
252+
if (fTextViewer instanceof ITextViewerExtension5)
253+
doPaint1(gc);
254+
else
255+
doPaint(gc);
256+
}
257+
247258
/**
248259
* Returns the document offset of the upper left corner of the
249260
* widgets view port, possibly including partially visible lines.

0 commit comments

Comments
 (0)