@@ -136,30 +136,66 @@ public final class Image extends Resource implements Drawable {
136136
137137 private List <Consumer <Image >> onDisposeListeners ;
138138
139- private record CachedHandle (ImageHandle handleContainer , int requestedWidth , int requestedHeight ) {
139+ private class HandleAtSize {
140+ private ImageHandle handleContainer = null ;
141+ private int requestedWidth = -1 ;
142+ private int requestedHeight = -1 ;
140143
141144 public void destroy () {
142- if (handleContainer != null ) {
145+ if (handleContainer != null && ! zoomLevelToImageHandle . containsValue ( handleContainer ) ) {
143146 handleContainer .destroy ();
144147 }
148+ handleContainer = null ;
149+ requestedWidth = -1 ;
150+ requestedHeight = -1 ;
145151 }
146152
147- public boolean isReusable (int height , int width ) {
148- if (handleContainer == null ) {
153+ public ImageHandle refresh (int width , int height ) {
154+ if (!isReusable (width , height )) {
155+ destroy ();
156+ requestedWidth = width ;
157+ requestedHeight = height ;
158+ handleContainer = createHandleAtExactSize (width , height )
159+ .orElseGet (() -> getOrCreateImageHandleAtClosestSize (width , height ));
160+ }
161+ return handleContainer ;
162+ }
163+
164+ private boolean isReusable (int width , int height ) {
165+ if (handleContainer == null || handleContainer .isDisposed ()) {
149166 return false ;
150167 }
151168 return (requestedHeight == height && requestedWidth == width )
152169 || (handleContainer .height == height && handleContainer .width == width );
170+ }
153171
172+ private Optional <ImageHandle > createHandleAtExactSize (int width , int height ) {
173+ Optional <ImageData > imageData = imageProvider .loadImageDataAtExactSize (width , height );
174+ if (imageData .isPresent ()) {
175+ ImageData adaptedData = adaptImageDataIfDisabledOrGray (imageData .get ());
176+ ImageHandle imageHandle = init (adaptedData , -1 );
177+ return Optional .of (imageHandle );
178+ }
179+ return Optional .empty ();
154180 }
155181
156- public ImageHandle getHandle () {
157- return handleContainer ;
182+ private ImageHandle getOrCreateImageHandleAtClosestSize (int widthHint , int heightHint ) {
183+ Rectangle bounds = getBounds (100 );
184+ int imageZoomForWidth = 100 * widthHint / bounds .width ;
185+ int imageZoomForHeight = 100 * heightHint / bounds .height ;
186+ int imageZoom = DPIUtil .getZoomForAutoscaleProperty (Math .max (imageZoomForWidth , imageZoomForHeight ));
187+ ImageHandle bestFittingHandle = zoomLevelToImageHandle .get (imageZoom );
188+ if (bestFittingHandle == null ) {
189+ ImageData bestFittingImageData = imageProvider .loadImageData (imageZoom ).element ();
190+ ImageData adaptedData = adaptImageDataIfDisabledOrGray (bestFittingImageData );
191+ bestFittingHandle = init (adaptedData , -1 );
192+ }
193+ return bestFittingHandle ;
158194 }
159- };
160195
161- // Initialize lastRequestedHandle with -1 for size-related fields to indicate uninitialized values
162- CachedHandle lastRequestedHandle = new CachedHandle (null , -1 , -1 );
196+ }
197+
198+ private final HandleAtSize lastRequestedHandle = new HandleAtSize ();
163199
164200private Image (Device device , int type , long handle , int nativeZoom ) {
165201 super (device );
@@ -840,14 +876,8 @@ ImageHandle getHandle (int targetZoom, int nativeZoom) {
840876}
841877
842878void executeOnImageHandleAtBestFittingSize (Consumer <ImageHandle > handleAtSizeConsumer , int widthHint , int heightHint ) {
843- if (!lastRequestedHandle .isReusable (heightHint , widthHint )) {
844- ImageData imageData ;
845- imageData = this .imageProvider .loadImageDataAtSize (widthHint , heightHint );
846- lastRequestedHandle .destroy ();
847- ImageHandle handleContainer = init (imageData , -1 );
848- lastRequestedHandle = new CachedHandle (handleContainer , widthHint , heightHint );
849- }
850- handleAtSizeConsumer .accept (lastRequestedHandle .getHandle ());
879+ ImageHandle imageHandle = lastRequestedHandle .refresh (widthHint , heightHint );
880+ handleAtSizeConsumer .accept (imageHandle );
851881}
852882
853883/**
@@ -1083,8 +1113,8 @@ void destroy () {
10831113}
10841114
10851115private void destroyHandles () {
1086- destroyHandles (__ -> true );
10871116 lastRequestedHandle .destroy ();
1117+ destroyHandles (__ -> true );
10881118}
10891119
10901120@ Override
@@ -1992,22 +2022,6 @@ ElementAtZoom<ImageData> getClosestAvailableImageData(int zoom) {
19922022 return new ElementAtZoom <>(getImageMetadata (new ZoomContext (closestZoom )).getImageData (), closestZoom );
19932023 }
19942024
1995- public ImageData loadImageDataAtSize (int widthHint , int heightHint ) {
1996- Optional <ImageData > exact = loadImageDataAtExactSize (widthHint , heightHint );
1997- if (exact .isPresent ()) {
1998- return adaptImageDataIfDisabledOrGray (exact .get ());
1999- }
2000- return loadImageDataClosestTo (widthHint , heightHint );
2001- }
2002-
2003- private ImageData loadImageDataClosestTo (int targetWidth , int targetHeight ) {
2004- Rectangle bounds = getBounds (100 );
2005- int imageZoomForWidth = 100 * targetWidth / bounds .width ;
2006- int imageZoomForHeight = 100 * targetHeight / bounds .height ;
2007- int imageZoom = DPIUtil .getZoomForAutoscaleProperty (Math .max (imageZoomForWidth , imageZoomForHeight ));
2008- return loadImageData (imageZoom ).element ();
2009- }
2010-
20112025 protected Optional <ImageData > loadImageDataAtExactSize (int width , int height ) {
20122026 return Optional .empty (); // exact size not available
20132027 }
0 commit comments