@@ -178,11 +178,8 @@ public Image(Device device, int width, int height) {
178
178
179
179
private Image (Device device , int width , int height , int nativeZoom ) {
180
180
super (device );
181
- initialNativeZoom = nativeZoom ;
182
- final int zoom = getZoom ();
183
- width = DPIUtil .scaleUp (width , zoom );
184
- height = DPIUtil .scaleUp (height , zoom );
185
- init (width , height );
181
+ this .initialNativeZoom = nativeZoom ;
182
+ this .imageProvider = new PlainImageProviderWrapper (width , height );
186
183
init ();
187
184
this .device .registerResourceWithZoomSupport (this );
188
185
}
@@ -331,8 +328,7 @@ public Image(Device device, Rectangle bounds) {
331
328
super (device );
332
329
if (bounds == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
333
330
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
334
- bounds = DPIUtil .scaleUp (bounds , getZoom ());
335
- init (bounds .width , bounds .height );
331
+ this .imageProvider = new PlainImageProviderWrapper (bounds .width , bounds .height );
336
332
init ();
337
333
this .device .registerResourceWithZoomSupport (this );
338
334
}
@@ -1406,6 +1402,10 @@ public ImageData getImageData (int zoom) {
1406
1402
return imageProvider .getImageData (zoom );
1407
1403
}
1408
1404
1405
+ return getScaledImageData (zoom );
1406
+ }
1407
+
1408
+ private ImageData getScaledImageData (int zoom ) {
1409
1409
// if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
1410
1410
// be a destructive operation. Therefor, always the current image data must be returned
1411
1411
if (memGC != null ) {
@@ -1416,6 +1416,7 @@ public ImageData getImageData (int zoom) {
1416
1416
return DPIUtil .scaleImageData (device , getImageMetadata (closestZoom ).getImageData (), zoom , closestZoom );
1417
1417
}
1418
1418
1419
+
1419
1420
/**
1420
1421
* Returns an <code>ImageData</code> based on the receiver.
1421
1422
* Modifications made to this <code>ImageData</code> will not
@@ -1458,39 +1459,6 @@ public int hashCode () {
1458
1459
return (int )win32_getHandle (this , getZoom ());
1459
1460
}
1460
1461
1461
- void init (int width , int height ) {
1462
- if (width <= 0 || height <= 0 ) {
1463
- SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1464
- }
1465
- type = SWT .BITMAP ;
1466
- long hDC = device .internal_new_GC (null );
1467
- ImageHandle imageMetadata = new ImageHandle (OS .CreateCompatibleBitmap (hDC , width , height ), getZoom ());
1468
- /*
1469
- * Feature in Windows. CreateCompatibleBitmap() may fail
1470
- * for large images. The fix is to create a DIB section
1471
- * in that case.
1472
- */
1473
- if (imageMetadata .handle == 0 ) {
1474
- int bits = OS .GetDeviceCaps (hDC , OS .BITSPIXEL );
1475
- int planes = OS .GetDeviceCaps (hDC , OS .PLANES );
1476
- int depth = bits * planes ;
1477
- if (depth < 16 ) depth = 16 ;
1478
- if (depth > 24 ) depth = 24 ;
1479
- imageMetadata = new ImageHandle (createDIB (width , height , depth ), getZoom ());
1480
- }
1481
- if (imageMetadata .handle != 0 ) {
1482
- long memDC = OS .CreateCompatibleDC (hDC );
1483
- long hOldBitmap = OS .SelectObject (memDC , imageMetadata .handle );
1484
- OS .PatBlt (memDC , 0 , 0 , width , height , OS .PATCOPY );
1485
- OS .SelectObject (memDC , hOldBitmap );
1486
- OS .DeleteDC (memDC );
1487
- }
1488
- device .internal_dispose_GC (hDC , null );
1489
- if (imageMetadata .handle == 0 ) {
1490
- SWT .error (SWT .ERROR_NO_HANDLES , null , device .getLastError ());
1491
- }
1492
- }
1493
-
1494
1462
static long createDIB (int width , int height , int depth ) {
1495
1463
BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER ();
1496
1464
bmiHeader .biSize = BITMAPINFOHEADER .sizeof ;
@@ -2082,13 +2050,114 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
2082
2050
}
2083
2051
2084
2052
private abstract class AbstractImageProviderWrapper {
2085
- abstract Object getProvider ();
2086
2053
protected abstract Rectangle getBounds (int zoom );
2087
2054
abstract ImageData getImageData (int zoom );
2088
2055
abstract ImageHandle getImageMetadata (int zoom );
2089
2056
abstract AbstractImageProviderWrapper createCopy (Image image );
2090
2057
abstract boolean isDisposed ();
2091
2058
2059
+ protected void destroy () {
2060
+ }
2061
+ }
2062
+
2063
+ private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
2064
+ private boolean isDestroyed ;
2065
+ private final int width ;
2066
+ private final int height ;
2067
+
2068
+ PlainImageProviderWrapper (int width , int height ) {
2069
+ if (width <= 0 || height <= 0 ) {
2070
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
2071
+ }
2072
+ this .width = width ;
2073
+ this .height = height ;
2074
+ type = SWT .BITMAP ;
2075
+ }
2076
+
2077
+ @ Override
2078
+ protected Rectangle getBounds (int zoom ) {
2079
+ Rectangle rectangle = new Rectangle (0 , 0 , width , height );
2080
+ return DPIUtil .scaleUp (rectangle , zoom );
2081
+ }
2082
+
2083
+ @ Override
2084
+ ImageData getImageData (int zoom ) {
2085
+ if (zoomLevelToImageHandle .isEmpty () || zoomLevelToImageHandle .containsKey (zoom )) {
2086
+ return getImageMetadata (zoom ).getImageData ();
2087
+ }
2088
+
2089
+ return getScaledImageData (zoom );
2090
+ }
2091
+
2092
+ @ Override
2093
+ ImageHandle getImageMetadata (int zoom ) {
2094
+ if (zoomLevelToImageHandle .isEmpty ()) {
2095
+ long handle = initBaseHandle (zoom );
2096
+ ImageHandle imageHandle = new ImageHandle (handle , zoom );
2097
+ zoomLevelToImageHandle .put (zoom , imageHandle );
2098
+ return imageHandle ;
2099
+ } else if (zoomLevelToImageHandle .containsKey (zoom )) {
2100
+ return zoomLevelToImageHandle .get (zoom );
2101
+ } else {
2102
+ ImageData resizedData = getImageData (zoom );
2103
+ ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2104
+ init (newData , zoom );
2105
+ return zoomLevelToImageHandle .get (zoom );
2106
+ }
2107
+ }
2108
+
2109
+ private long initBaseHandle (int zoom ) {
2110
+ if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
2111
+ int scaledWidth = DPIUtil .scaleUp (width , zoom );
2112
+ int scaledHeight = DPIUtil .scaleUp (height , zoom );
2113
+ long hDC = device .internal_new_GC (null );
2114
+ long newHandle = OS .CreateCompatibleBitmap (hDC , scaledWidth , scaledHeight );
2115
+ /*
2116
+ * Feature in Windows. CreateCompatibleBitmap() may fail
2117
+ * for large images. The fix is to create a DIB section
2118
+ * in that case.
2119
+ */
2120
+ if (newHandle == 0 ) {
2121
+ int bits = OS .GetDeviceCaps (hDC , OS .BITSPIXEL );
2122
+ int planes = OS .GetDeviceCaps (hDC , OS .PLANES );
2123
+ int depth = bits * planes ;
2124
+ if (depth < 16 ) depth = 16 ;
2125
+ if (depth > 24 ) depth = 24 ;
2126
+ newHandle = createDIB (scaledWidth , scaledHeight , depth );
2127
+ }
2128
+ if (newHandle != 0 ) {
2129
+ long memDC = OS .CreateCompatibleDC (hDC );
2130
+ long hOldBitmap = OS .SelectObject (memDC , newHandle );
2131
+ OS .PatBlt (memDC , 0 , 0 , scaledWidth , scaledHeight , OS .PATCOPY );
2132
+ OS .SelectObject (memDC , hOldBitmap );
2133
+ OS .DeleteDC (memDC );
2134
+ }
2135
+ device .internal_dispose_GC (hDC , null );
2136
+ if (newHandle == 0 ) {
2137
+ SWT .error (SWT .ERROR_NO_HANDLES , null , device .getLastError ());
2138
+ }
2139
+ return newHandle ;
2140
+ }
2141
+
2142
+ @ Override
2143
+ AbstractImageProviderWrapper createCopy (Image image ) {
2144
+ return image .new PlainImageProviderWrapper (width , height );
2145
+ }
2146
+
2147
+ @ Override
2148
+ protected void destroy () {
2149
+ this .isDestroyed = true ;
2150
+ }
2151
+
2152
+ @ Override
2153
+ boolean isDisposed () {
2154
+ return isDestroyed ;
2155
+ }
2156
+ }
2157
+
2158
+ private abstract class DynamicImageProviderWrapper extends AbstractImageProviderWrapper {
2159
+ abstract Object getProvider ();
2160
+
2092
2161
protected void checkProvider (Object provider , Class <?> expectedClass ) {
2093
2162
if (provider == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
2094
2163
if (!expectedClass .isAssignableFrom (provider .getClass ())) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
@@ -2101,15 +2170,12 @@ public int hashCode() {
2101
2170
2102
2171
@ Override
2103
2172
public boolean equals (Object otherProvider ) {
2104
- return otherProvider instanceof AbstractImageProviderWrapper aip //
2105
- && getProvider ().equals (aip .getProvider ());
2106
- }
2107
-
2108
- protected void destroy () {
2173
+ return otherProvider instanceof DynamicImageProviderWrapper aip
2174
+ && Objects .equals (getProvider (), aip .getProvider ());
2109
2175
}
2110
2176
}
2111
2177
2112
- private class ImageFileNameProviderWrapper extends AbstractImageProviderWrapper {
2178
+ private class ImageFileNameProviderWrapper extends DynamicImageProviderWrapper {
2113
2179
2114
2180
/**
2115
2181
* ImageFileNameProvider to provide file names at various Zoom levels
@@ -2175,7 +2241,7 @@ ImageFileNameProviderWrapper createCopy(Image image) {
2175
2241
}
2176
2242
}
2177
2243
2178
- private class ImageDataProviderWrapper extends AbstractImageProviderWrapper {
2244
+ private class ImageDataProviderWrapper extends DynamicImageProviderWrapper {
2179
2245
2180
2246
/**
2181
2247
* ImageDataProvider to provide ImageData at various Zoom levels
@@ -2225,13 +2291,13 @@ ImageDataProviderWrapper createCopy(Image image) {
2225
2291
}
2226
2292
}
2227
2293
2228
- private class ImageGcDrawerWrapper extends AbstractImageProviderWrapper {
2294
+ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
2229
2295
private ImageGcDrawer drawer ;
2230
2296
private int width ;
2231
2297
private int height ;
2232
2298
private boolean isDestroyed ;
2233
2299
2234
- public ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
2300
+ ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
2235
2301
checkProvider (imageGcDrawer , ImageGcDrawer .class );
2236
2302
this .drawer = imageGcDrawer ;
2237
2303
this .width = width ;
0 commit comments