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