Skip to content

Commit d1113ca

Browse files
committed
[win32] Create ImageData based image handles on demand
This commit refactors the Image constructors using plain ImageData to create all handles on demand instead of creating a first handle in the constructor.
1 parent 909a985 commit d1113ca

File tree

1 file changed

+155
-15
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+155
-15
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 155 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,7 @@ public Image(Device device, ImageData data) {
371371
super(device);
372372
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
373373
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
374-
int deviceZoom = getZoom();
375-
data = scaleImageData(data, deviceZoom, 100);
376-
init(data, deviceZoom);
374+
this.imageProvider = new PlainImageDataProviderWrapper(data);
377375
init();
378376
this.device.registerResourceWithZoomSupport(this);
379377
}
@@ -416,10 +414,7 @@ public Image(Device device, ImageData source, ImageData mask) {
416414
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
417415
}
418416
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
419-
source = scaleImageData(source, getZoom(), 100);
420-
mask = scaleImageData(mask, getZoom(), 100);
421-
mask = ImageData.convertMask(mask);
422-
initIconHandle(this.device, source, mask, getZoom());
417+
this.imageProvider = new MaskedImageDataProviderWrapper(source, mask);
423418
init();
424419
this.device.registerResourceWithZoomSupport(this);
425420
}
@@ -479,11 +474,9 @@ public Image(Device device, ImageData source, ImageData mask) {
479474
*/
480475
public Image (Device device, InputStream stream) {
481476
super(device);
477+
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
482478
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
483-
int deviceZoom = getZoom();
484-
ElementAtZoom<ImageData> imageCandidate = ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, deviceZoom);
485-
ImageData data = scaleImageData(imageCandidate.element(), deviceZoom, imageCandidate.zoom());
486-
init(data, deviceZoom);
479+
this.imageProvider = new ImageDataLoaderStreamProviderWrapper(stream);
487480
init();
488481
this.device.registerResourceWithZoomSupport(this);
489482
}
@@ -524,10 +517,7 @@ public Image (Device device, String filename) {
524517
super(device);
525518
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
526519
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
527-
int deviceZoom = getZoom();
528-
ElementAtZoom<ImageData> imageCandidate = ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, deviceZoom);
529-
ImageData data = scaleImageData(imageCandidate.element(), deviceZoom, imageCandidate.zoom());
530-
init(data, deviceZoom);
520+
this.imageProvider = new ImageDataLoaderFileProviderWrapper(filename);
531521
init();
532522
this.device.registerResourceWithZoomSupport(this);
533523
}
@@ -1947,6 +1937,156 @@ protected void destroy() {
19471937
}
19481938
}
19491939

1940+
private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
1941+
1942+
protected abstract ElementAtZoom<ImageData> loadImageData(int zoom);
1943+
1944+
void initImage() {
1945+
// As the init call configured some Image attributes (e.g. type)
1946+
// it must be called
1947+
ImageData imageDataAt100 = getImageData(100);
1948+
init(imageDataAt100, 100);
1949+
destroyHandleForZoom(100);
1950+
}
1951+
1952+
@Override
1953+
ImageData getImageData(int zoom) {
1954+
if (zoomLevelToImageHandle.containsKey(zoom)) {
1955+
return zoomLevelToImageHandle.get(zoom).getImageData();
1956+
}
1957+
if (!zoomLevelToImageHandle.isEmpty()) {
1958+
return getScaledImageData(zoom);
1959+
}
1960+
ElementAtZoom<ImageData> loadedImageData = loadImageData(zoom);
1961+
return DPIUtil.scaleImageData(device, loadedImageData, zoom);
1962+
}
1963+
1964+
@Override
1965+
ImageHandle getImageMetadata(int zoom) {
1966+
if (zoomLevelToImageHandle.containsKey(zoom)) {
1967+
return zoomLevelToImageHandle.get(zoom);
1968+
} else {
1969+
ImageData scaledImageData = getImageData(zoom);
1970+
ImageHandle imageHandle = init(scaledImageData, zoom);
1971+
return imageHandle;
1972+
}
1973+
}
1974+
}
1975+
1976+
private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1977+
private ImageData imageDataAt100;
1978+
1979+
PlainImageDataProviderWrapper(ImageData imageData) {
1980+
this.imageDataAt100 = (ImageData) imageData.clone();
1981+
initImage();
1982+
}
1983+
1984+
@Override
1985+
protected Rectangle getBounds(int zoom) {
1986+
Rectangle rectangle = new Rectangle(0, 0, imageDataAt100.width, imageDataAt100.height);
1987+
return DPIUtil.scaleUp(rectangle, zoom);
1988+
}
1989+
1990+
@Override
1991+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
1992+
return new ElementAtZoom<>(imageDataAt100, 100);
1993+
}
1994+
1995+
@Override
1996+
AbstractImageProviderWrapper createCopy(Image image) {
1997+
return image.new PlainImageDataProviderWrapper(this.imageDataAt100);
1998+
}
1999+
}
2000+
2001+
private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
2002+
private final ImageData srcAt100;
2003+
private final ImageData maskAt100;
2004+
2005+
MaskedImageDataProviderWrapper(ImageData srcAt100, ImageData maskAt100) {
2006+
this.srcAt100 = (ImageData) srcAt100.clone();
2007+
this.maskAt100 = (ImageData) maskAt100.clone();
2008+
initImage();
2009+
}
2010+
2011+
@Override
2012+
protected Rectangle getBounds(int zoom) {
2013+
Rectangle rectangle = new Rectangle(0, 0, srcAt100.width, srcAt100.height);
2014+
return DPIUtil.scaleUp(rectangle, zoom);
2015+
}
2016+
2017+
@Override
2018+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2019+
ImageData scaledSource = DPIUtil.scaleImageData(device, srcAt100, zoom, 100);
2020+
ImageData scaledMask = DPIUtil.scaleImageData(device, maskAt100, zoom, 100);
2021+
scaledMask = ImageData.convertMask(scaledMask);
2022+
ImageData mergedData = applyMask(scaledSource, scaledMask);
2023+
return new ElementAtZoom<>(mergedData, zoom);
2024+
}
2025+
2026+
@Override
2027+
AbstractImageProviderWrapper createCopy(Image image) {
2028+
return image.new MaskedImageDataProviderWrapper(this.srcAt100, this.maskAt100);
2029+
}
2030+
}
2031+
2032+
private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper {
2033+
private byte[] inputStreamData;
2034+
2035+
ImageDataLoaderStreamProviderWrapper(InputStream inputStream) {
2036+
try {
2037+
this.inputStreamData = inputStream.readAllBytes();
2038+
initImage();
2039+
} catch (IOException e) {
2040+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, e);
2041+
}
2042+
}
2043+
2044+
private ImageDataLoaderStreamProviderWrapper(byte[] inputStreamData) {
2045+
this.inputStreamData = inputStreamData;
2046+
}
2047+
2048+
@Override
2049+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2050+
return ImageDataLoader.load(new ByteArrayInputStream(inputStreamData), FileFormat.DEFAULT_ZOOM, zoom);
2051+
}
2052+
2053+
@Override
2054+
protected Rectangle getBounds(int zoom) {
2055+
ImageData scaledImageData = getImageData(zoom);
2056+
return new Rectangle(0, 0, scaledImageData.width, scaledImageData.height);
2057+
}
2058+
2059+
@Override
2060+
AbstractImageProviderWrapper createCopy(Image image) {
2061+
return new ImageDataLoaderStreamProviderWrapper(inputStreamData);
2062+
}
2063+
}
2064+
2065+
private class ImageDataLoaderFileProviderWrapper extends ImageFromImageDataProviderWrapper {
2066+
private String fileName;
2067+
2068+
ImageDataLoaderFileProviderWrapper(String fileName) {
2069+
this.fileName = fileName;
2070+
initImage();
2071+
}
2072+
2073+
@Override
2074+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2075+
return ImageDataLoader.load(fileName, FileFormat.DEFAULT_ZOOM, zoom);
2076+
}
2077+
2078+
@Override
2079+
protected Rectangle getBounds(int zoom) {
2080+
ImageData scaledImageData = getImageData(zoom);
2081+
return new Rectangle(0, 0, scaledImageData.width, scaledImageData.height);
2082+
}
2083+
2084+
@Override
2085+
AbstractImageProviderWrapper createCopy(Image image) {
2086+
return new ImageDataLoaderFileProviderWrapper(fileName);
2087+
}
2088+
}
2089+
19502090
private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
19512091
private final int width;
19522092
private final int height;

0 commit comments

Comments
 (0)