From 5aeb924ae7c23651c23c78bae8e3b6f40e810f15 Mon Sep 17 00:00:00 2001 From: Andreas Koch Date: Fri, 1 Nov 2024 14:56:18 +0100 Subject: [PATCH] [win32] workaround for ImageDataProvider implementation This commit adds a workaround for ImageDataProvider implementations that instantiate new Images inside the getImageData(zoom) implementation. This image can be instantiated with the wrong zoom in a multi zoom setting as Images still relay on the static zoom value in DPIUtil. This workaround should be replaced by a proper solution. Contributes to #62 and #131 --- .../win32/org/eclipse/swt/graphics/Image.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) 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 3a8cbb748d..74b9503dac 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 @@ -22,6 +22,7 @@ import org.eclipse.swt.internal.DPIUtil.*; import org.eclipse.swt.internal.gdip.*; import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.widgets.*; /** * Instances of this class are graphics which have been prepared @@ -819,7 +820,10 @@ public static Long win32_getHandle (Image image, int zoom) { image.init(newData, zoom); } } else if (image.imageDataProvider != null) { - ElementAtZoom imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (image.imageDataProvider, zoom); + ElementAtZoom imageCandidate; + try (StaticZoomUpdater unused = image.new StaticZoomUpdater(zoom)) { + imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (image.imageDataProvider, zoom); + } ImageData resizedData = DPIUtil.scaleImageData (image.device, imageCandidate.element(), zoom, imageCandidate.zoom()); ImageData newData = image.adaptImageDataIfDisabledOrGray(resizedData); image.init(newData, zoom); @@ -1443,7 +1447,10 @@ public ImageData getImageData (int zoom) { if (zoom == currentZoom) { return getImageDataAtCurrentZoom(); } else if (imageDataProvider != null) { - ElementAtZoom data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom); + ElementAtZoom data; + try (StaticZoomUpdater unused = new StaticZoomUpdater(zoom)) { + data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom); + } return DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom()); } else if (imageFileNameProvider != null) { ElementAtZoom fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, zoom); @@ -2397,4 +2404,25 @@ public static Image win32_new(Device device, int type, long handle) { image.setHandleForZoomLevel(handle, image.getZoom()); return image; } + +// This class is only used for a workaround and will be removed again +private class StaticZoomUpdater implements AutoCloseable { + private final boolean updateStaticZoom; + private final int currentNativeDeviceZoom; + + private StaticZoomUpdater(int targetZoom) { + this.currentNativeDeviceZoom = DPIUtil.getNativeDeviceZoom(); + this.updateStaticZoom = this.currentNativeDeviceZoom != targetZoom && device instanceof Display display && display.isRescalingAtRuntime(); + if (updateStaticZoom) { + DPIUtil.setDeviceZoom(targetZoom); + } + } + + @Override + public void close() { + if (updateStaticZoom) { + DPIUtil.setDeviceZoom(currentNativeDeviceZoom); + } + } +} }