diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java index 510bcb33490..35cb21c1e8e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java @@ -150,9 +150,10 @@ public static ImageData autoScaleImageData (Device device, final ImageData image int height = imageData.height; int scaledWidth = Math.round (width * scaleFactor); int scaledHeight = Math.round (height * scaleFactor); + int defaultZoomLevel = 100; boolean useSmoothScaling = isSmoothScalingEnabled() && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK; if (useSmoothScaling) { - Image original = new Image (device, (ImageDataProvider) zoom -> imageData); + Image original = new Image(device, (ImageDataProvider) zoom -> (zoom == defaultZoomLevel) ? imageData : null); ImageGcDrawer drawer = new ImageGcDrawer() { @Override public void drawOn(GC gc, int imageWidth, int imageHeight) { @@ -166,7 +167,7 @@ public int getGcStyle() { } }; Image resultImage = new Image (device, drawer, scaledWidth, scaledHeight); - ImageData result = resultImage.getImageData (100); + ImageData result = resultImage.getImageData (defaultZoomLevel); original.dispose (); resultImage.dispose (); return result; 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 28bb30fd718..e014b760de7 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 @@ -612,10 +612,33 @@ public Image(Device device, ImageDataProvider imageDataProvider) { SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom."); } + if (Device.strictChecks) { + validateLinearScaling(imageDataProvider); + } init(); this.device.registerResourceWithZoomSupport(this); } +private void validateLinearScaling(ImageDataProvider provider) { + final int baseZoom = 100; + final int scaledZoom = 200; + final int scaleFactor = scaledZoom / baseZoom; + ImageData baseImageData = provider.getImageData(baseZoom); + ImageData scaledImageData = provider.getImageData(scaledZoom); + + if (scaledImageData == null) { + return; + } + + if (scaledImageData.width != scaleFactor * baseImageData.width + || scaledImageData.height != scaleFactor * baseImageData.height) { + System.err.println(String.format( + "***WARNING: ImageData should be linearly scaled across zooms but size is (%d, %d) at 100%% and (%d, %d) at 200%%.", + baseImageData.width, baseImageData.height, scaledImageData.width, scaledImageData.height)); + new Error().printStackTrace(System.err); + } +} + /** * The provided ImageGcDrawer will be called on demand whenever a new variant of the * Image for an additional zoom is required. Depending on the OS-specific implementation diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java index c6a87e37a97..23b036d6923 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java @@ -1043,13 +1043,15 @@ public void test_imageDataIsCached() { public void test_imageDataSameViaDifferentProviders() { assumeFalse("Cocoa generates inconsistent image data", SwtTestUtil.isCocoa); String imagePath = getPath("collapseall.png"); - ImageFileNameProvider imageFileNameProvider = __ -> { - return imagePath; + ImageFileNameProvider imageFileNameProvider = zoom -> { + return (zoom == 100) ? imagePath : null; }; - ImageDataProvider dataProvider = __ -> { - try (InputStream imageStream = Files.newInputStream(Path.of(imagePath))) { - return new ImageData(imageStream); - } catch (IOException e) { + ImageDataProvider dataProvider = zoom -> { + if (zoom == 100) { + try (InputStream imageStream = Files.newInputStream(Path.of(imagePath))) { + return new ImageData(imageStream); + } catch (IOException e) { + } } return null; }; diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java index cd4a598799b..ab357a7b562 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java @@ -54,17 +54,11 @@ public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageFileNameProvid @Test public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageDataProvider() { - ImageDataProvider validImageDataProvider = zoom -> { - String fileName = "collapseall.svg"; - return new ImageData(getPath(fileName)); - }; + ImageDataProvider validImageDataProvider = zoom -> (zoom == 100) ? new ImageData(getPath("collapseall.svg")) : null; Image image = new Image(Display.getDefault(), validImageDataProvider); image.dispose(); - ImageDataProvider corruptImageDataProvider = zoom -> { - String fileName = "corrupt.svg"; - return new ImageData(getPath(fileName)); - }; + ImageDataProvider corruptImageDataProvider = zoom -> (zoom == 100) ? new ImageData(getPath("corrupt.svg")) : null; SWTException e = assertThrows(SWTException.class, () -> new Image(Display.getDefault(), corruptImageDataProvider)); assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e);