Skip to content

Commit 6284318

Browse files
committed
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 6284318

File tree

4 files changed

+92
-39
lines changed

4 files changed

+92
-39
lines changed

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

+16-6
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,14 +524,19 @@ 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+
doPaint(new GC(fBuffer), size.x, size.y);
531+
}
532+
dest.drawImage(fBuffer, 0, 0);
533+
}
522534

523-
GC gc= new GC(fBuffer);
535+
private void doPaint(GC gc, int width, int height) {
524536
gc.setFont(fCachedTextWidget.getFont());
525537
try {
526538
gc.setBackground(fCanvas.getBackground());
527-
gc.fillRectangle(0, 0, size.x, size.y);
539+
gc.fillRectangle(0, 0, width, height);
528540

529541
if (fCachedTextViewer instanceof ITextViewerExtension5)
530542
doPaint1(gc);
@@ -533,8 +545,6 @@ private void doubleBufferPaint(GC dest) {
533545
} finally {
534546
gc.dispose();
535547
}
536-
537-
dest.drawImage(fBuffer, 0, 0);
538548
}
539549

540550
/**

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

+24-13
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,10 @@ 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+
doPaint(new GC(fBuffer), size.x, size.y);
265263
}
266264

267265
dest.drawImage(fBuffer, 0, 0);
@@ -291,6 +289,19 @@ protected final boolean isViewerCompletelyShown() {
291289
return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget);
292290
}
293291

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

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

+35-13
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) {

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

+17-7
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,26 @@ private void doubleBufferPaint(GC dest) {
676683
fBuffer= null;
677684
}
678685
}
679-
if (fBuffer == null)
680-
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
686+
if (fBuffer == null) {
687+
fBuffer= new Image(fCanvas.getDisplay(), this::doPaint, size.x, size.y);
688+
} else {
689+
doPaint(new GC(fBuffer), size.x, size.y);
690+
}
681691

682-
GC gc= new GC(fBuffer);
692+
dest.drawImage(fBuffer, 0, 0);
693+
}
694+
695+
private void doPaint(GC gc, int width, int height) {
683696
try {
684697
gc.setBackground(fCanvas.getBackground());
685-
gc.fillRectangle(0, 0, size.x, size.y);
698+
gc.fillRectangle(0, 0, width, height);
686699

687700
cacheAnnotations();
688701

689702
doPaint(gc);
690-
691703
} finally {
692704
gc.dispose();
693705
}
694-
695-
dest.drawImage(fBuffer, 0, 0);
696706
}
697707

698708
private void cacheAnnotations() {

0 commit comments

Comments
 (0)