@@ -803,11 +803,12 @@ private ImageData applyGrayImageData(ImageData data, int pHeight, int pWidth) {
803
803
return newData ;
804
804
}
805
805
806
- private ImageHandle getImageMetadata (int zoom ) {
807
- if (zoomLevelToImageHandle .get (zoom ) != null ) {
808
- return zoomLevelToImageHandle .get (zoom );
806
+ private ImageHandle getImageMetadata (ZoomContext zoomContext ) {
807
+ int targetZoom = zoomContext .targetZoom ();
808
+ if (zoomLevelToImageHandle .get (targetZoom ) != null ) {
809
+ return zoomLevelToImageHandle .get (targetZoom );
809
810
}
810
- return imageProvider .newImageHandle (zoom );
811
+ return imageProvider .newImageHandle (zoomContext );
811
812
}
812
813
813
814
@@ -828,10 +829,10 @@ private ImageHandle getImageMetadata(int zoom) {
828
829
* @noreference This method is not intended to be referenced by clients.
829
830
*/
830
831
public static long win32_getHandle (Image image , int zoom ) {
831
- if (image .isDisposed ()) {
832
+ if (image .isDisposed ()) {
832
833
return 0L ;
833
834
}
834
- return image .getImageMetadata (zoom ).handle ;
835
+ return image .getImageMetadata (new ZoomContext ( zoom ) ).handle ;
835
836
}
836
837
837
838
/**
@@ -1265,7 +1266,7 @@ public ImageData getImageData (int zoom) {
1265
1266
if (zoomLevelToImageHandle .containsKey (zoom )) {
1266
1267
return zoomLevelToImageHandle .get (zoom ).getImageData ();
1267
1268
}
1268
- return this .imageProvider .newImageData (zoom );
1269
+ return this .imageProvider .newImageData (new ZoomContext ( zoom ) );
1269
1270
}
1270
1271
1271
1272
@@ -1742,7 +1743,7 @@ public long internal_new_GC (GCData data) {
1742
1743
return this .imageProvider .configureGCData (data );
1743
1744
}
1744
1745
1745
- private long configureGC (GCData data , int zoom ) {
1746
+ private long configureGC (GCData data , ZoomContext zoomContext ) {
1746
1747
if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
1747
1748
/*
1748
1749
* Create a new GC that can draw into the image.
@@ -1753,7 +1754,7 @@ private long configureGC(GCData data, int zoom) {
1753
1754
}
1754
1755
1755
1756
if (Device .strictChecks ) {
1756
- checkImageTypeForValidCustomDrawing (zoom );
1757
+ checkImageTypeForValidCustomDrawing (zoomContext . targetZoom () );
1757
1758
}
1758
1759
/* Create a compatible HDC for the device */
1759
1760
long hDC = device .internal_new_GC (null );
@@ -1770,9 +1771,9 @@ private long configureGC(GCData data, int zoom) {
1770
1771
data .style |= SWT .LEFT_TO_RIGHT ;
1771
1772
}
1772
1773
data .device = device ;
1773
- data .nativeZoom = zoom ;
1774
+ data .nativeZoom = zoomContext . nativeZoom () ;
1774
1775
data .image = this ;
1775
- data .font = SWTFontProvider .getSystemFont (device , zoom );
1776
+ data .font = SWTFontProvider .getSystemFont (device , zoomContext . nativeZoom () );
1776
1777
}
1777
1778
return imageDC ;
1778
1779
}
@@ -1882,7 +1883,7 @@ public String toString () {
1882
1883
1883
1884
<T > T applyUsingAnyHandle (Function <ImageHandle , T > function ) {
1884
1885
if (zoomLevelToImageHandle .isEmpty ()) {
1885
- ImageHandle temporaryHandle = this .imageProvider .newImageHandle (DPIUtil .getDeviceZoom ());
1886
+ ImageHandle temporaryHandle = this .imageProvider .newImageHandle (new ZoomContext ( DPIUtil .getDeviceZoom (), DPIUtil . getNativeDeviceZoom () ));
1886
1887
try {
1887
1888
return function .apply (temporaryHandle );
1888
1889
} finally {
@@ -1913,42 +1914,57 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
1913
1914
return new Image (device , type , handle , nativeZoom );
1914
1915
}
1915
1916
1917
+ /**
1918
+ * ZoomContext holds information about zoom details used to create and cache the image
1919
+ *
1920
+ * @param targetZoom zoom value the OS handle will be created, cached and served for,
1921
+ * it is usually an auto-scaled zoom
1922
+ * @param nativeZoom native zoom that can be used as context for the creation
1923
+ * of the handle, e.g. as font zoom for drawing on the image with a GC
1924
+ */
1925
+ private record ZoomContext (int targetZoom , int nativeZoom ) {
1926
+
1927
+ private ZoomContext (int targetZoom ) {
1928
+ this (targetZoom , targetZoom );
1929
+ }
1930
+ }
1931
+
1916
1932
private abstract class AbstractImageProviderWrapper {
1917
1933
1918
1934
protected abstract Rectangle getBounds (int zoom );
1919
1935
1920
1936
protected long configureGCData (GCData data ) {
1921
- return configureGC (data , 100 );
1937
+ return configureGC (data , new ZoomContext ( 100 ) );
1922
1938
}
1923
1939
1924
1940
public Collection <Integer > getPreservedZoomLevels () {
1925
1941
return Collections .emptySet ();
1926
1942
}
1927
1943
1928
- abstract ImageData newImageData (int zoom );
1944
+ abstract ImageData newImageData (ZoomContext zoomContext );
1929
1945
1930
1946
abstract AbstractImageProviderWrapper createCopy (Image image );
1931
1947
1932
1948
ImageData getScaledImageData (int zoom ) {
1933
1949
TreeSet <Integer > availableZooms = new TreeSet <>(zoomLevelToImageHandle .keySet ());
1934
1950
int closestZoom = Optional .ofNullable (availableZooms .higher (zoom )).orElse (availableZooms .lower (zoom ));
1935
- return DPIUtil .scaleImageData (device , getImageMetadata (closestZoom ).getImageData (), zoom , closestZoom );
1951
+ return DPIUtil .scaleImageData (device , getImageMetadata (new ZoomContext ( closestZoom ) ).getImageData (), zoom , closestZoom );
1936
1952
}
1937
1953
1938
- protected ImageHandle newImageHandle (int zoom ) {
1939
- ImageData resizedData = getImageData (zoom );
1940
- return newImageHandle (resizedData , zoom );
1954
+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
1955
+ ImageData resizedData = getImageData (zoomContext . targetZoom () );
1956
+ return newImageHandle (resizedData , zoomContext );
1941
1957
}
1942
1958
1943
- protected final ImageHandle newImageHandle (ImageData data , int zoom ) {
1959
+ protected final ImageHandle newImageHandle (ImageData data , ZoomContext zoomContext ) {
1944
1960
if (type == SWT .ICON && data .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
1945
1961
// If the original type was an icon with transparency mask and re-scaling leads
1946
1962
// to image data without transparency mask, this will create invalid images
1947
1963
// so this fallback will "repair" the image data by explicitly passing
1948
1964
// the transparency mask created from the scaled image data
1949
- return initIconHandle (device , data , data .getTransparencyMask (), zoom );
1965
+ return initIconHandle (device , data , data .getTransparencyMask (), zoomContext . targetZoom () );
1950
1966
} else {
1951
- return init (data , zoom );
1967
+ return init (data , zoomContext . targetZoom () );
1952
1968
}
1953
1969
}
1954
1970
}
@@ -1977,8 +1993,8 @@ protected Rectangle getBounds(int zoom) {
1977
1993
}
1978
1994
1979
1995
@ Override
1980
- ImageData newImageData (int zoom ) {
1981
- return getScaledImageData (zoom );
1996
+ ImageData newImageData (ZoomContext zoomContext ) {
1997
+ return getScaledImageData (zoomContext . targetZoom () );
1982
1998
}
1983
1999
1984
2000
@ Override
@@ -2000,34 +2016,34 @@ private abstract class ImageFromImageDataProviderWrapper extends AbstractImagePr
2000
2016
void initImage () {
2001
2017
// As the init call configured some Image attributes (e.g. type)
2002
2018
// it must be called
2003
- newImageData (100 );
2019
+ newImageData (new ZoomContext ( 100 ) );
2004
2020
}
2005
2021
2006
2022
@ Override
2007
- ImageData newImageData (int zoom ) {
2023
+ ImageData newImageData (ZoomContext zoomContext ) {
2008
2024
Function <Integer , ImageData > imageDataRetrieval = zoomToRetrieve -> {
2009
- ImageHandle handle = initializeHandleFromSource (zoomToRetrieve );
2025
+ ImageHandle handle = initializeHandleFromSource (zoomContext );
2010
2026
ImageData data = handle .getImageData ();
2011
2027
handle .destroy ();
2012
2028
return data ;
2013
2029
};
2014
- return cachedImageData .computeIfAbsent (zoom , imageDataRetrieval );
2030
+ return cachedImageData .computeIfAbsent (zoomContext . targetZoom () , imageDataRetrieval );
2015
2031
}
2016
2032
2017
2033
@ Override
2018
- protected ImageHandle newImageHandle (int zoom ) {
2019
- ImageData cachedData = cachedImageData .remove (zoom );
2034
+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2035
+ ImageData cachedData = cachedImageData .remove (zoomContext . targetZoom () );
2020
2036
if (cachedData != null ) {
2021
- return newImageHandle (cachedData , zoom );
2037
+ return newImageHandle (cachedData , zoomContext );
2022
2038
}
2023
- return initializeHandleFromSource (zoom );
2039
+ return initializeHandleFromSource (zoomContext );
2024
2040
}
2025
2041
2026
- private ImageHandle initializeHandleFromSource (int zoom ) {
2027
- ElementAtZoom <ImageData > imageDataAtZoom = loadImageData (zoom );
2028
- ImageData imageData = DPIUtil .scaleImageData (device , imageDataAtZoom .element (), zoom , imageDataAtZoom .zoom ());
2042
+ private ImageHandle initializeHandleFromSource (ZoomContext zoomContext ) {
2043
+ ElementAtZoom <ImageData > imageDataAtZoom = loadImageData (zoomContext . targetZoom () );
2044
+ ImageData imageData = DPIUtil .scaleImageData (device , imageDataAtZoom .element (), zoomContext . targetZoom () , imageDataAtZoom .zoom ());
2029
2045
imageData = adaptImageDataIfDisabledOrGray (imageData );
2030
- return newImageHandle (imageData , zoom );
2046
+ return newImageHandle (imageData , zoomContext );
2031
2047
}
2032
2048
2033
2049
}
@@ -2149,7 +2165,7 @@ public Collection<Integer> getPreservedZoomLevels() {
2149
2165
2150
2166
@ Override
2151
2167
protected long configureGCData (GCData data ) {
2152
- return configureGC (data , DPIUtil .getDeviceZoom ());
2168
+ return configureGC (data , new ZoomContext ( DPIUtil .getDeviceZoom () ));
2153
2169
}
2154
2170
2155
2171
@ Override
@@ -2159,33 +2175,35 @@ protected Rectangle getBounds(int zoom) {
2159
2175
}
2160
2176
2161
2177
@ Override
2162
- ImageData newImageData (int zoom ) {
2178
+ ImageData newImageData (ZoomContext zoomContext ) {
2179
+ int targetZoom = zoomContext .targetZoom ();
2163
2180
if (zoomLevelToImageHandle .isEmpty ()) {
2164
- return createBaseHandle (zoom ).getImageData ();
2181
+ return createBaseHandle (targetZoom ).getImageData ();
2165
2182
}
2166
2183
// if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
2167
2184
// be a destructive operation. Therefor, a new handle is created for the requested zoom
2168
2185
if (memGC != null ) {
2169
- return newImageHandle (zoom ).getImageData ();
2186
+ return newImageHandle (zoomContext ).getImageData ();
2170
2187
}
2171
- return getScaledImageData (zoom );
2188
+ return getScaledImageData (targetZoom );
2172
2189
}
2173
2190
2174
2191
@ Override
2175
- protected ImageHandle newImageHandle (int zoom ) {
2192
+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2193
+ int targetZoom = zoomContext .targetZoom ();
2176
2194
if (zoomLevelToImageHandle .isEmpty ()) {
2177
- return createBaseHandle (zoom );
2195
+ return createBaseHandle (targetZoom );
2178
2196
}
2179
2197
if (memGC != null ) {
2180
- if (memGC .getZoom () != zoom ) {
2198
+ if (memGC .getZoom () != targetZoom ) {
2181
2199
GC currentGC = memGC ;
2182
2200
memGC = null ;
2183
- createHandle (zoom );
2184
- currentGC .refreshFor (new DrawableWrapper (Image .this , zoom ));
2201
+ createHandle (targetZoom );
2202
+ currentGC .refreshFor (new DrawableWrapper (Image .this , zoomContext ));
2185
2203
}
2186
- return zoomLevelToImageHandle .get (zoom );
2204
+ return zoomLevelToImageHandle .get (targetZoom );
2187
2205
}
2188
- return super .newImageHandle (zoom );
2206
+ return super .newImageHandle (zoomContext );
2189
2207
}
2190
2208
private ImageHandle createBaseHandle (int zoom ) {
2191
2209
baseZoom = zoom ;
@@ -2274,29 +2292,30 @@ Object getProvider() {
2274
2292
}
2275
2293
2276
2294
@ Override
2277
- ImageData newImageData (int zoom ) {
2295
+ ImageData newImageData (ZoomContext zoomContext ) {
2278
2296
Function <Integer , ImageData > imageDataRetrival = zoomToRetrieve -> {
2279
2297
ImageHandle handle = initializeHandleFromSource (zoomToRetrieve );
2280
2298
ImageData data = handle .getImageData ();
2281
2299
handle .destroy ();
2282
2300
return data ;
2283
2301
};
2284
- return cachedImageData .computeIfAbsent (zoom , imageDataRetrival );
2302
+ return cachedImageData .computeIfAbsent (zoomContext . targetZoom () , imageDataRetrival );
2285
2303
}
2286
2304
2287
2305
2288
2306
@ Override
2289
- protected ImageHandle newImageHandle (int zoom ) {
2290
- ImageData cachedData = cachedImageData .remove (zoom );
2307
+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2308
+ int targetZoom = zoomContext .targetZoom ();
2309
+ ImageData cachedData = cachedImageData .remove (targetZoom );
2291
2310
if (cachedData != null ) {
2292
- return init (cachedData , zoom );
2311
+ return init (cachedData , targetZoom );
2293
2312
}
2294
- return initializeHandleFromSource (zoom );
2313
+ return initializeHandleFromSource (targetZoom );
2295
2314
}
2296
2315
2297
2316
private ImageHandle initializeHandleFromSource (int zoom ) {
2298
2317
ElementAtZoom <ImageData > imageDataAtZoom = loadImageData (zoom );
2299
- ImageData imageData = DPIUtil .scaleImageData (device ,imageDataAtZoom .element (), zoom , imageDataAtZoom .zoom ());
2318
+ ImageData imageData = DPIUtil .scaleImageData (device , imageDataAtZoom .element (), zoom , imageDataAtZoom .zoom ());
2300
2319
imageData = adaptImageDataIfDisabledOrGray (imageData );
2301
2320
return init (imageData , zoom );
2302
2321
}
@@ -2315,7 +2334,7 @@ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper<Imag
2315
2334
super (provider , ImageFileNameProvider .class );
2316
2335
// Checks for the contract of the passed provider require
2317
2336
// checking for valid image data creation
2318
- newImageData (DPIUtil .getDeviceZoom ());
2337
+ newImageData (new ZoomContext ( DPIUtil .getDeviceZoom () ));
2319
2338
}
2320
2339
2321
2340
@ Override
@@ -2569,7 +2588,7 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
2569
2588
private ImageGcDrawer drawer ;
2570
2589
private int width ;
2571
2590
private int height ;
2572
- private int currentZoom = 100 ;
2591
+ private ZoomContext currentZoom = new ZoomContext ( 100 ) ;
2573
2592
2574
2593
ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
2575
2594
checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2590,32 +2609,33 @@ protected long configureGCData(GCData data) {
2590
2609
}
2591
2610
2592
2611
@ Override
2593
- ImageData newImageData (int zoom ) {
2594
- return getImageMetadata (zoom ).getImageData ();
2612
+ ImageData newImageData (ZoomContext zoomContext ) {
2613
+ return getImageMetadata (zoomContext ).getImageData ();
2595
2614
}
2596
2615
2597
2616
@ Override
2598
- protected ImageHandle newImageHandle (int zoom ) {
2599
- currentZoom = zoom ;
2617
+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2618
+ currentZoom = zoomContext ;
2619
+ int targetZoom = zoomContext .targetZoom ();
2600
2620
int gcStyle = drawer .getGcStyle ();
2601
2621
Image image ;
2602
2622
if ((gcStyle & SWT .TRANSPARENT ) != 0 ) {
2603
- int scaledHeight = Win32DPIUtils .pointToPixel (height , zoom );
2604
- int scaledWidth = Win32DPIUtils .pointToPixel (width , zoom );
2623
+ int scaledHeight = Win32DPIUtils .pointToPixel (height , targetZoom );
2624
+ int scaledWidth = Win32DPIUtils .pointToPixel (width , targetZoom );
2605
2625
/* Create a 24 bit image data with alpha channel */
2606
2626
final ImageData resultData = new ImageData (scaledWidth , scaledHeight , 24 , new PaletteData (0xFF , 0xFF00 , 0xFF0000 ));
2607
2627
resultData .alphaData = new byte [scaledWidth * scaledHeight ];
2608
- image = new Image (device , resultData , zoom );
2628
+ image = new Image (device , resultData , targetZoom );
2609
2629
} else {
2610
2630
image = new Image (device , width , height );
2611
2631
}
2612
- GC gc = new GC (new DrawableWrapper (image , zoom ), gcStyle );
2632
+ GC gc = new GC (new DrawableWrapper (image , zoomContext ), gcStyle );
2613
2633
try {
2614
2634
drawer .drawOn (gc , width , height );
2615
- ImageData imageData = image .getImageMetadata ( zoom ). getImageData ();
2635
+ ImageData imageData = image .getImageData (targetZoom );
2616
2636
drawer .postProcess (imageData );
2617
2637
ImageData newData = adaptImageDataIfDisabledOrGray (imageData );
2618
- return init (newData , zoom );
2638
+ return init (newData , targetZoom );
2619
2639
} finally {
2620
2640
gc .dispose ();
2621
2641
image .dispose ();
@@ -2646,16 +2666,16 @@ public boolean equals(Object otherProvider) {
2646
2666
2647
2667
private static class DrawableWrapper implements Drawable {
2648
2668
private final Image image ;
2649
- private final int zoom ;
2669
+ private final ZoomContext zoomContext ;
2650
2670
2651
- public DrawableWrapper (Image image , int zoom ) {
2671
+ public DrawableWrapper (Image image , ZoomContext zoomContext ) {
2652
2672
this .image = image ;
2653
- this .zoom = zoom ;
2673
+ this .zoomContext = zoomContext ;
2654
2674
}
2655
2675
2656
2676
@ Override
2657
2677
public long internal_new_GC (GCData data ) {
2658
- return this .image .configureGC (data , zoom );
2678
+ return this .image .configureGC (data , zoomContext );
2659
2679
}
2660
2680
2661
2681
@ Override
0 commit comments