@@ -552,7 +552,10 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
552552 super (device );
553553 this .imageProvider = new ImageFileNameProviderWrapper (imageFileNameProvider );
554554 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
555- imageProvider .getImageMetadata (getZoom ());
555+ if (imageProvider .getImageData (100 ) == null ) {
556+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
557+ ": ImageFileNameProvider [" + imageFileNameProvider + "] returns null ImageData at 100% zoom." );
558+ }
556559 init ();
557560 this .device .registerResourceWithZoomSupport (this );
558561}
@@ -590,7 +593,10 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
590593 super (device );
591594 this .imageProvider = new ImageDataProviderWrapper (imageDataProvider );
592595 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
593- imageProvider .getImageMetadata (getZoom ());
596+ if (imageDataProvider .getImageData (100 ) == null ) {
597+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
598+ ": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom." );
599+ }
594600 init ();
595601 this .device .registerResourceWithZoomSupport (this );
596602}
@@ -1891,18 +1897,23 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
18911897}
18921898
18931899private abstract class AbstractImageProviderWrapper {
1900+ private boolean isDestroyed ;
1901+
18941902 protected abstract Rectangle getBounds (int zoom );
18951903 abstract ImageData getImageData (int zoom );
18961904 abstract ImageHandle getImageMetadata (int zoom );
18971905 abstract AbstractImageProviderWrapper createCopy (Image image );
1898- abstract boolean isDisposed ();
1906+
1907+ protected boolean isDisposed () {
1908+ return isDestroyed ;
1909+ }
18991910
19001911 protected void destroy () {
1912+ this .isDestroyed = true ;
19011913 }
19021914}
19031915
19041916private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
1905- private boolean isDestroyed ;
19061917 private final int width ;
19071918 private final int height ;
19081919
@@ -1984,16 +1995,6 @@ private long initBaseHandle(int zoom) {
19841995 AbstractImageProviderWrapper createCopy (Image image ) {
19851996 return image .new PlainImageProviderWrapper (width , height );
19861997 }
1987-
1988- @ Override
1989- protected void destroy () {
1990- this .isDestroyed = true ;
1991- }
1992-
1993- @ Override
1994- boolean isDisposed () {
1995- return isDestroyed ;
1996- }
19971998}
19981999
19992000private abstract class DynamicImageProviderWrapper extends AbstractImageProviderWrapper {
@@ -2016,28 +2017,43 @@ public boolean equals(Object otherProvider) {
20162017 }
20172018}
20182019
2019- private class ImageFileNameProviderWrapper extends DynamicImageProviderWrapper {
2020+ private abstract class BaseImageProviderWrapper <T > extends DynamicImageProviderWrapper {
2021+ protected final T provider ;
2022+ private final Map <Integer , Rectangle > zoomToBounds = new HashMap <>();
20202023
2021- /**
2022- * ImageFileNameProvider to provide file names at various Zoom levels
2023- */
2024- private final ImageFileNameProvider provider ;
2025-
2026- ImageFileNameProviderWrapper (ImageFileNameProvider provider ) {
2027- checkProvider (provider , ImageFileNameProvider .class );
2024+ BaseImageProviderWrapper (T provider , Class <T > expectedClass ) {
2025+ checkProvider (provider , expectedClass );
20282026 this .provider = provider ;
20292027 }
20302028
2029+ @ Override
2030+ Object getProvider () {
2031+ return provider ;
2032+ }
2033+
20312034 @ Override
20322035 protected Rectangle getBounds (int zoom ) {
2033- ImageHandle imageHandle = zoomLevelToImageHandle .values ().iterator ().next ();
2034- Rectangle rectangle = new Rectangle (0 , 0 , imageHandle .width , imageHandle .height );
2035- return DPIUtil .scaleBounds (rectangle , zoom , imageHandle .zoom );
2036+ if (zoomLevelToImageHandle .containsKey (zoom )) {
2037+ ImageHandle imgHandle = zoomLevelToImageHandle .get (zoom );
2038+ return new Rectangle (0 , 0 , imgHandle .width , imgHandle .height );
2039+ }
2040+ if (!zoomToBounds .containsKey (zoom )) {
2041+ ImageData imageData = getImageData (zoom );
2042+ Rectangle rectangle = new Rectangle (0 , 0 , imageData .width , imageData .height );
2043+ zoomToBounds .put (zoom , rectangle );
2044+ }
2045+ return zoomToBounds .get (zoom );
2046+ }
2047+ }
2048+
2049+ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper <ImageFileNameProvider > {
2050+ ImageFileNameProviderWrapper (ImageFileNameProvider provider ) {
2051+ super (provider , ImageFileNameProvider .class );
20362052 }
20372053
20382054 @ Override
20392055 ImageData getImageData (int zoom ) {
2040- ElementAtZoom <String > fileForZoom = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
2056+ ElementAtZoom <String > fileForZoom = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
20412057 ImageHandle nativeInitializedImage ;
20422058 if (zoomLevelToImageHandle .containsKey (fileForZoom .zoom ())) {
20432059 nativeInitializedImage = zoomLevelToImageHandle .get (fileForZoom .zoom ());
@@ -2072,16 +2088,6 @@ ImageHandle getImageMetadata(int zoom) {
20722088 return zoomLevelToImageHandle .get (zoom );
20732089 }
20742090
2075- @ Override
2076- boolean isDisposed () {
2077- return zoomLevelToImageHandle .isEmpty ();
2078- }
2079-
2080- @ Override
2081- Object getProvider () {
2082- return provider ;
2083- }
2084-
20852091 @ Override
20862092 public int hashCode () {
20872093 return Objects .hash (provider , styleFlag , transparentPixel , getZoom ());
@@ -2286,23 +2292,9 @@ private long extractHandleForPixelFormat(int width, int height, int pixelFormat)
22862292 }
22872293}
22882294
2289- private class ImageDataProviderWrapper extends DynamicImageProviderWrapper {
2290-
2291- /**
2292- * ImageDataProvider to provide ImageData at various Zoom levels
2293- */
2294- private final ImageDataProvider provider ;
2295-
2295+ private class ImageDataProviderWrapper extends BaseImageProviderWrapper <ImageDataProvider > {
22962296 ImageDataProviderWrapper (ImageDataProvider provider ) {
2297- checkProvider (provider , ImageDataProvider .class );
2298- this .provider = provider ;
2299- }
2300-
2301- @ Override
2302- protected Rectangle getBounds (int zoom ) {
2303- ImageHandle imageHandle = zoomLevelToImageHandle .values ().iterator ().next ();
2304- Rectangle rectangle = new Rectangle (0 , 0 , imageHandle .width , imageHandle .height );
2305- return DPIUtil .scaleBounds (rectangle , zoom , imageHandle .zoom );
2297+ super (provider , ImageDataProvider .class );
23062298 }
23072299
23082300 @ Override
@@ -2320,16 +2312,6 @@ ImageHandle getImageMetadata(int zoom) {
23202312 return zoomLevelToImageHandle .get (zoom );
23212313 }
23222314
2323- @ Override
2324- boolean isDisposed () {
2325- return zoomLevelToImageHandle .isEmpty ();
2326- }
2327-
2328- @ Override
2329- Object getProvider () {
2330- return provider ;
2331- }
2332-
23332315 @ Override
23342316 ImageDataProviderWrapper createCopy (Image image ) {
23352317 return image .new ImageDataProviderWrapper (provider );
@@ -2340,7 +2322,6 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
23402322 private ImageGcDrawer drawer ;
23412323 private int width ;
23422324 private int height ;
2343- private boolean isDestroyed ;
23442325
23452326 ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
23462327 checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2379,16 +2360,6 @@ ImageHandle getImageMetadata(int zoom) {
23792360 return zoomLevelToImageHandle .get (zoom );
23802361 }
23812362
2382- @ Override
2383- protected void destroy () {
2384- isDestroyed = true ;
2385- }
2386-
2387- @ Override
2388- boolean isDisposed () {
2389- return isDestroyed ;
2390- }
2391-
23922363 @ Override
23932364 Object getProvider () {
23942365 return drawer ;
0 commit comments