@@ -111,7 +111,7 @@ public final class Image extends Resource implements Drawable {
111111 /**
112112 * AbstractImageProvider to avail right ImageProvider (ImageDataProvider or ImageFileNameProvider)
113113 */
114- private AbstractImageProviderWrapper imageProvider ;
114+ private final AbstractImageProviderWrapper imageProvider ;
115115
116116 /**
117117 * Style flag used to differentiate normal, gray-scale and disabled images based
@@ -138,16 +138,13 @@ public final class Image extends Resource implements Drawable {
138138
139139 private Map <Integer , ImageHandle > zoomLevelToImageHandle = new HashMap <>();
140140
141- /**
142- * Prevents uninitialized instances from being created outside the package.
143- */
144- Image (Device device ) {
145- this (device , DPIUtil .getNativeDeviceZoom ());
146- }
147-
148- private Image (Device device , int nativeZoom ) {
141+ private Image (Device device , int type , long handle , int nativeZoom ) {
149142 super (device );
150143 initialNativeZoom = nativeZoom ;
144+ this .type = type ;
145+ this .imageProvider = new ExistingImageHandleProviderWrapper (handle , nativeZoom );
146+ this .isInitialized = true ;
147+ this .device .registerResourceWithZoomSupport (this );
151148}
152149
153150/**
@@ -243,9 +240,7 @@ public Image(Device device, Image srcImage, int flag) {
243240 initialNativeZoom = srcImage .initialNativeZoom ;
244241 Rectangle rect = srcImage .getBounds (getZoom ());
245242 this .type = srcImage .type ;
246- if (srcImage .imageProvider != null ) {
247- this .imageProvider = srcImage .imageProvider .createCopy (this );
248- }
243+ this .imageProvider = srcImage .imageProvider .createCopy (this );
249244 this .styleFlag = srcImage .styleFlag | flag ;
250245 long srcImageHandle = win32_getHandle (srcImage , getZoom ());
251246 switch (flag ) {
@@ -1916,11 +1911,7 @@ public String toString () {
19161911 * @noreference This method is not intended to be referenced by clients.
19171912 */
19181913public static Image win32_new (Device device , int type , long handle , int nativeZoom ) {
1919- Image image = new Image (device , nativeZoom );
1920- image .type = type ;
1921- image .new ImageHandle (handle , nativeZoom );
1922- image .device .registerResourceWithZoomSupport (image );
1923- return image ;
1914+ return new Image (device , type , handle , nativeZoom );
19241915}
19251916
19261917private abstract class AbstractImageProviderWrapper {
@@ -1940,6 +1931,63 @@ protected void destroy() {
19401931 }
19411932}
19421933
1934+ private class ExistingImageHandleProviderWrapper extends AbstractImageProviderWrapper {
1935+
1936+ private final int width ;
1937+ private final int height ;
1938+ private final long handle ;
1939+ private final int zoomForHandle ;
1940+
1941+ public ExistingImageHandleProviderWrapper (long handle , int zoomForHandle ) {
1942+ this .handle = handle ;
1943+ this .zoomForHandle = zoomForHandle ;
1944+ ImageHandle imageHandle = new ImageHandle (handle , zoomForHandle );
1945+
1946+ ImageData baseData = imageHandle .getImageData ();
1947+ this .width = DPIUtil .scaleDown (baseData .width , zoomForHandle );
1948+ this .height = DPIUtil .scaleDown (baseData .height , zoomForHandle );
1949+ }
1950+
1951+ @ Override
1952+ protected Rectangle getBounds (int zoom ) {
1953+ Rectangle rectangle = new Rectangle (0 , 0 , width , height );
1954+ return DPIUtil .scaleUp (rectangle , zoom );
1955+ }
1956+
1957+ @ Override
1958+ ImageData getImageData (int zoom ) {
1959+ if (zoomLevelToImageHandle .isEmpty () || zoomLevelToImageHandle .containsKey (zoom )) {
1960+ return getImageMetadata (zoom ).getImageData ();
1961+ }
1962+
1963+ return getScaledImageData (zoom );
1964+ }
1965+
1966+ @ Override
1967+ ImageHandle getImageMetadata (int zoom ) {
1968+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1969+ return zoomLevelToImageHandle .get (zoom );
1970+ } else {
1971+ ImageData resizedData = getImageData (zoom );
1972+ ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
1973+ if (type == SWT .ICON && newData .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
1974+ // If the original type was an icon with transparency mask and re-scaling leads
1975+ // to image data without transparency mask, this will create invalid images
1976+ // so this fallback will "repair" the image data by explicitly passing
1977+ // the transparency mask created from the scaled image data
1978+ return initIconHandle (device , newData , newData .getTransparencyMask (), zoom );
1979+ } else {
1980+ return init (newData , zoom );
1981+ }
1982+ }
1983+ }
1984+
1985+ @ Override
1986+ AbstractImageProviderWrapper createCopy (Image image ) {
1987+ return image .new ExistingImageHandleProviderWrapper (handle , zoomForHandle );
1988+ }
1989+ }
1990+
19431991private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
19441992
19451993 protected abstract ElementAtZoom <ImageData > loadImageData (int zoom );
0 commit comments