Skip to content

Commit 8b2a4c3

Browse files
committed
A strict check 200% image data is double the size of 100% image data
A strict check to be used only for debugging means, this ensures the imageData is scaled linearly for 100 and 200 zooms.
1 parent 649bb49 commit 8b2a4c3

File tree

5 files changed

+73
-12
lines changed

5 files changed

+73
-12
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,12 @@ private static ImageData autoScaleImageData (Device device, final ImageData imag
299299
int height = imageData.height;
300300
int scaledWidth = Math.round (width * scaleFactor);
301301
int scaledHeight = Math.round (height * scaleFactor);
302+
int defaultZoomLevel = 100;
302303
boolean useSmoothScaling = isSmoothScalingEnabled() && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK;
303304
if (useSmoothScaling) {
304-
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
305+
Image original = new Image(device, (ImageDataProvider) zoom -> {
306+
return (zoom == defaultZoomLevel) ? imageData : null;
307+
});
305308
ImageGcDrawer drawer = new ImageGcDrawer() {
306309
@Override
307310
public void drawOn(GC gc, int imageWidth, int imageHeight) {
@@ -315,7 +318,7 @@ public int getGcStyle() {
315318
}
316319
};
317320
Image resultImage = new Image (device, drawer, scaledWidth, scaledHeight);
318-
ImageData result = resultImage.getImageData (100);
321+
ImageData result = resultImage.getImageData (defaultZoomLevel);
319322
original.dispose ();
320323
resultImage.dispose ();
321324
return result;

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,29 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
610610
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
611611
": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom.");
612612
}
613+
if (Device.strictChecks) {
614+
validateLinearScaling(imageDataProvider);
615+
}
613616
init();
614617
this.device.registerResourceWithZoomSupport(this);
615618
}
616619

620+
private void validateLinearScaling(ImageDataProvider provider) {
621+
final int baseZoom = 100;
622+
final int scaledZoom = 200;
623+
final int scaleFactor = scaledZoom / baseZoom;
624+
ImageData baseImageData = provider.getImageData(baseZoom);
625+
ImageData scaledImageData = provider.getImageData(scaledZoom);
626+
627+
if (scaledImageData == null) {
628+
return;
629+
}
630+
631+
if (scaledImageData.width != scaleFactor * baseImageData.width || scaledImageData.height != scaleFactor * baseImageData.height) {
632+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "ImageData should be linearly scaled across zooms.");
633+
}
634+
}
635+
617636
/**
618637
* The provided ImageGcDrawer will be called on demand whenever a new variant of the
619638
* Image for an additional zoom is required. Depending on the OS-specific implementation

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,13 +1031,15 @@ public void test_imageDataIsCached() {
10311031
public void test_imageDataSameViaDifferentProviders() {
10321032
assumeFalse("Cocoa generates inconsistent image data", SwtTestUtil.isCocoa);
10331033
String imagePath = getPath("collapseall.png");
1034-
ImageFileNameProvider imageFileNameProvider = __ -> {
1035-
return imagePath;
1034+
ImageFileNameProvider imageFileNameProvider = zoom -> {
1035+
return (zoom == 100) ? imagePath : null;
10361036
};
1037-
ImageDataProvider dataProvider = __ -> {
1038-
try (InputStream imageStream = Files.newInputStream(Path.of(imagePath))) {
1039-
return new ImageData(imageStream);
1040-
} catch (IOException e) {
1037+
ImageDataProvider dataProvider = zoom -> {
1038+
if (zoom == 100) {
1039+
try (InputStream imageStream = Files.newInputStream(Path.of(imagePath))) {
1040+
return new ImageData(imageStream);
1041+
} catch (IOException e) {
1042+
}
10411043
}
10421044
return null;
10431045
};

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_ImageData.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import static org.junit.Assert.assertNotNull;
2525
import static org.junit.Assert.assertNull;
2626
import static org.junit.Assert.assertThrows;
27+
import static org.junit.Assert.fail;
28+
import static org.junit.Assume.assumeNotNull;
29+
import static org.junit.Assume.assumeTrue;
2730

2831
import java.io.IOException;
2932
import java.io.InputStream;
@@ -32,8 +35,10 @@
3235

3336
import org.eclipse.swt.SWT;
3437
import org.eclipse.swt.SWTException;
38+
import org.eclipse.swt.graphics.GC;
3539
import org.eclipse.swt.graphics.Image;
3640
import org.eclipse.swt.graphics.ImageData;
41+
import org.eclipse.swt.graphics.ImageDataProvider;
3742
import org.eclipse.swt.graphics.PaletteData;
3843
import org.eclipse.swt.graphics.RGB;
3944
import org.eclipse.swt.tests.graphics.ImageDataTestHelper;
@@ -799,6 +804,40 @@ public void test_setAlphaIII() {
799804
assertSWTProblem("Incorrect exception thrown for putWidth < 0", SWT.ERROR_INVALID_ARGUMENT, ex);
800805
}
801806

807+
@Test
808+
public void test_ImageCreationFailsWithNonScalingImageDataProviderWhenStrictCheckIsEnabled() {
809+
assumeNotNull(System.getProperty("org.eclipse.swt.internal.enableStrictChecks"));
810+
Display display = Display.getDefault();
811+
GC gc = new GC(display);
812+
try {
813+
ImageDataProvider wrongDataProvider = (zoom) -> new ImageData(16, 16, 32, new PaletteData());
814+
Image image = new Image(display, wrongDataProvider);
815+
image.dispose();
816+
fail("Expected an exception due to non-linearly scaled image data provider");
817+
} catch (IllegalArgumentException | SWTException e) {
818+
} finally {
819+
gc.dispose();
820+
display.dispose();
821+
}
822+
}
823+
824+
@Test
825+
public void test_ImageCreationFailsWithNonScalingImageDataProviderWhenStrictCheckIsDisabled() {
826+
assumeTrue(System.getProperty("org.eclipse.swt.internal.enableStrictChecks") == null);
827+
Display display = Display.getDefault();
828+
GC gc = new GC(display);
829+
try {
830+
ImageDataProvider wrongDataProvider = (zoom) -> new ImageData(16, 16, 32, new PaletteData());
831+
Image image = new Image(display, wrongDataProvider);
832+
image.dispose();
833+
} catch (IllegalArgumentException | SWTException e) {
834+
fail("Image creation is expected to succeed without strict checks, even for a non-scaling ImageDataProvider.");
835+
} finally {
836+
gc.dispose();
837+
display.dispose();
838+
}
839+
}
840+
802841
@Test
803842
public void test_setPixelIII() {
804843
int value;

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,13 @@ public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageFileNameProvid
5555
@Test
5656
public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageDataProvider() {
5757
ImageDataProvider validImageDataProvider = zoom -> {
58-
String fileName = "collapseall.svg";
59-
return new ImageData(getPath(fileName));
58+
return (zoom == 100) ? new ImageData(getPath("collapseall.svg")) : null;
6059
};
6160
Image image = new Image(Display.getDefault(), validImageDataProvider);
6261
image.dispose();
6362

6463
ImageDataProvider corruptImageDataProvider = zoom -> {
65-
String fileName = "corrupt.svg";
66-
return new ImageData(getPath(fileName));
64+
return (zoom == 100) ? new ImageData(getPath("corrupt.svg")) : null;
6765
};
6866
SWTException e = assertThrows(SWTException.class,
6967
() -> new Image(Display.getDefault(), corruptImageDataProvider));

0 commit comments

Comments
 (0)