diff --git a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java index 6b60c2a20df..8a4ce184f1e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java @@ -25,6 +25,90 @@ @ExtendWith(WithMonitorSpecificScalingExtension.class) class ImagesWin32Tests { + @Test + public void test_imageScaledFrom150_when125PercentImageUnavailable() { + Display display = Display.getDefault(); + GC gc = new GC(display); + GCData gcData = gc.getGCData(); + gcData.nativeZoom = 125; + ImageDataProvider imageDataProviderReturnsNullAt125 = zoom -> { + if (zoom == 125) { + return null; + } + float scaleFactor = zoom / 100f; + int scaledWidth = Math.round(16 * scaleFactor); + int scaledHeight = Math.round(16 * scaleFactor); + return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0))); + }; + Image image = new Image(display, imageDataProviderReturnsNullAt125); + gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16); + gc.dispose(); + image.dispose(); + } + + @Test + public void test_imageScaledFrom100_when125And150PercentImagesUnavailable() { + Display display = Display.getDefault(); + GC gc = new GC(display); + GCData gcData = gc.getGCData(); + gcData.nativeZoom = 125; + ImageDataProvider imageDataProviderReturnsNullAt125and150 = zoom -> { + if (zoom == 125) { + return null; + } + if (zoom == 150) { + return null; + } + float scaleFactor = zoom / 100f; + int scaledWidth = Math.round(16 * scaleFactor); + int scaledHeight = Math.round(16 * scaleFactor); + return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0))); + }; + Image image = new Image(display, imageDataProviderReturnsNullAt125and150); + gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16); + gc.dispose(); + image.dispose(); + } + + @Test + public void test_drawImage_when130PercentImageUnavailable() { + Display display = Display.getDefault(); + GC gc = new GC(display); + GCData gcData = gc.getGCData(); + gcData.nativeZoom = 130; + ImageDataProvider imageDataProviderReturnsNullAt125 = zoom -> { + if (zoom == 130){ + return null; + } + float scaleFactor = zoom / 100f; + int scaledWidth = Math.round(16 * scaleFactor); + int scaledHeight = Math.round(16 * scaleFactor); + return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0))); + }; + Image image = new Image(display, imageDataProviderReturnsNullAt125); + gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16); + gc.dispose(); + image.dispose(); + } + + @Test + public void test_drawImageUsesWronglyScaledImageDataProvider() { + Display display = Display.getDefault(); + GC gc = new GC(display); + GCData gcData = gc.getGCData(); + gcData.nativeZoom = 125; + ImageDataProvider incorrectlyScaledimageDataProvider = zoom -> { + int scaleFactor = zoom / 100; + int scaledWidth = Math.round(16 * scaleFactor); + int scaledHeight = Math.round(16 * scaleFactor); + return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0))); + }; + Image image = new Image(display, incorrectlyScaledimageDataProvider); + gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16); + gc.dispose(); + image.dispose(); + } + @Test public void testImageIconTypeShouldNotChangeAfterCallingGetHandleForDifferentZoom() { Image icon = Display.getDefault().getSystemImage(SWT.ICON_ERROR); 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 92636ff4f3f..0cb9b4cf267 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 @@ -990,7 +990,7 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); int gcZoom = getZoom(); - int srcImageZoom = calculateZoomForImage(gcZoom, srcWidth, srcHeight, destWidth, destHeight); + int srcImageZoom = calculateZoomForImage(image, gcZoom, srcWidth, srcHeight, destWidth, destHeight); drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, gcZoom, srcImageZoom); } @@ -1003,25 +1003,29 @@ private Collection getAllCurrentMonitorZooms() { return Collections.emptySet(); } -private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) { +private int calculateZoomForImage(Image image, int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) { + int scaledImageZoom; + float imageScaleFactor = 1f * destWidth / srcWidth; + int imageZoom = Math.round(gcZoom * imageScaleFactor); if (srcWidth == 1 && srcHeight == 1) { // One pixel images can use the GC zoom - return gcZoom; - } - if (destWidth == srcWidth && destHeight == srcHeight) { + scaledImageZoom = gcZoom; + } else if (destWidth == srcWidth && destHeight == srcHeight) { // unscaled images can use the GC zoom - return gcZoom; - } - - float imageScaleFactor = 1f * destWidth / srcWidth; - int imageZoom = Math.round(gcZoom * imageScaleFactor); - if (getAllCurrentMonitorZooms().contains(imageZoom)) { - return imageZoom; - } - if (imageZoom > 150) { - return 200; - } - return 100; + scaledImageZoom = gcZoom; + } else if (getAllCurrentMonitorZooms().contains(imageZoom)) { + scaledImageZoom = imageZoom; + } else if (imageZoom > 150) { + scaledImageZoom = 200; + } else { + scaledImageZoom = 100; + } + Rectangle scaledBounds = image.getBounds(scaledImageZoom); + Rectangle unScaledBound = image.getBounds(); + // validates if the image bounds are scaled up correctly as per required zoom, if it is not zoom is returned as per actual scaling factor. + float scalingFactor = (float) scaledBounds.height / unScaledBound.height; + scaledImageZoom = (int) (scalingFactor * 100); + return scaledImageZoom; } private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,