@@ -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-
2021- /**
2022- * ImageFileNameProvider to provide file names at various Zoom levels
2023- */
2024- private final ImageFileNameProvider provider ;
2020+ private abstract class BaseImageProviderWrapper <T > extends DynamicImageProviderWrapper {
2021+ protected final T provider ;
2022+ private final Map <Integer , Rectangle > zoomToBounds = new HashMap <>();
20252023
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 ());
@@ -2248,61 +2254,59 @@ ImageHandle initNative(String filename, int zoom) {
22482254 private int extractDepthForPixelFormat (BitmapData bitmapData ) {
22492255 int depth = 0 ;
22502256 switch (bitmapData .PixelFormat ) {
2251- case Gdip .PixelFormat1bppIndexed : depth = 1 ; break ;
2252- case Gdip .PixelFormat4bppIndexed : depth = 4 ; break ;
2253- case Gdip .PixelFormat8bppIndexed : depth = 8 ; break ;
2254- case Gdip .PixelFormat16bppARGB1555 :
2255- case Gdip .PixelFormat16bppRGB555 :
2256- case Gdip .PixelFormat16bppRGB565 : depth = 16 ; break ;
2257- case Gdip .PixelFormat24bppRGB : depth = 24 ; break ;
2258- case Gdip .PixelFormat32bppRGB :
2259- case Gdip .PixelFormat32bppARGB : depth = 32 ; break ;
2257+ case Gdip .PixelFormat1bppIndexed :
2258+ depth = 1 ;
2259+ break ;
2260+ case Gdip .PixelFormat4bppIndexed :
2261+ depth = 4 ;
2262+ break ;
2263+ case Gdip .PixelFormat8bppIndexed :
2264+ depth = 8 ;
2265+ break ;
2266+ case Gdip .PixelFormat16bppARGB1555 :
2267+ case Gdip .PixelFormat16bppRGB555 :
2268+ case Gdip .PixelFormat16bppRGB565 :
2269+ depth = 16 ;
2270+ break ;
2271+ case Gdip .PixelFormat24bppRGB :
2272+ depth = 24 ;
2273+ break ;
2274+ case Gdip .PixelFormat32bppRGB :
2275+ case Gdip .PixelFormat32bppARGB :
2276+ depth = 32 ;
2277+ break ;
22602278 }
22612279 return depth ;
22622280 }
22632281
22642282 private long extractHandleForPixelFormat (int width , int height , int pixelFormat ) {
22652283 long handle = 0 ;
22662284 switch (pixelFormat ) {
2267- case Gdip .PixelFormat16bppRGB555 :
2268- case Gdip .PixelFormat16bppRGB565 :
2269- handle = createDIB (width , height , 16 );
2270- break ;
2271- case Gdip .PixelFormat24bppRGB :
2272- case Gdip .PixelFormat32bppCMYK :
2273- handle = createDIB (width , height , 24 );
2274- break ;
2275- case Gdip .PixelFormat32bppRGB :
2285+ case Gdip .PixelFormat16bppRGB555 :
2286+ case Gdip .PixelFormat16bppRGB565 :
2287+ handle = createDIB (width , height , 16 );
2288+ break ;
2289+ case Gdip .PixelFormat24bppRGB :
2290+ case Gdip .PixelFormat32bppCMYK :
2291+ handle = createDIB (width , height , 24 );
2292+ break ;
2293+ case Gdip .PixelFormat32bppRGB :
22762294 // These will lose either precision or transparency
2277- case Gdip .PixelFormat16bppGrayScale :
2278- case Gdip .PixelFormat48bppRGB :
2279- case Gdip .PixelFormat32bppPARGB :
2280- case Gdip .PixelFormat64bppARGB :
2281- case Gdip .PixelFormat64bppPARGB :
2282- handle = createDIB (width , height , 32 );
2283- break ;
2295+ case Gdip .PixelFormat16bppGrayScale :
2296+ case Gdip .PixelFormat48bppRGB :
2297+ case Gdip .PixelFormat32bppPARGB :
2298+ case Gdip .PixelFormat64bppARGB :
2299+ case Gdip .PixelFormat64bppPARGB :
2300+ handle = createDIB (width , height , 32 );
2301+ break ;
22842302 }
22852303 return handle ;
22862304 }
22872305}
22882306
2289- private class ImageDataProviderWrapper extends DynamicImageProviderWrapper {
2290-
2291- /**
2292- * ImageDataProvider to provide ImageData at various Zoom levels
2293- */
2294- private final ImageDataProvider provider ;
2295-
2307+ private class ImageDataProviderWrapper extends BaseImageProviderWrapper <ImageDataProvider > {
22962308 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 );
2309+ super (provider , ImageDataProvider .class );
23062310 }
23072311
23082312 @ Override
@@ -2320,16 +2324,6 @@ ImageHandle getImageMetadata(int zoom) {
23202324 return zoomLevelToImageHandle .get (zoom );
23212325 }
23222326
2323- @ Override
2324- boolean isDisposed () {
2325- return zoomLevelToImageHandle .isEmpty ();
2326- }
2327-
2328- @ Override
2329- Object getProvider () {
2330- return provider ;
2331- }
2332-
23332327 @ Override
23342328 ImageDataProviderWrapper createCopy (Image image ) {
23352329 return image .new ImageDataProviderWrapper (provider );
@@ -2340,7 +2334,6 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
23402334 private ImageGcDrawer drawer ;
23412335 private int width ;
23422336 private int height ;
2343- private boolean isDestroyed ;
23442337
23452338 ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
23462339 checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2379,16 +2372,6 @@ ImageHandle getImageMetadata(int zoom) {
23792372 return zoomLevelToImageHandle .get (zoom );
23802373 }
23812374
2382- @ Override
2383- protected void destroy () {
2384- isDestroyed = true ;
2385- }
2386-
2387- @ Override
2388- boolean isDisposed () {
2389- return isDestroyed ;
2390- }
2391-
23922375 @ Override
23932376 Object getProvider () {
23942377 return drawer ;
0 commit comments