@@ -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,24 +2017,41 @@ public boolean equals(Object otherProvider) {
20162017 }
20172018}
20182019
2019- private class ImageFileNameProviderWrapper extends DynamicImageProviderWrapper {
20202020
2021- /**
2022- * ImageFileNameProvider to provide file names at various Zoom levels
2023- */
2024- private final ImageFileNameProvider provider ;
2021+ private abstract class BaseImageProviderWrapper <T > extends DynamicImageProviderWrapper {
2022+ protected final T provider ;
2023+ protected final Map <Integer , Rectangle > zoomToBounds = new HashMap <>();
20252024
2026- ImageFileNameProviderWrapper ( ImageFileNameProvider provider ) {
2027- checkProvider (provider , ImageFileNameProvider . class );
2028- this .provider = provider ;
2029- }
2025+ BaseImageProviderWrapper ( T provider , Class < T > expectedClass ) {
2026+ checkProvider (provider , expectedClass );
2027+ this .provider = provider ;
2028+ }
20302029
2031- @ Override
2030+ @ Override
2031+ Object getProvider () {
2032+ return provider ;
2033+ }
2034+
2035+ @ Override
20322036 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- }
2037+ if (zoomLevelToImageHandle .containsKey (zoom )) {
2038+ ImageHandle imgHandle = zoomLevelToImageHandle .get (zoom );
2039+ return new Rectangle (0 , 0 , imgHandle .width , imgHandle .height );
2040+ }
2041+ if (!zoomToBounds .containsKey (zoom )) {
2042+ ImageData imageData = getImageData (zoom );
2043+ Rectangle rectangle = new Rectangle (0 , 0 , imageData .width , imageData .height );
2044+ zoomToBounds .put (zoom , rectangle );
2045+ }
2046+ return zoomToBounds .get (zoom );
2047+ }
2048+ }
2049+
2050+
2051+ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper <ImageFileNameProvider > {
2052+ ImageFileNameProviderWrapper (ImageFileNameProvider provider ) {
2053+ super (provider , ImageFileNameProvider .class );
2054+ }
20372055
20382056 @ Override
20392057 ImageData getImageData (int zoom ) {
@@ -2073,13 +2091,8 @@ ImageHandle getImageMetadata(int zoom) {
20732091 }
20742092
20752093 @ Override
2076- boolean isDisposed () {
2077- return zoomLevelToImageHandle .isEmpty ();
2078- }
2079-
2080- @ Override
2081- Object getProvider () {
2082- return provider ;
2094+ ImageFileNameProviderWrapper createCopy (Image image ) {
2095+ return image .new ImageFileNameProviderWrapper (provider );
20832096 }
20842097
20852098 @ Override
@@ -2286,24 +2299,10 @@ private long extractHandleForPixelFormat(int width, int height, int pixelFormat)
22862299 }
22872300}
22882301
2289- private class ImageDataProviderWrapper extends DynamicImageProviderWrapper {
2290-
2291- /**
2292- * ImageDataProvider to provide ImageData at various Zoom levels
2293- */
2294- private final ImageDataProvider provider ;
2295-
2302+ private class ImageDataProviderWrapper extends BaseImageProviderWrapper <ImageDataProvider > {
22962303 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 );
2306- }
2304+ super (provider , ImageDataProvider .class );
2305+ }
23072306
23082307 @ Override
23092308 ImageData getImageData (int zoom ) {
@@ -2320,16 +2319,6 @@ ImageHandle getImageMetadata(int zoom) {
23202319 return zoomLevelToImageHandle .get (zoom );
23212320 }
23222321
2323- @ Override
2324- boolean isDisposed () {
2325- return zoomLevelToImageHandle .isEmpty ();
2326- }
2327-
2328- @ Override
2329- Object getProvider () {
2330- return provider ;
2331- }
2332-
23332322 @ Override
23342323 ImageDataProviderWrapper createCopy (Image image ) {
23352324 return image .new ImageDataProviderWrapper (provider );
@@ -2340,7 +2329,6 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
23402329 private ImageGcDrawer drawer ;
23412330 private int width ;
23422331 private int height ;
2343- private boolean isDestroyed ;
23442332
23452333 ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
23462334 checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2379,16 +2367,6 @@ ImageHandle getImageMetadata(int zoom) {
23792367 return zoomLevelToImageHandle .get (zoom );
23802368 }
23812369
2382- @ Override
2383- protected void destroy () {
2384- isDestroyed = true ;
2385- }
2386-
2387- @ Override
2388- boolean isDisposed () {
2389- return isDestroyed ;
2390- }
2391-
23922370 @ Override
23932371 Object getProvider () {
23942372 return drawer ;
0 commit comments