Skip to content

Commit 7ede441

Browse files
committed
Ensure DrawImage deals with scenario ImageData not linearly scaled
This change makes sure DrawImage handles the scenario where ImageData may not be linearly scaled across zooms.
1 parent 649bb49 commit 7ede441

File tree

2 files changed

+102
-13
lines changed
  • bundles/org.eclipse.swt

2 files changed

+102
-13
lines changed

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,90 @@
2525
@ExtendWith(WithMonitorSpecificScalingExtension.class)
2626
class ImagesWin32Tests {
2727

28+
@Test
29+
public void test_imageScaledFrom150_when125PercentImageUnavailable() {
30+
Display display = Display.getDefault();
31+
GC gc = new GC(display);
32+
GCData gcData = gc.getGCData();
33+
gcData.nativeZoom = 125;
34+
ImageDataProvider imageDataProviderReturnsNullAt125 = zoom -> {
35+
if (zoom == 125) {
36+
return null;
37+
}
38+
float scaleFactor = zoom / 100f;
39+
int scaledWidth = Math.round(16 * scaleFactor);
40+
int scaledHeight = Math.round(16 * scaleFactor);
41+
return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0)));
42+
};
43+
Image image = new Image(display, imageDataProviderReturnsNullAt125);
44+
gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16);
45+
gc.dispose();
46+
image.dispose();
47+
}
48+
49+
@Test
50+
public void test_imageScaledFrom100_when125And150PercentImagesUnavailable() {
51+
Display display = Display.getDefault();
52+
GC gc = new GC(display);
53+
GCData gcData = gc.getGCData();
54+
gcData.nativeZoom = 125;
55+
ImageDataProvider imageDataProviderReturnsNullAt125and150 = zoom -> {
56+
if (zoom == 125) {
57+
return null;
58+
}
59+
if (zoom == 150) {
60+
return null;
61+
}
62+
float scaleFactor = zoom / 100f;
63+
int scaledWidth = Math.round(16 * scaleFactor);
64+
int scaledHeight = Math.round(16 * scaleFactor);
65+
return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0)));
66+
};
67+
Image image = new Image(display, imageDataProviderReturnsNullAt125and150);
68+
gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16);
69+
gc.dispose();
70+
image.dispose();
71+
}
72+
73+
@Test
74+
public void test_drawImage_when130PercentImageUnavailable() {
75+
Display display = Display.getDefault();
76+
GC gc = new GC(display);
77+
GCData gcData = gc.getGCData();
78+
gcData.nativeZoom = 130;
79+
ImageDataProvider imageDataProviderReturnsNullAt125 = zoom -> {
80+
if (zoom == 130){
81+
return null;
82+
}
83+
float scaleFactor = zoom / 100f;
84+
int scaledWidth = Math.round(16 * scaleFactor);
85+
int scaledHeight = Math.round(16 * scaleFactor);
86+
return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0)));
87+
};
88+
Image image = new Image(display, imageDataProviderReturnsNullAt125);
89+
gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16);
90+
gc.dispose();
91+
image.dispose();
92+
}
93+
94+
@Test
95+
public void test_drawImageUsesWronglyScaledImageDataProvider() {
96+
Display display = Display.getDefault();
97+
GC gc = new GC(display);
98+
GCData gcData = gc.getGCData();
99+
gcData.nativeZoom = 125;
100+
ImageDataProvider incorrectlyScaledimageDataProvider = zoom -> {
101+
int scaleFactor = zoom / 100;
102+
int scaledWidth = Math.round(16 * scaleFactor);
103+
int scaledHeight = Math.round(16 * scaleFactor);
104+
return new ImageData(scaledWidth, scaledHeight, 1, new PaletteData(new RGB(255, 0, 0)));
105+
};
106+
Image image = new Image(display, incorrectlyScaledimageDataProvider);
107+
gc.drawImage(image, 0, 0, 16, 16, 0, 0, 16, 16);
108+
gc.dispose();
109+
image.dispose();
110+
}
111+
28112
@Test
29113
public void testImageIconTypeShouldNotChangeAfterCallingGetHandleForDifferentZoom() {
30114
Image icon = Display.getDefault().getSystemImage(SWT.ICON_ERROR);

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

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei
990990
if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
991991

992992
int gcZoom = getZoom();
993-
int srcImageZoom = calculateZoomForImage(gcZoom, srcWidth, srcHeight, destWidth, destHeight);
993+
int srcImageZoom = calculateZoomForImage(image, gcZoom, srcWidth, srcHeight, destWidth, destHeight);
994994
drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, gcZoom, srcImageZoom);
995995
}
996996

@@ -1003,25 +1003,30 @@ private Collection<Integer> getAllCurrentMonitorZooms() {
10031003
return Collections.emptySet();
10041004
}
10051005

1006-
private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) {
1006+
private int calculateZoomForImage(Image image, int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) {
1007+
int scaledImageZoom;
10071008
if (srcWidth == 1 && srcHeight == 1) {
10081009
// One pixel images can use the GC zoom
1009-
return gcZoom;
1010-
}
1011-
if (destWidth == srcWidth && destHeight == srcHeight) {
1010+
scaledImageZoom = gcZoom;
1011+
} else if (destWidth == srcWidth && destHeight == srcHeight) {
10121012
// unscaled images can use the GC zoom
1013-
return gcZoom;
1013+
scaledImageZoom = gcZoom;
10141014
}
1015-
10161015
float imageScaleFactor = 1f * destWidth / srcWidth;
10171016
int imageZoom = Math.round(gcZoom * imageScaleFactor);
10181017
if (getAllCurrentMonitorZooms().contains(imageZoom)) {
1019-
return imageZoom;
1020-
}
1021-
if (imageZoom > 150) {
1022-
return 200;
1023-
}
1024-
return 100;
1018+
scaledImageZoom = imageZoom;
1019+
} else if (imageZoom > 150) {
1020+
scaledImageZoom = 200;
1021+
} else {
1022+
scaledImageZoom = 100;
1023+
}
1024+
Rectangle scaledBounds = image.getBounds(scaledImageZoom);
1025+
Rectangle unScaledBound = image.getBounds();
1026+
// 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.
1027+
float scalingFactor = (float) scaledBounds.height / unScaledBound.height;
1028+
scaledImageZoom = (int) (scalingFactor * 100);
1029+
return scaledImageZoom;
10251030
}
10261031

10271032
private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY,

0 commit comments

Comments
 (0)