Skip to content

Commit 044cb7c

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 e941580 commit 044cb7c

File tree

1 file changed

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

1 file changed

+177
-13
lines changed

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

+177-13
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,7 @@ public Image(Device device, ImageData data) {
366366
super(device);
367367
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
368368
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
369-
int deviceZoom = getZoom();
370-
data = DPIUtil.scaleImageData(device, new ElementAtZoom<>(data, 100), deviceZoom);
371-
init(data, deviceZoom);
369+
this.imageProvider = new PlainImageDataProviderWrapper(data);
372370
init();
373371
this.device.registerResourceWithZoomSupport(this);
374372
}
@@ -411,10 +409,7 @@ public Image(Device device, ImageData source, ImageData mask) {
411409
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
412410
}
413411
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
414-
source = DPIUtil.autoScaleUp(device, source);
415-
mask = DPIUtil.autoScaleUp(device, mask);
416-
mask = ImageData.convertMask(mask);
417-
initIconHandle(this.device, source, mask, getZoom());
412+
this.imageProvider = new MaskedImageDataProviderWrapper(source, mask);
418413
init();
419414
this.device.registerResourceWithZoomSupport(this);
420415
}
@@ -474,10 +469,12 @@ public Image(Device device, ImageData source, ImageData mask) {
474469
*/
475470
public Image (Device device, InputStream stream) {
476471
super(device);
472+
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
477473
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
478-
int deviceZoom = getZoom();
479-
ImageData data = DPIUtil.scaleImageData(device, ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, deviceZoom), deviceZoom);
480-
init(data, deviceZoom);
474+
this.imageProvider = new ImageDataLoaderStreamProviderWrapper(stream);
475+
if (this.imageProvider.getImageData(100) == null) {
476+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": InputStream returns null ImageData at 100% zoom.");
477+
}
481478
init();
482479
this.device.registerResourceWithZoomSupport(this);
483480
}
@@ -518,9 +515,10 @@ public Image (Device device, String filename) {
518515
super(device);
519516
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
520517
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
521-
int deviceZoom = getZoom();
522-
ImageData data = DPIUtil.scaleImageData(device, ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, deviceZoom), deviceZoom);
523-
init(data, deviceZoom);
518+
this.imageProvider = new ImageDataLoaderFileProviderWrapper(filename);
519+
if (this.imageProvider.getImageData(100) == null) {
520+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ": Input filename returns null ImageData at 100% zoom.");
521+
}
524522
init();
525523
this.device.registerResourceWithZoomSupport(this);
526524
}
@@ -626,6 +624,14 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height)
626624
init();
627625
}
628626

627+
@Override
628+
void init() {
629+
super.init();
630+
if (this.imageProvider != null) {
631+
this.imageProvider.initImage();
632+
}
633+
}
634+
629635
private ImageData adaptImageDataIfDisabledOrGray(ImageData data) {
630636
ImageData returnImageData = null;
631637
switch (this.styleFlag) {
@@ -1885,10 +1891,168 @@ private abstract class AbstractImageProviderWrapper {
18851891
abstract AbstractImageProviderWrapper createCopy(Image image);
18861892
abstract boolean isDisposed();
18871893

1894+
protected void initImage() {
1895+
}
1896+
18881897
protected void destroy() {
18891898
}
18901899
}
18911900

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

0 commit comments

Comments
 (0)