Skip to content

Commit 4e1b5df

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 0768d7e commit 4e1b5df

File tree

1 file changed

+151
-13
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+151
-13
lines changed

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

Lines changed: 151 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,7 @@ public Image(Device device, ImageData data) {
360360
super(device);
361361
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
362362
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
363-
int deviceZoom = getZoom();
364-
data = DPIUtil.scaleImageData(device, new ElementAtZoom<>(data, 100), deviceZoom);
365-
init(data, deviceZoom);
363+
this.imageProvider = new PlainImageDataProviderWrapper(data);
366364
init();
367365
this.device.registerResourceWithZoomSupport(this);
368366
}
@@ -405,10 +403,7 @@ public Image(Device device, ImageData source, ImageData mask) {
405403
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
406404
}
407405
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
408-
source = DPIUtil.autoScaleUp(device, source);
409-
mask = DPIUtil.autoScaleUp(device, mask);
410-
mask = ImageData.convertMask(mask);
411-
initIconHandle(this.device, source, mask, getZoom());
406+
this.imageProvider = new MaskedImageDataProviderWrapper(source, mask);
412407
init();
413408
this.device.registerResourceWithZoomSupport(this);
414409
}
@@ -468,10 +463,12 @@ public Image(Device device, ImageData source, ImageData mask) {
468463
*/
469464
public Image (Device device, InputStream stream) {
470465
super(device);
466+
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
471467
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
472-
int deviceZoom = getZoom();
473-
ImageData data = DPIUtil.scaleImageData(device, ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, deviceZoom), deviceZoom);
474-
init(data, deviceZoom);
468+
this.imageProvider = new ImageDataLoaderStreamProviderWrapper(stream);
469+
if (this.imageProvider.getImageData(100) == null) {
470+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": InputStream returns null ImageData at 100% zoom.");
471+
}
475472
init();
476473
this.device.registerResourceWithZoomSupport(this);
477474
}
@@ -512,9 +509,10 @@ public Image (Device device, String filename) {
512509
super(device);
513510
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
514511
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
515-
int deviceZoom = getZoom();
516-
ImageData data = DPIUtil.scaleImageData(device, ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, deviceZoom), deviceZoom);
517-
init(data, deviceZoom);
512+
this.imageProvider = new ImageDataLoaderFileProviderWrapper(filename);
513+
if (this.imageProvider.getImageData(100) == null) {
514+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": Input filename returns null ImageData at 100% zoom.");
515+
}
518516
init();
519517
this.device.registerResourceWithZoomSupport(this);
520518
}
@@ -1901,6 +1899,146 @@ protected void destroy() {
19011899
}
19021900
}
19031901

1902+
private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
1903+
private boolean isDestroyed;
1904+
1905+
protected abstract ElementAtZoom<ImageData> loadImageData(int zoom);
1906+
1907+
@Override
1908+
ImageData getImageData(int zoom) {
1909+
if (zoomLevelToImageHandle.containsKey(zoom)) {
1910+
return zoomLevelToImageHandle.get(zoom).getImageData();
1911+
}
1912+
ElementAtZoom<ImageData> loadedImageData = loadImageData(zoom);
1913+
return DPIUtil.scaleImageData(device, loadedImageData, zoom);
1914+
}
1915+
1916+
@Override
1917+
ImageHandle getImageMetadata(int zoom) {
1918+
if (zoomLevelToImageHandle.containsKey(zoom)) {
1919+
return zoomLevelToImageHandle.get(zoom);
1920+
} else {
1921+
ImageData scaledImageData = getImageData(zoom);
1922+
ImageHandle imageHandle = init(scaledImageData, zoom);
1923+
return imageHandle;
1924+
}
1925+
}
1926+
1927+
@Override
1928+
protected void destroy() {
1929+
this.isDestroyed = true;
1930+
}
1931+
1932+
@Override
1933+
boolean isDisposed() {
1934+
return isDestroyed;
1935+
}
1936+
}
1937+
1938+
1939+
private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1940+
private final ImageData srcAt100;
1941+
private final ImageData maskAt100;
1942+
1943+
MaskedImageDataProviderWrapper(ImageData srcAt100, ImageData maskAt100) {
1944+
this.srcAt100 = (ImageData) srcAt100.clone();
1945+
this.maskAt100 = (ImageData) maskAt100.clone();
1946+
}
1947+
1948+
@Override
1949+
protected Rectangle getBounds(int zoom) {
1950+
Rectangle rectangle = new Rectangle(0, 0, srcAt100.width, srcAt100.height);
1951+
return DPIUtil.scaleUp(rectangle, zoom);
1952+
}
1953+
1954+
@Override
1955+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
1956+
ImageData scaledSource = DPIUtil.scaleImageData(device, srcAt100, zoom, 100);
1957+
ImageData mask = ImageData.convertMask(maskAt100);
1958+
ImageData scaledMask = DPIUtil.scaleImageData(device, mask, zoom, 100);
1959+
ImageData mergedData = applyMask(scaledSource, scaledMask);
1960+
return new ElementAtZoom<>(mergedData, zoom);
1961+
}
1962+
1963+
@Override
1964+
AbstractImageProviderWrapper createCopy(Image image) {
1965+
return image.new MaskedImageDataProviderWrapper(this.srcAt100, this.maskAt100);
1966+
}
1967+
}
1968+
1969+
1970+
private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1971+
private ImageData imageDataAt100;
1972+
1973+
PlainImageDataProviderWrapper(ImageData imageData) {
1974+
this.imageDataAt100 = (ImageData) imageData.clone();
1975+
}
1976+
1977+
@Override
1978+
protected Rectangle getBounds(int zoom) {
1979+
Rectangle rectangle = new Rectangle(0, 0, imageDataAt100.width, imageDataAt100.height);
1980+
return DPIUtil.scaleUp(rectangle, zoom);
1981+
}
1982+
1983+
@Override
1984+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
1985+
return new ElementAtZoom<>(imageDataAt100, 100);
1986+
}
1987+
1988+
@Override
1989+
AbstractImageProviderWrapper createCopy(Image image) {
1990+
return image.new PlainImageDataProviderWrapper(this.imageDataAt100);
1991+
}
1992+
}
1993+
1994+
private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper {
1995+
private InputStream inputStream;
1996+
1997+
ImageDataLoaderStreamProviderWrapper(InputStream inputStream) {
1998+
this.inputStream = inputStream;
1999+
}
2000+
2001+
@Override
2002+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2003+
return ImageDataLoader.load(inputStream, FileFormat.DEFAULT_ZOOM, zoom);
2004+
}
2005+
2006+
@Override
2007+
protected Rectangle getBounds(int zoom) {
2008+
ImageData scaledImageData = getImageData(zoom);
2009+
return new Rectangle(0, 0, scaledImageData.width, scaledImageData.height);
2010+
}
2011+
2012+
@Override
2013+
AbstractImageProviderWrapper createCopy(Image image) {
2014+
return new ImageDataLoaderStreamProviderWrapper(inputStream);
2015+
}
2016+
}
2017+
2018+
private class ImageDataLoaderFileProviderWrapper extends ImageFromImageDataProviderWrapper {
2019+
private String fileName;
2020+
2021+
ImageDataLoaderFileProviderWrapper(String fileName) {
2022+
this.fileName = fileName;
2023+
}
2024+
2025+
@Override
2026+
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2027+
return ImageDataLoader.load(fileName, FileFormat.DEFAULT_ZOOM, zoom);
2028+
}
2029+
2030+
@Override
2031+
protected Rectangle getBounds(int zoom) {
2032+
ImageData scaledImageData = getImageData(zoom);
2033+
return new Rectangle(0, 0, scaledImageData.width, scaledImageData.height);
2034+
}
2035+
2036+
@Override
2037+
AbstractImageProviderWrapper createCopy(Image image) {
2038+
return new ImageDataLoaderFileProviderWrapper(fileName);
2039+
}
2040+
}
2041+
19042042
private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
19052043
private boolean isDestroyed;
19062044
private final int width;

0 commit comments

Comments
 (0)