diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index 1f4fbb1a9b..b8acce453e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -4901,16 +4901,31 @@ public void setBackgroundPattern (Pattern pattern) { storeAndApplyOperationForExistingHandle(new SetBackgroundPatternOperation(pattern)); } -private class SetBackgroundPatternOperation extends Operation { - private final Pattern pattern; +private abstract class PatternOperation extends Operation { + private Pattern pattern; + PatternOperation(Pattern pattern) { + this.pattern = pattern; + } + + protected Pattern getPattern() { + if (pattern != null && pattern.isDisposed()) { + // recreate locally managed pattern if the original was disposed + pattern = pattern.copy(); + registerForDisposal(pattern); + } + return pattern; + } +} + +private class SetBackgroundPatternOperation extends PatternOperation { SetBackgroundPatternOperation(Pattern pattern) { - this.pattern = pattern == null ? null : pattern.copy(); - registerForDisposal(this.pattern); + super(pattern); } @Override void apply() { + Pattern pattern = getPattern(); if (data.gdipGraphics == 0 && pattern == null) return; initGdip(); if (data.backgroundPattern == pattern) return; @@ -5249,16 +5264,15 @@ public void setForegroundPattern (Pattern pattern) { storeAndApplyOperationForExistingHandle(new SetForegroundPatternOperation(pattern)); } -private class SetForegroundPatternOperation extends Operation { - private final Pattern pattern; +private class SetForegroundPatternOperation extends PatternOperation { SetForegroundPatternOperation(Pattern pattern) { - this.pattern = pattern == null ? null : pattern.copy(); - registerForDisposal(this.pattern); + super(pattern); } @Override void apply() { + Pattern pattern = getPattern(); if (data.gdipGraphics == 0 && pattern == null) return; initGdip(); if (data.foregroundPattern == pattern) return; @@ -5990,8 +6004,11 @@ Point textExtentInPixels(String string, int flags) { return new Point(rect.right, rect.bottom); } -void refreshFor(Drawable drawable, ImageHandle imageHandle) { +void reapplyTo(Drawable drawable, ImageHandle imageHandle) { if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (!data.reapplicable) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } destroy(); GCData newData = new GCData(); originalData.copyTo(newData); @@ -6097,9 +6114,13 @@ int getZoom() { } private void storeAndApplyOperationForExistingHandle(Operation operation) { - removePreviousOperationIfSupercededBy(operation); - operations.add(operation); operation.apply(); + if (data.reapplicable) { + removePreviousOperationIfSupercededBy(operation); + operations.add(operation); + } else { + operation.disposeAll(); + } } private void removePreviousOperationIfSupercededBy(Operation operation) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java index a8ccae520a..d6aa237167 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java @@ -49,6 +49,7 @@ public final class GCData { public int alpha = 0xFF; public int nativeZoom; int imageZoom; + boolean reapplicable; public Image image; public PAINTSTRUCT ps; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 76ccd1c7b9..fe0c3a3f31 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -2333,6 +2333,7 @@ public Collection getPreservedZoomLevels() { @Override protected long configureGCData(GCData data) { + data.reapplicable = true; return configureGC(data, new ZoomContext(DPIUtil.getDeviceZoom(), DPIUtil.getNativeDeviceZoom())); } @@ -2374,7 +2375,7 @@ protected DestroyableImageHandle newImageHandle(ZoomContext zoomContext) { GC currentGC = memGC; memGC = null; DestroyableImageHandle imageHandle = createHandle(targetZoom); - currentGC.refreshFor(new DrawableWrapper(Image.this, zoomContext), imageHandle); + currentGC.reapplyTo(new DrawableWrapper(Image.this, zoomContext), imageHandle); return imageHandle; } diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java index cafb4f9146..2806c1d865 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java @@ -487,8 +487,8 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_ImageDataAtSizePro Exception e = assertThrows(IllegalArgumentException.class, () -> gc.drawImage(image, 0, 0, 1, 1)); assertSWTProblem("Incorrect exception thrown for provider == null", SWT.ERROR_INVALID_ARGUMENT, e); } finally { - image.dispose(); drawToImage.dispose(); + image.dispose(); } }