Skip to content

Commit a2298c9

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 aff1ccc commit a2298c9

File tree

3 files changed

+82
-31
lines changed

3 files changed

+82
-31
lines changed

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.eclipse.swt.graphics.Font;
3636
import org.eclipse.swt.graphics.GC;
3737
import org.eclipse.swt.graphics.Image;
38+
import org.eclipse.swt.graphics.ImageGcDrawer;
3839
import org.eclipse.swt.graphics.Point;
3940
import org.eclipse.swt.graphics.Rectangle;
4041
import org.eclipse.swt.widgets.Canvas;
@@ -266,6 +267,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl
266267
fCachedTextWidget= null;
267268
});
268269

270+
fCanvas.addListener(SWT.ZoomChanged, e -> {
271+
if (fBuffer != null) {
272+
fBuffer.dispose();
273+
fBuffer= null;
274+
}
275+
});
276+
269277
fMouseListener= new MouseListener() {
270278
@Override
271279
public void mouseUp(MouseEvent event) {
@@ -517,10 +525,18 @@ private void doubleBufferPaint(GC dest) {
517525
fBuffer= null;
518526
}
519527
}
520-
if (fBuffer == null)
521-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
528+
if (fBuffer == null) {
529+
ImageGcDrawer imageGcDrawer= (gc, imageWidth, imageHeight) -> {
530+
doPaint(gc, new Point(imageWidth, imageHeight));
531+
};
532+
fBuffer= new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
533+
} else {
534+
doPaint(new GC(fBuffer), size);
535+
}
536+
dest.drawImage(fBuffer, 0, 0);
537+
}
522538

523-
GC gc= new GC(fBuffer);
539+
private void doPaint(GC gc, Point size) {
524540
gc.setFont(fCachedTextWidget.getFont());
525541
try {
526542
gc.setBackground(fCanvas.getBackground());
@@ -533,8 +549,6 @@ private void doubleBufferPaint(GC dest) {
533549
} finally {
534550
gc.dispose();
535551
}
536-
537-
dest.drawImage(fBuffer, 0, 0);
538552
}
539553

540554
/**

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

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.eclipse.swt.graphics.Font;
2323
import org.eclipse.swt.graphics.GC;
2424
import org.eclipse.swt.graphics.Image;
25+
import org.eclipse.swt.graphics.ImageGcDrawer;
2526
import org.eclipse.swt.graphics.Point;
2627
import org.eclipse.swt.graphics.Rectangle;
2728
import org.eclipse.swt.widgets.Canvas;
@@ -199,6 +200,13 @@ public Control createControl(CompositeRuler parentRuler, Composite parentControl
199200
fCachedTextWidget= null;
200201
});
201202

203+
fCanvas.addListener(SWT.ZoomChanged, e -> {
204+
if (fBuffer != null) {
205+
fBuffer.dispose();
206+
fBuffer= null;
207+
}
208+
});
209+
202210
fCanvas.addMouseListener(fMouseHandler);
203211
fCanvas.addMouseMoveListener(fMouseHandler);
204212

@@ -249,19 +257,13 @@ private void doubleBufferPaint(GC dest) {
249257
fBuffer= null;
250258
}
251259
}
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();
260+
if (fBuffer == null) {
261+
ImageGcDrawer imageGcDrawer= (gc, imageWidth, imageHeight) -> {
262+
doPaint(gc, new Point(imageWidth, imageHeight));
263+
};
264+
fBuffer= new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
265+
} else {
266+
doPaint(new GC(fBuffer), size);
265267
}
266268

267269
dest.drawImage(fBuffer, 0, 0);
@@ -291,6 +293,19 @@ protected final boolean isViewerCompletelyShown() {
291293
return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget);
292294
}
293295

296+
private void doPaint(GC gc, Point size) {
297+
gc.setFont(fCanvas.getFont());
298+
299+
try {
300+
gc.setBackground(getBackground());
301+
gc.fillRectangle(0, 0, size.x, size.y);
302+
303+
doPaint(gc);
304+
} finally {
305+
gc.dispose();
306+
}
307+
}
308+
294309
/**
295310
* Draws the ruler column.
296311
*

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

Lines changed: 35 additions & 13 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);
@@ -681,8 +688,17 @@ private void doubleBufferPaint(GC dest) {
681688

682689
boolean bufferStillValid = fBuffer != null;
683690
if (fBuffer == null) {
684-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
685-
}
691+
ImageGcDrawer imageGcDrawer= (gc, imageWidth, imageHeight) -> {
692+
ILineRange lines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer);
693+
if (lines == null) {
694+
return;
695+
}
696+
// We redraw everything; paint directly into the buffer
697+
initializeGC(gc, 0, 0, imageWidth, imageHeight);
698+
doPaint(gc, lines);
699+
};
700+
fBuffer= new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
701+
} else {
686702
GC bufferGC= new GC(fBuffer);
687703
Image newBuffer= null;
688704
try {
@@ -745,16 +761,7 @@ private void doubleBufferPaint(GC dest) {
745761
fLastBottomModelLine= bottomModelLine;
746762
fLastHeight= height;
747763
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-
}
764+
newBuffer= newBufferImage(size, bufferY, bufferH, visibleLines);
758765
bufferGC.drawImage(newBuffer, 0, bufferY, size.x, bufferH, 0, bufferY, size.x, bufferH);
759766
if (dy > 0 && bufferY + bufferH < size.y) {
760767
// Scrolled down in the text, but didn't use the full height of the Canvas: clear
@@ -774,9 +781,24 @@ private void doubleBufferPaint(GC dest) {
774781
newBuffer.dispose();
775782
}
776783
}
784+
}
777785
dest.drawImage(fBuffer, 0, 0);
778786
}
779787

788+
private Image newBufferImage(Point size, int bufferY, int bufferH, final ILineRange visibleLines) {
789+
ImageGcDrawer imageGcDrawer= (localGC, imageWidth, imageHeight) -> {
790+
// Some rulers may paint outside the line region. Let them paint in a new image,
791+
// the copy the wanted bits.
792+
try {
793+
initializeGC(localGC, 0, bufferY, imageWidth, bufferH);
794+
doPaint(localGC, visibleLines);
795+
} finally {
796+
localGC.dispose();
797+
}
798+
};
799+
return new Image(fCanvas.getDisplay(), imageGcDrawer, size.x, size.y);
800+
}
801+
780802
private void initializeGC(GC gc, int x, int y, int width, int height) {
781803
gc.setFont(fCanvas.getFont());
782804
if (fForeground != null) {

0 commit comments

Comments
 (0)