Skip to content

Commit 588e560

Browse files
committed
Avoid attempt to draw images with target width/height of 0
Recently, the ability to scale images for the desired target size of a drawImage operation executed on a GC and the incorporation of a Transform potentially applied to that GC have been implemented. With this, the target size for an image to be drawn can become 0 and the request of a handle of that size can fail, in particular when trying to rasterize an SVG at that size. This change adapts the implementation of the handle retrieval for a desired size in the Image implementation so that the minimum size of the provided handle is 1 in both of the dimensions. The draw operation in the GC will then take care of potentially not drawing anything at all when the actual intended size is really 0. It also adds a test case for the specific case of requesting a handle at size 0 and also adds a test for the general correctness of image handle retrieval when a transform is applied to the GC. Fixes #3078
1 parent 4a95cb2 commit 588e560

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1878,7 +1878,7 @@ public static void drawAtSize(GC gc, ImageData imageData, int width, int height)
18781878
}
18791879

18801880
void executeOnImageAtSizeBestFittingSize(Consumer<Image> imageAtBestFittingSizeConsumer, int destWidth, int destHeight) {
1881-
Optional<Image> imageAtSize = cachedImageAtSize.refresh(destWidth, destHeight);
1881+
Optional<Image> imageAtSize = cachedImageAtSize.refresh(Math.max(1, destWidth), Math.max(1, destHeight));
18821882
imageAtBestFittingSizeConsumer.accept(imageAtSize.orElse(this));
18831883
}
18841884

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ private Optional<ImageData> loadImageDataAtExactSize(int targetWidth, int target
10251025
}
10261026

10271027
void executeOnImageAtSize(Consumer<Image> imageAtBestFittingSizeConsumer, int destWidth, int destHeight) {
1028-
Optional<Image> imageAtSize = cachedImageAtSize.refresh(destWidth, destHeight);
1028+
Optional<Image> imageAtSize = cachedImageAtSize.refresh(Math.max(1, destWidth), Math.max(1, destHeight));
10291029
imageAtBestFittingSizeConsumer.accept(imageAtSize.orElse(this));
10301030
}
10311031

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,8 @@ ImageHandle getHandle (int targetZoom, int nativeZoom) {
941941
return imageHandleManager.getOrCreate(targetZoom, () -> imageProvider.newImageHandle(zoomContext));
942942
}
943943

944-
void executeOnImageHandleAtBestFittingSize(Consumer<ImageHandle> handleAtSizeConsumer, int widthHint, int heightHint) {
945-
ImageHandle imageHandle = lastRequestedHandle.refresh(widthHint, heightHint);
944+
void executeOnImageHandleAtBestFittingSize(Consumer<ImageHandle> handleAtSizeConsumer, int destWidth, int destHeight) {
945+
ImageHandle imageHandle = lastRequestedHandle.refresh(Math.max(1, destWidth), Math.max(1, destHeight));
946946
handleAtSizeConsumer.accept(imageHandle);
947947
}
948948

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import static org.junit.jupiter.api.Assumptions.assumeFalse;
2828
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2929

30+
import java.io.IOException;
31+
import java.io.InputStream;
3032
import java.lang.ref.WeakReference;
3133
import java.util.concurrent.atomic.AtomicBoolean;
3234
import java.util.concurrent.atomic.AtomicReference;
@@ -48,12 +50,15 @@
4850
import org.eclipse.swt.graphics.Rectangle;
4951
import org.eclipse.swt.graphics.Transform;
5052
import org.eclipse.swt.internal.DPIUtil;
53+
import org.eclipse.swt.tests.graphics.ImageDataTestHelper;
5154
import org.eclipse.swt.widgets.Canvas;
5255
import org.eclipse.swt.widgets.Display;
5356
import org.eclipse.swt.widgets.Shell;
5457
import org.junit.jupiter.api.AfterEach;
5558
import org.junit.jupiter.api.BeforeEach;
5659
import org.junit.jupiter.api.Test;
60+
import org.junit.jupiter.api.condition.EnabledOnOs;
61+
import org.junit.jupiter.api.condition.OS;
5762
import org.junit.jupiter.params.ParameterizedTest;
5863
import org.junit.jupiter.params.provider.ValueSource;
5964

@@ -394,6 +399,50 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII() {
394399
images.dispose();
395400
}
396401

402+
@Test
403+
@EnabledOnOs(OS.WINDOWS)
404+
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_withTransform() throws IOException {
405+
Image image = null;
406+
try (InputStream is = getClass().getResourceAsStream("collapseall.svg")) {
407+
image = new Image(Display.getDefault(), is);
408+
}
409+
Transform transform = new Transform(display, 2, 0, 0, 2, 0, 0);
410+
gc.setTransform(transform);
411+
gc.drawImage(image, 0, 0, 2, 2);
412+
ImageData resultImageDataWithTransform = getImageDataFromGC(gc, 0, 0, 4, 4);
413+
414+
gc.setTransform(null);
415+
gc.drawImage(image, 10, 10, 4, 4);
416+
ImageData resultImageDataWithoutTransform = getImageDataFromGC(gc, 10, 10, 4, 4);
417+
418+
ImageDataTestHelper.assertImageDataEqual(resultImageDataWithoutTransform, resultImageDataWithoutTransform, resultImageDataWithTransform);
419+
420+
image.dispose();
421+
transform.dispose();
422+
}
423+
424+
private ImageData getImageDataFromGC(GC gc, int x, int y, int width, int height) {
425+
Image extractionImage = new Image(display, width, height);
426+
gc.copyArea(extractionImage, x, y);
427+
ImageData resultImageData = extractionImage.getImageData();
428+
extractionImage.dispose();
429+
return resultImageData;
430+
}
431+
432+
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_withTransform_zeroTargetSize() throws IOException {
433+
Image image = null;
434+
try (InputStream is = getClass().getResourceAsStream("collapseall.svg")) {
435+
image = new Image(Display.getDefault(), is);
436+
}
437+
Transform transform = new Transform(display, 0.1f, 0, 0, 0.1f, 0, 0);
438+
gc.setTransform(transform);
439+
// The destination size will become 0, but no exception should be thrown.
440+
gc.drawImage(image, 0, 0, 2, 2);
441+
442+
image.dispose();
443+
transform.dispose();
444+
}
445+
397446
@Test
398447
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_ImageDataProvider() {
399448
int width = 32;

0 commit comments

Comments
 (0)