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..a7559354653 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 Yatta Solutions + * Copyright (c) 2024, 2026 Yatta Solutions * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,13 +13,18 @@ *******************************************************************************/ package org.eclipse.swt.graphics; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.*; +import java.util.stream.*; import org.eclipse.swt.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.widgets.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; @ExtendWith(PlatformSpecificExecutionExtension.class) @ExtendWith(WithMonitorSpecificScalingExtension.class) @@ -30,9 +35,52 @@ public void testImageIconTypeShouldNotChangeAfterCallingGetHandleForDifferentZoo Image icon = Display.getDefault().getSystemImage(SWT.ICON_ERROR); try { Image.win32_getHandle(icon, 200); - assertEquals("Image type should stay to SWT.ICON", SWT.ICON, icon.type); + assertEquals(SWT.ICON, icon.type, "Image type should stay to SWT.ICON"); } finally { icon.dispose(); } } + + /** + * For images with very different width and height (e.g. 500x2), independent + * integer division when computing the zoom from each axis's pixel hint can make the + * height-derived zoom larger than the width-derived zoom. The correct fix is to + * derive the zoom from the axis with the larger pixel hint, which has more pixels + * and therefore a proportionally smaller rounding error. + *
+ * Verifies that for a wide (500-pixel) image at standard display zoom levels, the
+ * selected handle width matches the expected width at the requested zoom, across a
+ * range of image heights where integer-division rounding divergence is most extreme.
+ */
+ @ParameterizedTest
+ @MethodSource("provideZoomAndHeightCombinations")
+ public void getImageHandle_asymmetricDimensions_selectsCorrectZoom(int displayZoom, int logicalHeight) {
+ Display display = Display.getDefault();
+ int logicalWidth = 500;
+ PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
+ ImageDataProvider provider = zoom -> new ImageData(
+ Math.max(1, Math.round(logicalWidth * zoom / 100f)),
+ Math.max(1, Math.round(logicalHeight * zoom / 100f)),
+ 32, palette);
+ Image image = new Image(display, provider);
+ int widthHint = Math.round(logicalWidth * displayZoom / 100f);
+ int heightHint = Math.round(logicalHeight * displayZoom / 100f);
+ int[] capturedWidth = {-1};
+ try {
+ image.executeOnImageHandleAtBestFittingSize(h -> capturedWidth[0] = h.width(), widthHint, heightHint);
+ assertEquals(widthHint, capturedWidth[0],
+ "Handle width should match widthHint for a " + logicalWidth + "x" + logicalHeight
+ + " image at display zoom " + displayZoom + "%: expected " + widthHint
+ + " but got " + capturedWidth[0]);
+ } finally {
+ image.dispose();
+ }
+ }
+
+ private static Stream