Skip to content

Commit 0e4765d

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 0e4765d

File tree

1 file changed

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

1 file changed

+135
-15
lines changed

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

+135-15
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,12 @@ 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 ImageFileNameProviderWrapper(zoom -> {
521+
if (zoom == 100) {
522+
return filename;
523+
}
524+
return null;
525+
});
531526
init();
532527
this.device.registerResourceWithZoomSupport(this);
533528
}
@@ -1947,6 +1942,131 @@ protected void destroy() {
19471942
}
19481943
}
19491944

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

0 commit comments

Comments
 (0)