|
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,76 @@ public static void drawAtSize(GC gc, ImageData imageData, int width, int height) |
1837 | 1839 | }); |
1838 | 1840 | } |
1839 | 1841 |
|
| 1842 | +@FunctionalInterface |
| 1843 | +interface HandleAtSizeConsumer { |
| 1844 | + void accept(Image imageAtBestPossibleSize); |
| 1845 | +} |
| 1846 | + |
| 1847 | +void executeOnImageHandleAtSize(HandleAtSizeConsumer handleAtSizeConsumer, int destWidth, int destHeight) { |
| 1848 | + Optional<Image> imageAtSize = cachedImageAtSize.refresh(destWidth, destHeight); |
| 1849 | + handleAtSizeConsumer.accept(imageAtSize.orElse(this)); |
| 1850 | +} |
| 1851 | + |
| 1852 | +private CachedImageAtSize cachedImageAtSize = new CachedImageAtSize(); |
| 1853 | + |
| 1854 | +private class CachedImageAtSize { |
| 1855 | + private Image image; |
| 1856 | + |
| 1857 | + public void destroy() { |
| 1858 | + if (image != null) { |
| 1859 | + image.dispose(); |
| 1860 | + image = null; |
| 1861 | + } |
| 1862 | + } |
| 1863 | + |
| 1864 | + private Optional<Image> refresh(int destWidth, int destHeight) { |
| 1865 | + if (isReusable(destHeight, destWidth)) { |
| 1866 | + return Optional.of(image); |
| 1867 | + } else { |
| 1868 | + destroy(); |
| 1869 | + Optional<Image> imageAtSize = loadImageAtSize(destWidth, destHeight); |
| 1870 | + image = imageAtSize.orElse(null); |
| 1871 | + return imageAtSize; |
| 1872 | + } |
| 1873 | + } |
| 1874 | + |
| 1875 | + private boolean isReusable(int height, int width) { |
| 1876 | + return image != null && image.height == height && image.width == width; |
| 1877 | + } |
| 1878 | + |
| 1879 | + private Optional<Image> loadImageAtSize(int destWidth, int destHeight) { |
| 1880 | + Optional<ImageData> imageData = loadImageDataAtExactSize(pointToPixel(destWidth, DPIUtil.getDeviceZoom()), pointToPixel(destHeight, DPIUtil.getDeviceZoom())); |
| 1881 | + if (imageData.isEmpty()) { |
| 1882 | + return Optional.empty(); |
| 1883 | + } |
| 1884 | + Image image = new Image(device, imageData.get()); |
| 1885 | + NSBitmapImageRep representation = image.getRepresentation(100); |
| 1886 | + if (styleFlag != SWT.IMAGE_COPY) { |
| 1887 | + image.createRepFromSourceAndApplyFlag(representation, pointToPixel(destWidth, DPIUtil.getDeviceZoom()), pointToPixel(destHeight, DPIUtil.getDeviceZoom()), styleFlag); |
| 1888 | + image.handle.removeRepresentation(representation); |
| 1889 | + } |
| 1890 | + return Optional.of(image); |
| 1891 | + } |
| 1892 | + |
| 1893 | + private Optional<ImageData> loadImageDataAtExactSize(int targetWidth, int targetHeight) { |
| 1894 | + if (imageDataProvider instanceof ImageDataAtSizeProvider imageDataAtSizeProvider) { |
| 1895 | + ImageData imageData = imageDataAtSizeProvider.getImageData(targetWidth, targetHeight); |
| 1896 | + if (imageData == null) { |
| 1897 | + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, |
| 1898 | + " ImageDataAtSizeProvider returned null for width=" + targetWidth + ", height=" + targetHeight); |
| 1899 | + } |
| 1900 | + return Optional.of(imageData); |
| 1901 | + } |
| 1902 | + if (imageFileNameProvider != null) { |
| 1903 | + String fileName = DPIUtil.validateAndGetImagePathAtZoom(imageFileNameProvider, 100).element(); |
| 1904 | + if (ImageDataLoader.isDynamicallySizable(fileName)) { |
| 1905 | + ImageData imageDataAtSize = ImageDataLoader.loadBySize(fileName, targetWidth, targetHeight); |
| 1906 | + return Optional.of(imageDataAtSize); |
| 1907 | + } |
| 1908 | + } |
| 1909 | + return Optional.empty(); |
| 1910 | + } |
| 1911 | +} |
| 1912 | + |
1840 | 1913 | } |
1841 | 1914 |
|
0 commit comments