@@ -101,14 +101,9 @@ public final class Image extends Resource implements Drawable {
101101 GC memGC ;
102102
103103 /**
104- * ImageFileNameProvider to provide file names at various Zoom levels
104+ * AbstractImageProvider to avail right ImageProvider (ImageDataProvider or ImageFileNameProvider)
105105 */
106- private ImageFileNameProvider imageFileNameProvider ;
107-
108- /**
109- * ImageDataProvider to provide ImageData at various Zoom levels
110- */
111- private ImageDataProvider imageDataProvider ;
106+ private AbstractImageProvider imageProvider ;
112107
113108 /**
114109 * Style flag used to differentiate normal, gray-scale and disabled images based
@@ -228,8 +223,9 @@ public Image(Device device, Image srcImage, int flag) {
228223 if (srcImage .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
229224 Rectangle rect = srcImage .getBoundsInPixels ();
230225 this .type = srcImage .type ;
231- this .imageDataProvider = srcImage .imageDataProvider ;
232- this .imageFileNameProvider = srcImage .imageFileNameProvider ;
226+ if (srcImage .imageProvider != null ) {
227+ this .imageProvider = srcImage .imageProvider .createCopy (this );
228+ }
233229 this .styleFlag = srcImage .styleFlag | flag ;
234230 initialNativeZoom = srcImage .initialNativeZoom ;
235231 long srcImageHandle = win32_getHandle (srcImage , getZoom ());
@@ -547,7 +543,7 @@ public Image (Device device, String filename) {
547543 */
548544public Image (Device device , ImageFileNameProvider imageFileNameProvider ) {
549545 super (device );
550- this .imageFileNameProvider = imageFileNameProvider ;
546+ this .imageProvider = new ImageFileNameProviderWrapper ( imageFileNameProvider ) ;
551547 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
552548 ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , getZoom ());
553549 if (fileName .zoom () == getZoom ()) {
@@ -594,7 +590,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
594590 */
595591public Image (Device device , ImageDataProvider imageDataProvider ) {
596592 super (device );
597- this .imageDataProvider = imageDataProvider ;
593+ this .imageProvider = new ImageDataProviderWrapper ( imageDataProvider ) ;
598594 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
599595 ElementAtZoom <ImageData > data = DPIUtil .validateAndGetImageDataAtZoom (imageDataProvider , getZoom ());
600596 ImageData resizedData = DPIUtil .scaleImageData (device , data .element (), getZoom (), data .zoom ());
@@ -750,26 +746,8 @@ private ImageHandle getImageMetadata(int zoom) {
750746 if (zoomLevelToImageHandle .get (zoom ) != null ) {
751747 return zoomLevelToImageHandle .get (zoom );
752748 }
753-
754- if (imageFileNameProvider != null ) {
755- ElementAtZoom <String > imageCandidate = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , zoom );
756- ImageData imageData = new ImageData (imageCandidate .element ());
757- if (imageCandidate .zoom () == zoom ) {
758- /* Release current native resources */
759- ImageHandle imageMetadata = initNative (imageCandidate .element (), zoom );
760- if (imageMetadata == null ) init (imageData , zoom );
761- init ();
762- } else {
763- ImageData resizedData = DPIUtil .scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
764- ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
765- init (newData , zoom );
766- }
767- } else if (imageDataProvider != null ) {
768- ElementAtZoom <ImageData > imageCandidate = DPIUtil .validateAndGetImageDataAtZoom (imageDataProvider , zoom );
769- ImageData resizedData = DPIUtil .scaleImageData (device , imageCandidate .element (), zoom , imageCandidate .zoom ());
770- ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
771- init (newData , zoom );
772- init ();
749+ if (imageProvider != null ) {
750+ return imageProvider .getImageMetadata (zoom );
773751 } else {
774752 ImageData resizedData = getImageData (zoom );
775753 ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
@@ -1208,10 +1186,8 @@ public boolean equals (Object object) {
12081186 if (!(object instanceof Image )) return false ;
12091187 Image image = (Image ) object ;
12101188 if (device != image .device || transparentPixel != image .transparentPixel || getZoom () != image .getZoom ()) return false ;
1211- if (imageDataProvider != null && image .imageDataProvider != null ) {
1212- return (styleFlag == image .styleFlag ) && imageDataProvider .equals (image .imageDataProvider );
1213- } else if (imageFileNameProvider != null && image .imageFileNameProvider != null ) {
1214- return (styleFlag == image .styleFlag ) && imageFileNameProvider .equals (image .imageFileNameProvider );
1189+ if (imageProvider != null && image .imageProvider != null ) {
1190+ return (styleFlag == image .styleFlag ) && imageProvider .equals (image .imageProvider );
12151191 } else {
12161192 return win32_getHandle (this , getZoom ()) == win32_getHandle (image , getZoom ());
12171193 }
@@ -1387,15 +1363,8 @@ public ImageData getImageData (int zoom) {
13871363 int currentZoom = getZoom ();
13881364 if (zoom == currentZoom ) {
13891365 return getImageDataAtCurrentZoom ();
1390- } else if (imageDataProvider != null ) {
1391- ElementAtZoom <ImageData > data ;
1392- try (StaticZoomUpdater unused = new StaticZoomUpdater (zoom )) {
1393- data = DPIUtil .validateAndGetImageDataAtZoom (imageDataProvider , zoom );
1394- }
1395- return DPIUtil .scaleImageData (device , data .element (), zoom , data .zoom ());
1396- } else if (imageFileNameProvider != null ) {
1397- ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , zoom );
1398- return DPIUtil .scaleImageData (device , new ImageData (fileName .element ()), zoom , fileName .zoom ());
1366+ } else if (imageProvider != null ) {
1367+ return imageProvider .getImageData (zoom );
13991368 }
14001369
14011370 // if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
@@ -1442,13 +1411,10 @@ public ImageData getImageDataAtCurrentZoom() {
14421411 */
14431412@ Override
14441413public int hashCode () {
1445- if (imageDataProvider != null ) {
1446- return imageDataProvider .hashCode ();
1447- } else if (imageFileNameProvider != null ) {
1448- return Objects .hash (imageFileNameProvider , styleFlag , transparentPixel , getZoom ());
1449- } else {
1450- return (int )win32_getHandle (this , getZoom ());
1414+ if (imageProvider != null ) {
1415+ return imageProvider .hashCode ();
14511416 }
1417+ return (int )win32_getHandle (this , getZoom ());
14521418}
14531419
14541420void init (int width , int height ) {
@@ -2091,6 +2057,114 @@ public void close() {
20912057 }
20922058}
20932059
2060+ private abstract class AbstractImageProvider {
2061+ abstract Object getProvider ();
2062+ abstract ImageData getImageData (int zoom );
2063+ abstract ImageHandle getImageMetadata (int zoom );
2064+ abstract AbstractImageProvider createCopy (Image image );
2065+
2066+ @ Override
2067+ public int hashCode () {
2068+ return getProvider ().hashCode ();
2069+ }
2070+
2071+ @ Override
2072+ public boolean equals (Object otherProvider ) {
2073+ if (otherProvider != null && otherProvider instanceof AbstractImageProvider ) {
2074+ return getProvider ().equals (((AbstractImageProvider ) otherProvider ).getProvider ());
2075+ }
2076+ return false ;
2077+ }
2078+ }
2079+
2080+ private class ImageFileNameProviderWrapper extends AbstractImageProvider {
2081+
2082+ /**
2083+ * ImageFileNameProvider to provide file names at various Zoom levels
2084+ */
2085+ final ImageFileNameProvider provider ;
2086+
2087+ public ImageFileNameProviderWrapper (ImageFileNameProvider provider ) {
2088+ this .provider = provider ;
2089+ }
2090+
2091+ @ Override
2092+ ImageData getImageData (int zoom ) {
2093+ ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
2094+ return DPIUtil .scaleImageData (device , new ImageData (fileName .element ()), zoom , fileName .zoom ());
2095+ }
2096+
2097+ @ Override
2098+ ImageHandle getImageMetadata (int zoom ) {
2099+ ElementAtZoom <String > imageCandidate = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
2100+ ImageData imageData = new ImageData (imageCandidate .element ());
2101+ if (imageCandidate .zoom () == zoom ) {
2102+ /* Release current native resources */
2103+ ImageHandle imageMetadata = initNative (imageCandidate .element (), zoom );
2104+ if (imageMetadata == null ) init (imageData , zoom );
2105+ init ();
2106+ } else {
2107+ ImageData resizedData = DPIUtil .scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
2108+ ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2109+ init (newData , zoom );
2110+ }
2111+ return zoomLevelToImageHandle .get (zoom );
2112+ }
2113+
2114+ @ Override
2115+ Object getProvider () {
2116+ return provider ;
2117+ }
2118+
2119+ @ Override
2120+ public int hashCode () {
2121+ return Objects .hash (provider , styleFlag , transparentPixel , getZoom ());
2122+ }
2123+
2124+ @ Override
2125+ AbstractImageProvider createCopy (Image image ) {
2126+ return image .new ImageFileNameProviderWrapper (provider );
2127+ }
2128+ }
2129+
2130+ private class ImageDataProviderWrapper extends AbstractImageProvider {
2131+
2132+ /**
2133+ * ImageDataProvider to provide ImageData at various Zoom levels
2134+ */
2135+ final ImageDataProvider provider ;
2136+
2137+ public ImageDataProviderWrapper (ImageDataProvider provider ) {
2138+ this .provider = provider ;
2139+ }
2140+
2141+ @ Override
2142+ ImageData getImageData (int zoom ) {
2143+ ElementAtZoom <ImageData > data = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2144+ return DPIUtil .scaleImageData (device , data .element (), zoom , data .zoom ());
2145+ }
2146+
2147+ @ Override
2148+ ImageHandle getImageMetadata (int zoom ) {
2149+ ElementAtZoom <ImageData > imageCandidate = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2150+ ImageData resizedData = DPIUtil .scaleImageData (device , imageCandidate .element (), zoom , imageCandidate .zoom ());
2151+ ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2152+ init (newData , zoom );
2153+ init ();
2154+ return zoomLevelToImageHandle .get (zoom );
2155+ }
2156+
2157+ @ Override
2158+ Object getProvider () {
2159+ return provider ;
2160+ }
2161+
2162+ @ Override
2163+ AbstractImageProvider createCopy (Image image ) {
2164+ return image .new ImageDataProviderWrapper (provider );
2165+ }
2166+ }
2167+
20942168private class ImageHandle {
20952169 private final long handle ;
20962170 private final int zoom ;
0 commit comments