|
14 | 14 | package org.eclipse.swt.graphics; |
15 | 15 |
|
16 | 16 |
|
| 17 | +import static org.eclipse.swt.internal.DPIUtil.pointToPixel; |
17 | 18 | import static org.eclipse.swt.internal.image.ImageColorTransformer.DEFAULT_DISABLED_IMAGE_TRANSFORMER; |
18 | 19 |
|
19 | 20 | import java.io.*; |
@@ -1177,6 +1178,7 @@ private NSBitmapImageRep createRepresentation(ImageData imageData, AlphaInfo alp |
1177 | 1178 |
|
1178 | 1179 | @Override |
1179 | 1180 | void destroy() { |
| 1181 | + cachedImageAtSize.destroy(); |
1180 | 1182 | if (memGC != null) memGC.dispose(); |
1181 | 1183 | handle.release(); |
1182 | 1184 | handle = null; |
@@ -1837,5 +1839,73 @@ public static void drawAtSize(GC gc, ImageData imageData, int width, int height) |
1837 | 1839 | }); |
1838 | 1840 | } |
1839 | 1841 |
|
| 1842 | +void executeOnImageAtSizeBestFittingSize(Consumer<Image> imageAtBestFittingSizeConsumer, int destWidth, int destHeight) { |
| 1843 | + Optional<Image> imageAtSize = cachedImageAtSize.refresh(destWidth, destHeight); |
| 1844 | + imageAtBestFittingSizeConsumer.accept(imageAtSize.orElse(this)); |
| 1845 | +} |
| 1846 | + |
| 1847 | +private CachedImageAtSize cachedImageAtSize = new CachedImageAtSize(); |
| 1848 | + |
| 1849 | +private class CachedImageAtSize { |
| 1850 | + private Image image; |
| 1851 | + |
| 1852 | + public void destroy() { |
| 1853 | + if (image != null) { |
| 1854 | + image.dispose(); |
| 1855 | + image = null; |
| 1856 | + } |
| 1857 | + } |
| 1858 | + |
| 1859 | + private Optional<Image> refresh(int destWidth, int destHeight) { |
| 1860 | + int scaledWidth = pointToPixel(destWidth, DPIUtil.getDeviceZoom()); |
| 1861 | + int scaledHeight = pointToPixel(destHeight, DPIUtil.getDeviceZoom()); |
| 1862 | + if (isReusable(scaledWidth, scaledHeight)) { |
| 1863 | + return Optional.of(image); |
| 1864 | + } else { |
| 1865 | + destroy(); |
| 1866 | + Optional<Image> imageAtSize = loadImageAtSize(scaledWidth, scaledHeight); |
| 1867 | + image = imageAtSize.orElse(null); |
| 1868 | + return imageAtSize; |
| 1869 | + } |
| 1870 | + } |
| 1871 | + |
| 1872 | + private boolean isReusable(int width, int height) { |
| 1873 | + return image != null && image.height == height && image.width == width; |
| 1874 | + } |
| 1875 | + |
| 1876 | + private Optional<Image> loadImageAtSize(int destWidth, int destHeight) { |
| 1877 | + Optional<ImageData> imageData = loadImageDataAtExactSize(destWidth, destHeight); |
| 1878 | + if (imageData.isEmpty()) { |
| 1879 | + return Optional.empty(); |
| 1880 | + } |
| 1881 | + Image image = new Image(device, imageData.get()); |
| 1882 | + if (styleFlag != SWT.IMAGE_COPY) { |
| 1883 | + NSBitmapImageRep representation = image.getRepresentation(100); |
| 1884 | + image.createRepFromSourceAndApplyFlag(representation, destWidth, destHeight, styleFlag); |
| 1885 | + image.handle.removeRepresentation(representation); |
| 1886 | + } |
| 1887 | + return Optional.of(image); |
| 1888 | + } |
| 1889 | + |
| 1890 | + private Optional<ImageData> loadImageDataAtExactSize(int targetWidth, int targetHeight) { |
| 1891 | + if (imageDataProvider instanceof ImageDataAtSizeProvider imageDataAtSizeProvider) { |
| 1892 | + ImageData imageData = imageDataAtSizeProvider.getImageData(targetWidth, targetHeight); |
| 1893 | + if (imageData == null) { |
| 1894 | + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, |
| 1895 | + " ImageDataAtSizeProvider returned null for width=" + targetWidth + ", height=" + targetHeight); |
| 1896 | + } |
| 1897 | + return Optional.of(imageData); |
| 1898 | + } |
| 1899 | + if (imageFileNameProvider != null) { |
| 1900 | + String fileName = DPIUtil.validateAndGetImagePathAtZoom(imageFileNameProvider, 100).element(); |
| 1901 | + if (ImageDataLoader.isDynamicallySizable(fileName)) { |
| 1902 | + ImageData imageDataAtSize = ImageDataLoader.loadBySize(fileName, targetWidth, targetHeight); |
| 1903 | + return Optional.of(imageDataAtSize); |
| 1904 | + } |
| 1905 | + } |
| 1906 | + return Optional.empty(); |
| 1907 | + } |
| 1908 | +} |
| 1909 | + |
1840 | 1910 | } |
1841 | 1911 |
|
0 commit comments