@@ -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}
@@ -2067,18 +2073,23 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
20672073}
20682074
20692075private abstract class AbstractImageProviderWrapper {
2076+ private boolean isDestroyed ;
2077+
20702078 protected abstract Rectangle getBounds (int zoom );
20712079 abstract ImageData getImageData (int zoom );
20722080 abstract ImageHandle getImageMetadata (int zoom );
20732081 abstract AbstractImageProviderWrapper createCopy (Image image );
2074- abstract boolean isDisposed ();
2082+
2083+ protected boolean isDisposed () {
2084+ return isDestroyed ;
2085+ }
20752086
20762087 protected void destroy () {
2088+ this .isDestroyed = true ;
20772089 }
20782090}
20792091
20802092private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
2081- private boolean isDestroyed ;
20822093 private final int width ;
20832094 private final int height ;
20842095
@@ -2160,16 +2171,6 @@ private long initBaseHandle(int zoom) {
21602171 AbstractImageProviderWrapper createCopy (Image image ) {
21612172 return image .new PlainImageProviderWrapper (width , height );
21622173 }
2163-
2164- @ Override
2165- protected void destroy () {
2166- this .isDestroyed = true ;
2167- }
2168-
2169- @ Override
2170- boolean isDisposed () {
2171- return isDestroyed ;
2172- }
21732174}
21742175
21752176private abstract class DynamicImageProviderWrapper extends AbstractImageProviderWrapper {
@@ -2192,24 +2193,41 @@ public boolean equals(Object otherProvider) {
21922193 }
21932194}
21942195
2195- private class ImageFileNameProviderWrapper extends DynamicImageProviderWrapper {
21962196
2197- /**
2198- * ImageFileNameProvider to provide file names at various Zoom levels
2199- */
2200- private final ImageFileNameProvider provider ;
2197+ private abstract class BaseImageProviderWrapper <T > extends DynamicImageProviderWrapper {
2198+ protected final T provider ;
2199+ protected Map <Integer , Rectangle > rectCache = new HashMap <>();
22012200
2202- ImageFileNameProviderWrapper ( ImageFileNameProvider provider ) {
2203- checkProvider (provider , ImageFileNameProvider . class );
2204- this .provider = provider ;
2205- }
2201+ BaseImageProviderWrapper ( T provider , Class < T > expectedClass ) {
2202+ checkProvider (provider , expectedClass );
2203+ this .provider = provider ;
2204+ }
22062205
2207- @ Override
2206+ @ Override
2207+ Object getProvider () {
2208+ return provider ;
2209+ }
2210+
2211+ @ Override
22082212 protected Rectangle getBounds (int zoom ) {
2209- ImageHandle imageHandle = zoomLevelToImageHandle .values ().iterator ().next ();
2210- Rectangle rectangle = new Rectangle (0 , 0 , imageHandle .width , imageHandle .height );
2211- return DPIUtil .scaleBounds (rectangle , zoom , imageHandle .zoom );
2212- }
2213+ if (zoomLevelToImageHandle .containsKey (zoom )) {
2214+ ImageHandle imgHandle = zoomLevelToImageHandle .get (zoom );
2215+ return new Rectangle (0 , 0 , imgHandle .width , imgHandle .height );
2216+ }
2217+ if (!rectCache .containsKey (zoom )) {
2218+ ImageData imageData = getImageData (zoom );
2219+ Rectangle rectangle = new Rectangle (0 , 0 , imageData .width , imageData .height );
2220+ rectCache .put (zoom , rectangle );
2221+ }
2222+ return rectCache .get (zoom );
2223+ }
2224+ }
2225+
2226+
2227+ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper <ImageFileNameProvider > {
2228+ ImageFileNameProviderWrapper (ImageFileNameProvider provider ) {
2229+ super (provider , ImageFileNameProvider .class );
2230+ }
22132231
22142232 @ Override
22152233 ImageData getImageData (int zoom ) {
@@ -2237,45 +2255,16 @@ ImageHandle getImageMetadata(int zoom) {
22372255 return zoomLevelToImageHandle .get (zoom );
22382256 }
22392257
2240- @ Override
2241- boolean isDisposed () {
2242- return zoomLevelToImageHandle .isEmpty ();
2243- }
2244-
2245- @ Override
2246- Object getProvider () {
2247- return provider ;
2248- }
2249-
2250- @ Override
2251- public int hashCode () {
2252- return Objects .hash (provider , styleFlag , transparentPixel , getZoom ());
2253- }
2254-
22552258 @ Override
22562259 ImageFileNameProviderWrapper createCopy (Image image ) {
22572260 return image .new ImageFileNameProviderWrapper (provider );
22582261 }
22592262}
22602263
2261- private class ImageDataProviderWrapper extends DynamicImageProviderWrapper {
2262-
2263- /**
2264- * ImageDataProvider to provide ImageData at various Zoom levels
2265- */
2266- private final ImageDataProvider provider ;
2267-
2264+ private class ImageDataProviderWrapper extends BaseImageProviderWrapper <ImageDataProvider > {
22682265 ImageDataProviderWrapper (ImageDataProvider provider ) {
2269- checkProvider (provider , ImageDataProvider .class );
2270- this .provider = provider ;
2271- }
2272-
2273- @ Override
2274- protected Rectangle getBounds (int zoom ) {
2275- ImageHandle imageHandle = zoomLevelToImageHandle .values ().iterator ().next ();
2276- Rectangle rectangle = new Rectangle (0 , 0 , imageHandle .width , imageHandle .height );
2277- return DPIUtil .scaleBounds (rectangle , zoom , imageHandle .zoom );
2278- }
2266+ super (provider , ImageDataProvider .class );
2267+ }
22792268
22802269 @ Override
22812270 ImageData getImageData (int zoom ) {
@@ -2292,16 +2281,6 @@ ImageHandle getImageMetadata(int zoom) {
22922281 return zoomLevelToImageHandle .get (zoom );
22932282 }
22942283
2295- @ Override
2296- boolean isDisposed () {
2297- return zoomLevelToImageHandle .isEmpty ();
2298- }
2299-
2300- @ Override
2301- Object getProvider () {
2302- return provider ;
2303- }
2304-
23052284 @ Override
23062285 ImageDataProviderWrapper createCopy (Image image ) {
23072286 return image .new ImageDataProviderWrapper (provider );
@@ -2312,7 +2291,6 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
23122291 private ImageGcDrawer drawer ;
23132292 private int width ;
23142293 private int height ;
2315- private boolean isDestroyed ;
23162294
23172295 ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
23182296 checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2351,16 +2329,6 @@ ImageHandle getImageMetadata(int zoom) {
23512329 return zoomLevelToImageHandle .get (zoom );
23522330 }
23532331
2354- @ Override
2355- protected void destroy () {
2356- isDestroyed = true ;
2357- }
2358-
2359- @ Override
2360- boolean isDisposed () {
2361- return isDestroyed ;
2362- }
2363-
23642332 @ Override
23652333 Object getProvider () {
23662334 return drawer ;
@@ -2699,4 +2667,4 @@ private ImageData getImageData() {
26992667 }
27002668
27012669}
2702- }
2670+ }
0 commit comments