From a46c3173507a8be462b4a44b93853d8981dacf55 Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Mon, 17 Mar 2025 13:18:11 +0100 Subject: [PATCH] Create handles for ImageDataProvider and ImageFilenameProvider on demand --- .../win32/org/eclipse/swt/graphics/Image.java | 132 ++++++++---------- 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 34c4ea9bbe0..31f200af876 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -90,6 +90,11 @@ public final class Image extends Resource implements Drawable { */ public int type; + /** + * this field make sure the image is initialized without any errors + */ + boolean isInitialized = false; + /** * specifies the transparent pixel */ @@ -552,7 +557,10 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) { super(device); this.imageProvider = new ImageFileNameProviderWrapper(imageFileNameProvider); initialNativeZoom = DPIUtil.getNativeDeviceZoom(); - imageProvider.getImageMetadata(getZoom()); + if (imageProvider.getImageData(100) == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, + ": ImageFileNameProvider [" + imageFileNameProvider + "] returns null ImageData at 100% zoom."); + } init(); this.device.registerResourceWithZoomSupport(this); } @@ -590,7 +598,10 @@ public Image(Device device, ImageDataProvider imageDataProvider) { super(device); this.imageProvider = new ImageDataProviderWrapper(imageDataProvider); initialNativeZoom = DPIUtil.getNativeDeviceZoom(); - imageProvider.getImageMetadata(getZoom()); + if (imageDataProvider.getImageData(100) == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, + ": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom."); + } init(); this.device.registerResourceWithZoomSupport(this); } @@ -642,6 +653,12 @@ private ImageData adaptImageDataIfDisabledOrGray(ImageData data) { return returnImageData; } +@Override +void init() { + super.init(); + this.isInitialized = true; +} + private ImageData applyDisableImageData(ImageData data, int height, int width) { PaletteData palette = data.palette; RGB[] rgbs = new RGB[3]; @@ -1891,18 +1908,23 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo } private abstract class AbstractImageProviderWrapper { + private boolean isDestroyed; + protected abstract Rectangle getBounds(int zoom); abstract ImageData getImageData(int zoom); abstract ImageHandle getImageMetadata(int zoom); abstract AbstractImageProviderWrapper createCopy(Image image); - abstract boolean isDisposed(); + + protected boolean isDisposed() { + return !isInitialized || isDestroyed; + } protected void destroy() { + this.isDestroyed = true; } } private class PlainImageProviderWrapper extends AbstractImageProviderWrapper { - private boolean isDestroyed; private final int width; private final int height; @@ -1984,16 +2006,6 @@ private long initBaseHandle(int zoom) { AbstractImageProviderWrapper createCopy(Image image) { return image.new PlainImageProviderWrapper(width, height); } - - @Override - protected void destroy() { - this.isDestroyed = true; - } - - @Override - boolean isDisposed() { - return isDestroyed; - } } private abstract class DynamicImageProviderWrapper extends AbstractImageProviderWrapper { @@ -2016,28 +2028,43 @@ public boolean equals(Object otherProvider) { } } -private class ImageFileNameProviderWrapper extends DynamicImageProviderWrapper { +private abstract class BaseImageProviderWrapper extends DynamicImageProviderWrapper { + protected final T provider; + private final Map zoomToBounds = new HashMap<>(); - /** - * ImageFileNameProvider to provide file names at various Zoom levels - */ - private final ImageFileNameProvider provider; - - ImageFileNameProviderWrapper(ImageFileNameProvider provider) { - checkProvider(provider, ImageFileNameProvider.class); + BaseImageProviderWrapper(T provider, Class expectedClass) { + checkProvider(provider, expectedClass); this.provider = provider; } + @Override + Object getProvider() { + return provider; + } + @Override protected Rectangle getBounds(int zoom) { - ImageHandle imageHandle = zoomLevelToImageHandle.values().iterator().next(); - Rectangle rectangle = new Rectangle(0, 0, imageHandle.width, imageHandle.height); - return DPIUtil.scaleBounds(rectangle, zoom, imageHandle.zoom); + if (zoomLevelToImageHandle.containsKey(zoom)) { + ImageHandle imgHandle = zoomLevelToImageHandle.get(zoom); + return new Rectangle(0, 0, imgHandle.width, imgHandle.height); + } + if (!zoomToBounds.containsKey(zoom)) { + ImageData imageData = getImageData(zoom); + Rectangle rectangle = new Rectangle(0, 0, imageData.width, imageData.height); + zoomToBounds.put(zoom, rectangle); + } + return zoomToBounds.get(zoom); + } +} + +private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper { + ImageFileNameProviderWrapper(ImageFileNameProvider provider) { + super(provider, ImageFileNameProvider.class); } @Override ImageData getImageData(int zoom) { - ElementAtZoom fileForZoom = DPIUtil.validateAndGetImagePathAtZoom (provider, zoom); + ElementAtZoom fileForZoom = DPIUtil.validateAndGetImagePathAtZoom(provider, zoom); ImageHandle nativeInitializedImage; if (zoomLevelToImageHandle.containsKey(fileForZoom.zoom())) { nativeInitializedImage = zoomLevelToImageHandle.get(fileForZoom.zoom()); @@ -2072,16 +2099,6 @@ ImageHandle getImageMetadata(int zoom) { return zoomLevelToImageHandle.get(zoom); } - @Override - boolean isDisposed() { - return zoomLevelToImageHandle.isEmpty(); - } - - @Override - Object getProvider() { - return provider; - } - @Override public int hashCode() { return Objects.hash(provider, styleFlag, transparentPixel, getZoom()); @@ -2286,23 +2303,9 @@ private long extractHandleForPixelFormat(int width, int height, int pixelFormat) } } -private class ImageDataProviderWrapper extends DynamicImageProviderWrapper { - - /** - * ImageDataProvider to provide ImageData at various Zoom levels - */ - private final ImageDataProvider provider; - +private class ImageDataProviderWrapper extends BaseImageProviderWrapper { ImageDataProviderWrapper(ImageDataProvider provider) { - checkProvider(provider, ImageDataProvider.class); - this.provider = provider; - } - - @Override - protected Rectangle getBounds(int zoom) { - ImageHandle imageHandle = zoomLevelToImageHandle.values().iterator().next(); - Rectangle rectangle = new Rectangle(0, 0, imageHandle.width, imageHandle.height); - return DPIUtil.scaleBounds(rectangle, zoom, imageHandle.zoom); + super(provider, ImageDataProvider.class); } @Override @@ -2320,16 +2323,6 @@ ImageHandle getImageMetadata(int zoom) { return zoomLevelToImageHandle.get(zoom); } - @Override - boolean isDisposed() { - return zoomLevelToImageHandle.isEmpty(); - } - - @Override - Object getProvider() { - return provider; - } - @Override ImageDataProviderWrapper createCopy(Image image) { return image.new ImageDataProviderWrapper(provider); @@ -2340,7 +2333,6 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper { private ImageGcDrawer drawer; private int width; private int height; - private boolean isDestroyed; ImageGcDrawerWrapper(ImageGcDrawer imageGcDrawer, int width, int height) { checkProvider(imageGcDrawer, ImageGcDrawer.class); @@ -2379,16 +2371,6 @@ ImageHandle getImageMetadata(int zoom) { return zoomLevelToImageHandle.get(zoom); } - @Override - protected void destroy() { - isDestroyed = true; - } - - @Override - boolean isDisposed() { - return isDestroyed; - } - @Override Object getProvider() { return drawer; @@ -2726,5 +2708,9 @@ private ImageData getImageData() { } } + private boolean isDisposed() { + return this.handle == 0; + } + } }