@@ -927,6 +927,81 @@ void destroy() {
927927 memGC = null ;
928928}
929929
930+ private CachedImageAtSize cachedImageAtSize = new CachedImageAtSize ();
931+
932+ private class CachedImageAtSize {
933+ private Image image ;
934+
935+ public void destroy () {
936+ if (image != null ) {
937+ image .dispose ();
938+ image = null ;
939+ }
940+ }
941+
942+ private Optional <Image > refresh (int destWidth , int destHeight ) {
943+ int scaledWidth = DPIUtil .pointToPixel (destWidth , DPIUtil .getDeviceZoom ());
944+ int scaledHeight = DPIUtil .pointToPixel (destHeight , DPIUtil .getDeviceZoom ());
945+ if (isReusable (scaledWidth , scaledHeight )) {
946+ return Optional .of (image );
947+ } else {
948+ destroy ();
949+ Optional <Image > imageAtSize = loadImageAtSize (scaledWidth , scaledHeight );
950+ image = imageAtSize .orElse (null );
951+ return imageAtSize ;
952+ }
953+ }
954+
955+ private boolean isReusable (int width , int height ) {
956+ return image != null && image .height == height && image .width == width ;
957+ }
958+
959+ private Optional <Image > loadImageAtSize (int destWidth , int destHeight ) {
960+ Optional <ImageData > imageData = loadImageDataAtExactSize (destWidth , destHeight );
961+ if (imageData .isEmpty ()) {
962+ return Optional .empty ();
963+ }
964+ Image image = new Image (device , imageData .get (),100 );
965+ if (styleFlag != SWT .IMAGE_COPY ) {
966+ image .currentDeviceZoom =DPIUtil .getDeviceZoom ();
967+ Image styledImage = new Image (device , image , styleFlag );
968+ styledImage .currentDeviceZoom = 100 ;
969+ image .dispose ();
970+ image = styledImage ;
971+ }
972+ return Optional .of (image );
973+ }
974+
975+ private Optional <ImageData > loadImageDataAtExactSize (int targetWidth , int targetHeight ) {
976+ if (imageDataProvider instanceof ImageDataAtSizeProvider imageDataAtSizeProvider ) {
977+ ImageData imageData = imageDataAtSizeProvider .getImageData (targetWidth , targetHeight );
978+ if (imageData == null ) {
979+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
980+ " ImageDataAtSizeProvider returned null for width=" + targetWidth + ", height=" + targetHeight );
981+ }
982+ return Optional .of (imageData );
983+ }
984+ if (imageFileNameProvider != null ) {
985+ String fileName = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , 100 ).element ();
986+ if (ImageDataLoader .isDynamicallySizable (fileName )) {
987+ ImageData imageDataAtSize = ImageDataLoader .loadBySize (fileName , targetWidth , targetHeight );
988+ return Optional .of (imageDataAtSize );
989+ }
990+ }
991+ return Optional .empty ();
992+ }
993+ }
994+
995+ @ FunctionalInterface
996+ interface ImageAtSizeConsumer {
997+ void accept (Image image );
998+ }
999+
1000+ void executeOnImageAtSize (ImageAtSizeConsumer imageAtSizeConsumer , int destWidth , int destHeight ) {
1001+ Optional <Image > imageAtSize = cachedImageAtSize .refresh (destWidth , destHeight );
1002+ imageAtSizeConsumer .accept (imageAtSize .orElse (this ));
1003+ }
1004+
9301005/**
9311006 * Compares the argument to the receiver, and returns true
9321007 * if they represent the <em>same</em> object using a class
0 commit comments