Skip to content

Commit fe6a332

Browse files
committed
[GTK] Support loading and drawing images at desired size
This change introduces support for loading and drawing images at custom sizes in the GTK versions of GC and Image. The GC#drawImage() method, which only accepts the destination position and size, now attempts to load image at the destination size in case if it is provided by ImageFilenameProvider returning svgs or if the image is created with a imageDataAtSizeProvider.
1 parent d2de8e3 commit fe6a332

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ public void drawImage(Image image, int destX, int destY, int destWidth, int dest
913913
if (image.isDisposed()) {
914914
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
915915
}
916-
drawImage(image, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false);
916+
image.executeOnImageAtSize(imageAtSize -> drawImage(imageAtSize, 0, 0, 0, 0, destX, destY, destWidth, destHeight, false), destWidth, destHeight);
917917
}
918918

919919
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {

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

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,81 @@ void destroy() {
927927
memGC = null;
928928
}
929929

930+
private CachedImageAtSize cachedImageAtSize = new CachedImageAtSize();
931+
932+
private class CachedImageAtSize {
933+
private Image image;
934+
935+
public void destroy() {
936+
if (image != null) {
937+
image.dispose();
938+
image = null;
939+
}
940+
}
941+
942+
private Optional<Image> refresh(int destWidth, int destHeight) {
943+
int scaledWidth = DPIUtil.pointToPixel(destWidth, DPIUtil.getDeviceZoom());
944+
int scaledHeight = DPIUtil.pointToPixel(destHeight, DPIUtil.getDeviceZoom());
945+
if (isReusable(scaledWidth, scaledHeight)) {
946+
return Optional.of(image);
947+
} else {
948+
destroy();
949+
Optional<Image> imageAtSize = loadImageAtSize(scaledWidth, scaledHeight);
950+
image = imageAtSize.orElse(null);
951+
return imageAtSize;
952+
}
953+
}
954+
955+
private boolean isReusable(int width, int height) {
956+
return image != null && image.height == height && image.width == width;
957+
}
958+
959+
private Optional<Image> loadImageAtSize(int destWidth, int destHeight) {
960+
Optional<ImageData> imageData = loadImageDataAtExactSize(destWidth, destHeight);
961+
if (imageData.isEmpty()) {
962+
return Optional.empty();
963+
}
964+
Image image = new Image(device, imageData.get(),100);
965+
if (styleFlag != SWT.IMAGE_COPY) {
966+
image.currentDeviceZoom=DPIUtil.getDeviceZoom();
967+
Image styledImage = new Image(device, image, styleFlag);
968+
styledImage.currentDeviceZoom = 100;
969+
image.dispose();
970+
image = styledImage;
971+
}
972+
return Optional.of(image);
973+
}
974+
975+
private Optional<ImageData> loadImageDataAtExactSize(int targetWidth, int targetHeight) {
976+
if (imageDataProvider instanceof ImageDataAtSizeProvider imageDataAtSizeProvider) {
977+
ImageData imageData = imageDataAtSizeProvider.getImageData(targetWidth, targetHeight);
978+
if (imageData == null) {
979+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
980+
" ImageDataAtSizeProvider returned null for width=" + targetWidth + ", height=" + targetHeight);
981+
}
982+
return Optional.of(imageData);
983+
}
984+
if (imageFileNameProvider != null) {
985+
String fileName = DPIUtil.validateAndGetImagePathAtZoom(imageFileNameProvider, 100).element();
986+
if (ImageDataLoader.isDynamicallySizable(fileName)) {
987+
ImageData imageDataAtSize = ImageDataLoader.loadBySize(fileName, targetWidth, targetHeight);
988+
return Optional.of(imageDataAtSize);
989+
}
990+
}
991+
return Optional.empty();
992+
}
993+
}
994+
995+
@FunctionalInterface
996+
interface ImageAtSizeConsumer {
997+
void accept(Image image);
998+
}
999+
1000+
void executeOnImageAtSize(ImageAtSizeConsumer imageAtSizeConsumer, int destWidth, int destHeight) {
1001+
Optional<Image> imageAtSize = cachedImageAtSize.refresh(destWidth, destHeight);
1002+
imageAtSizeConsumer.accept(imageAtSize.orElse(this));
1003+
}
1004+
9301005
/**
9311006
* Compares the argument to the receiver, and returns true
9321007
* if they represent the <em>same</em> object using a class

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@
5454
import org.junit.jupiter.api.AfterEach;
5555
import org.junit.jupiter.api.BeforeEach;
5656
import org.junit.jupiter.api.Test;
57-
import org.junit.jupiter.api.condition.DisabledOnOs;
58-
import org.junit.jupiter.api.condition.OS;
5957
import org.junit.jupiter.params.ParameterizedTest;
6058
import org.junit.jupiter.params.provider.ValueSource;
6159

@@ -442,7 +440,6 @@ public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_ImageDataProvider(
442440
}
443441

444442
@Test
445-
@DisabledOnOs(value = OS.LINUX)
446443
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_ImageDataAtSizeProvider_invalid() {
447444
ImageDataAtSizeProvider provider = new ImageDataAtSizeProvider() {
448445
@Override
@@ -469,11 +466,10 @@ public ImageData getImageData(int width, int height) {
469466

470467
@ParameterizedTest
471468
@ValueSource(ints = {SWT.IMAGE_COPY, SWT.IMAGE_DISABLE, SWT.IMAGE_GRAY, -1})
472-
@DisabledOnOs(value = OS.LINUX)
473469
public void test_drawImageLorg_eclipse_swt_graphics_ImageIIII_ImageDataAtSizeProvider(int styleFlag) {
474470
int width = 50;
475471
int height = 70;
476-
Image drawToImage = new Image(display, width, height);
472+
Image drawToImage = new Image(display, new ImageData(width, height, 32, new PaletteData(0xFF0000, 0xFF00, 0xFF)));
477473
GC gc = new GC(drawToImage);
478474
gc.setAntialias(SWT.OFF);
479475
RGB drawnRgb = new RGB(255, 255, 255);

0 commit comments

Comments
 (0)