@@ -803,11 +803,12 @@ private ImageData applyGrayImageData(ImageData data, int pHeight, int pWidth) {
803803 return newData ;
804804}
805805
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 );
809810 }
810- return imageProvider .newImageHandle (zoom );
811+ return imageProvider .newImageHandle (zoomContext );
811812}
812813
813814
@@ -828,10 +829,10 @@ private ImageHandle getImageMetadata(int zoom) {
828829 * @noreference This method is not intended to be referenced by clients.
829830 */
830831public static long win32_getHandle (Image image , int zoom ) {
831- if (image .isDisposed ()) {
832+ if (image .isDisposed ()) {
832833 return 0L ;
833834 }
834- return image .getImageMetadata (zoom ).handle ;
835+ return image .getImageMetadata (new ZoomContext ( zoom ) ).handle ;
835836}
836837
837838/**
@@ -1265,7 +1266,7 @@ public ImageData getImageData (int zoom) {
12651266 if (zoomLevelToImageHandle .containsKey (zoom )) {
12661267 return zoomLevelToImageHandle .get (zoom ).getImageData ();
12671268 }
1268- return this .imageProvider .newImageData (zoom );
1269+ return this .imageProvider .newImageData (new ZoomContext ( zoom ) );
12691270}
12701271
12711272
@@ -1742,7 +1743,7 @@ public long internal_new_GC (GCData data) {
17421743 return this .imageProvider .configureGCData (data );
17431744}
17441745
1745- private long configureGC (GCData data , int zoom ) {
1746+ private long configureGC (GCData data , ZoomContext zoomContext ) {
17461747 if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
17471748 /*
17481749 * Create a new GC that can draw into the image.
@@ -1753,7 +1754,7 @@ private long configureGC(GCData data, int zoom) {
17531754 }
17541755
17551756 if (Device .strictChecks ) {
1756- checkImageTypeForValidCustomDrawing (zoom );
1757+ checkImageTypeForValidCustomDrawing (zoomContext . targetZoom () );
17571758 }
17581759 /* Create a compatible HDC for the device */
17591760 long hDC = device .internal_new_GC (null );
@@ -1770,9 +1771,9 @@ private long configureGC(GCData data, int zoom) {
17701771 data .style |= SWT .LEFT_TO_RIGHT ;
17711772 }
17721773 data .device = device ;
1773- data .nativeZoom = zoom ;
1774+ data .nativeZoom = zoomContext . nativeZoom () ;
17741775 data .image = this ;
1775- data .font = SWTFontProvider .getSystemFont (device , zoom );
1776+ data .font = SWTFontProvider .getSystemFont (device , zoomContext . nativeZoom () );
17761777 }
17771778 return imageDC ;
17781779}
@@ -1882,7 +1883,7 @@ public String toString () {
18821883
18831884<T > T applyUsingAnyHandle (Function <ImageHandle , T > function ) {
18841885 if (zoomLevelToImageHandle .isEmpty ()) {
1885- ImageHandle temporaryHandle = this .imageProvider .newImageHandle (DPIUtil .getDeviceZoom ());
1886+ ImageHandle temporaryHandle = this .imageProvider .newImageHandle (new ZoomContext ( DPIUtil .getDeviceZoom (), DPIUtil . getNativeDeviceZoom () ));
18861887 try {
18871888 return function .apply (temporaryHandle );
18881889 } finally {
@@ -1913,42 +1914,57 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
19131914 return new Image (device , type , handle , nativeZoom );
19141915}
19151916
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+
19161932private abstract class AbstractImageProviderWrapper {
19171933
19181934 protected abstract Rectangle getBounds (int zoom );
19191935
19201936 protected long configureGCData (GCData data ) {
1921- return configureGC (data , 100 );
1937+ return configureGC (data , new ZoomContext ( 100 ) );
19221938 }
19231939
19241940 public Collection <Integer > getPreservedZoomLevels () {
19251941 return Collections .emptySet ();
19261942 }
19271943
1928- abstract ImageData newImageData (int zoom );
1944+ abstract ImageData newImageData (ZoomContext zoomContext );
19291945
19301946 abstract AbstractImageProviderWrapper createCopy (Image image );
19311947
19321948 ImageData getScaledImageData (int zoom ) {
19331949 TreeSet <Integer > availableZooms = new TreeSet <>(zoomLevelToImageHandle .keySet ());
19341950 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 );
19361952 }
19371953
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 );
19411957 }
19421958
1943- protected final ImageHandle newImageHandle (ImageData data , int zoom ) {
1959+ protected final ImageHandle newImageHandle (ImageData data , ZoomContext zoomContext ) {
19441960 if (type == SWT .ICON && data .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
19451961 // If the original type was an icon with transparency mask and re-scaling leads
19461962 // to image data without transparency mask, this will create invalid images
19471963 // so this fallback will "repair" the image data by explicitly passing
19481964 // 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 () );
19501966 } else {
1951- return init (data , zoom );
1967+ return init (data , zoomContext . targetZoom () );
19521968 }
19531969 }
19541970}
@@ -1977,8 +1993,8 @@ protected Rectangle getBounds(int zoom) {
19771993 }
19781994
19791995 @ Override
1980- ImageData newImageData (int zoom ) {
1981- return getScaledImageData (zoom );
1996+ ImageData newImageData (ZoomContext zoomContext ) {
1997+ return getScaledImageData (zoomContext . targetZoom () );
19821998 }
19831999
19842000 @ Override
@@ -2000,34 +2016,34 @@ private abstract class ImageFromImageDataProviderWrapper extends AbstractImagePr
20002016 void initImage () {
20012017 // As the init call configured some Image attributes (e.g. type)
20022018 // it must be called
2003- newImageData (100 );
2019+ newImageData (new ZoomContext ( 100 ) );
20042020 }
20052021
20062022 @ Override
2007- ImageData newImageData (int zoom ) {
2023+ ImageData newImageData (ZoomContext zoomContext ) {
20082024 Function <Integer , ImageData > imageDataRetrieval = zoomToRetrieve -> {
2009- ImageHandle handle = initializeHandleFromSource (zoomToRetrieve );
2025+ ImageHandle handle = initializeHandleFromSource (zoomContext );
20102026 ImageData data = handle .getImageData ();
20112027 handle .destroy ();
20122028 return data ;
20132029 };
2014- return cachedImageData .computeIfAbsent (zoom , imageDataRetrieval );
2030+ return cachedImageData .computeIfAbsent (zoomContext . targetZoom () , imageDataRetrieval );
20152031 }
20162032
20172033 @ 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 () );
20202036 if (cachedData != null ) {
2021- return newImageHandle (cachedData , zoom );
2037+ return newImageHandle (cachedData , zoomContext );
20222038 }
2023- return initializeHandleFromSource (zoom );
2039+ return initializeHandleFromSource (zoomContext );
20242040 }
20252041
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 ());
20292045 imageData = adaptImageDataIfDisabledOrGray (imageData );
2030- return newImageHandle (imageData , zoom );
2046+ return newImageHandle (imageData , zoomContext );
20312047 }
20322048
20332049}
@@ -2149,7 +2165,7 @@ public Collection<Integer> getPreservedZoomLevels() {
21492165
21502166 @ Override
21512167 protected long configureGCData (GCData data ) {
2152- return configureGC (data , DPIUtil .getDeviceZoom ());
2168+ return configureGC (data , new ZoomContext ( DPIUtil .getDeviceZoom () ));
21532169 }
21542170
21552171 @ Override
@@ -2159,33 +2175,35 @@ protected Rectangle getBounds(int zoom) {
21592175 }
21602176
21612177 @ Override
2162- ImageData newImageData (int zoom ) {
2178+ ImageData newImageData (ZoomContext zoomContext ) {
2179+ int targetZoom = zoomContext .targetZoom ();
21632180 if (zoomLevelToImageHandle .isEmpty ()) {
2164- return createBaseHandle (zoom ).getImageData ();
2181+ return createBaseHandle (targetZoom ).getImageData ();
21652182 }
21662183 // if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
21672184 // be a destructive operation. Therefor, a new handle is created for the requested zoom
21682185 if (memGC != null ) {
2169- return newImageHandle (zoom ).getImageData ();
2186+ return newImageHandle (zoomContext ).getImageData ();
21702187 }
2171- return getScaledImageData (zoom );
2188+ return getScaledImageData (targetZoom );
21722189 }
21732190
21742191 @ Override
2175- protected ImageHandle newImageHandle (int zoom ) {
2192+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2193+ int targetZoom = zoomContext .targetZoom ();
21762194 if (zoomLevelToImageHandle .isEmpty ()) {
2177- return createBaseHandle (zoom );
2195+ return createBaseHandle (targetZoom );
21782196 }
21792197 if (memGC != null ) {
2180- if (memGC .getZoom () != zoom ) {
2198+ if (memGC .getZoom () != targetZoom ) {
21812199 GC currentGC = memGC ;
21822200 memGC = null ;
2183- createHandle (zoom );
2184- currentGC .refreshFor (new DrawableWrapper (Image .this , zoom ));
2201+ createHandle (targetZoom );
2202+ currentGC .refreshFor (new DrawableWrapper (Image .this , zoomContext ));
21852203 }
2186- return zoomLevelToImageHandle .get (zoom );
2204+ return zoomLevelToImageHandle .get (targetZoom );
21872205 }
2188- return super .newImageHandle (zoom );
2206+ return super .newImageHandle (zoomContext );
21892207 }
21902208 private ImageHandle createBaseHandle (int zoom ) {
21912209 baseZoom = zoom ;
@@ -2274,29 +2292,30 @@ Object getProvider() {
22742292 }
22752293
22762294 @ Override
2277- ImageData newImageData (int zoom ) {
2295+ ImageData newImageData (ZoomContext zoomContext ) {
22782296 Function <Integer , ImageData > imageDataRetrival = zoomToRetrieve -> {
22792297 ImageHandle handle = initializeHandleFromSource (zoomToRetrieve );
22802298 ImageData data = handle .getImageData ();
22812299 handle .destroy ();
22822300 return data ;
22832301 };
2284- return cachedImageData .computeIfAbsent (zoom , imageDataRetrival );
2302+ return cachedImageData .computeIfAbsent (zoomContext . targetZoom () , imageDataRetrival );
22852303 }
22862304
22872305
22882306 @ 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 );
22912310 if (cachedData != null ) {
2292- return init (cachedData , zoom );
2311+ return init (cachedData , targetZoom );
22932312 }
2294- return initializeHandleFromSource (zoom );
2313+ return initializeHandleFromSource (targetZoom );
22952314 }
22962315
22972316 private ImageHandle initializeHandleFromSource (int zoom ) {
22982317 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 ());
23002319 imageData = adaptImageDataIfDisabledOrGray (imageData );
23012320 return init (imageData , zoom );
23022321 }
@@ -2315,7 +2334,7 @@ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper<Imag
23152334 super (provider , ImageFileNameProvider .class );
23162335 // Checks for the contract of the passed provider require
23172336 // checking for valid image data creation
2318- newImageData (DPIUtil .getDeviceZoom ());
2337+ newImageData (new ZoomContext ( DPIUtil .getDeviceZoom () ));
23192338 }
23202339
23212340 @ Override
@@ -2569,7 +2588,7 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
25692588 private ImageGcDrawer drawer ;
25702589 private int width ;
25712590 private int height ;
2572- private int currentZoom = 100 ;
2591+ private ZoomContext currentZoom = new ZoomContext ( 100 ) ;
25732592
25742593 ImageGcDrawerWrapper (ImageGcDrawer imageGcDrawer , int width , int height ) {
25752594 checkProvider (imageGcDrawer , ImageGcDrawer .class );
@@ -2590,32 +2609,33 @@ protected long configureGCData(GCData data) {
25902609 }
25912610
25922611 @ Override
2593- ImageData newImageData (int zoom ) {
2594- return getImageMetadata (zoom ).getImageData ();
2612+ ImageData newImageData (ZoomContext zoomContext ) {
2613+ return getImageMetadata (zoomContext ).getImageData ();
25952614 }
25962615
25972616 @ Override
2598- protected ImageHandle newImageHandle (int zoom ) {
2599- currentZoom = zoom ;
2617+ protected ImageHandle newImageHandle (ZoomContext zoomContext ) {
2618+ currentZoom = zoomContext ;
2619+ int targetZoom = zoomContext .targetZoom ();
26002620 int gcStyle = drawer .getGcStyle ();
26012621 Image image ;
26022622 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 );
26052625 /* Create a 24 bit image data with alpha channel */
26062626 final ImageData resultData = new ImageData (scaledWidth , scaledHeight , 24 , new PaletteData (0xFF , 0xFF00 , 0xFF0000 ));
26072627 resultData .alphaData = new byte [scaledWidth * scaledHeight ];
2608- image = new Image (device , resultData , zoom );
2628+ image = new Image (device , resultData , targetZoom );
26092629 } else {
26102630 image = new Image (device , width , height );
26112631 }
2612- GC gc = new GC (new DrawableWrapper (image , zoom ), gcStyle );
2632+ GC gc = new GC (new DrawableWrapper (image , zoomContext ), gcStyle );
26132633 try {
26142634 drawer .drawOn (gc , width , height );
2615- ImageData imageData = image .getImageMetadata ( zoom ). getImageData ();
2635+ ImageData imageData = image .getImageData (targetZoom );
26162636 drawer .postProcess (imageData );
26172637 ImageData newData = adaptImageDataIfDisabledOrGray (imageData );
2618- return init (newData , zoom );
2638+ return init (newData , targetZoom );
26192639 } finally {
26202640 gc .dispose ();
26212641 image .dispose ();
@@ -2646,16 +2666,16 @@ public boolean equals(Object otherProvider) {
26462666
26472667private static class DrawableWrapper implements Drawable {
26482668 private final Image image ;
2649- private final int zoom ;
2669+ private final ZoomContext zoomContext ;
26502670
2651- public DrawableWrapper (Image image , int zoom ) {
2671+ public DrawableWrapper (Image image , ZoomContext zoomContext ) {
26522672 this .image = image ;
2653- this .zoom = zoom ;
2673+ this .zoomContext = zoomContext ;
26542674 }
26552675
26562676 @ Override
26572677 public long internal_new_GC (GCData data ) {
2658- return this .image .configureGC (data , zoom );
2678+ return this .image .configureGC (data , zoomContext );
26592679 }
26602680
26612681 @ Override
0 commit comments