Skip to content

Commit 3dad941

Browse files
committed
[win32] Wrapper for existing image handles
This commit adds a wrapper for images created with an existing OS handle to ensure all existing image constructors are tied to a final wrapper instance.
1 parent 7cc858e commit 3dad941

File tree

1 file changed

+65
-17
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+65
-17
lines changed

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

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public final class Image extends Resource implements Drawable {
109109
/**
110110
* AbstractImageProvider to avail right ImageProvider (ImageDataProvider or ImageFileNameProvider)
111111
*/
112-
private AbstractImageProviderWrapper imageProvider;
112+
private final AbstractImageProviderWrapper imageProvider;
113113

114114
/**
115115
* Style flag used to differentiate normal, gray-scale and disabled images based
@@ -136,16 +136,13 @@ public final class Image extends Resource implements Drawable {
136136

137137
private Map<Integer, ImageHandle> zoomLevelToImageHandle = new HashMap<>();
138138

139-
/**
140-
* Prevents uninitialized instances from being created outside the package.
141-
*/
142-
Image (Device device) {
143-
this(device, DPIUtil.getNativeDeviceZoom());
144-
}
145-
146-
private Image (Device device, int nativeZoom) {
139+
private Image (Device device, int type, long handle, int nativeZoom) {
147140
super(device);
148141
initialNativeZoom = nativeZoom;
142+
this.type = type;
143+
this.imageProvider = new ExistingImageHandleProviderWrapper(handle, nativeZoom);
144+
this.isInitialized = true;
145+
this.device.registerResourceWithZoomSupport(this);
149146
}
150147

151148
/**
@@ -241,9 +238,7 @@ public Image(Device device, Image srcImage, int flag) {
241238
initialNativeZoom = srcImage.initialNativeZoom;
242239
Rectangle rect = srcImage.getBounds(getZoom());
243240
this.type = srcImage.type;
244-
if(srcImage.imageProvider != null) {
245-
this.imageProvider = srcImage.imageProvider.createCopy(this);
246-
}
241+
this.imageProvider = srcImage.imageProvider.createCopy(this);
247242
this.styleFlag = srcImage.styleFlag | flag;
248243
long srcImageHandle = win32_getHandle(srcImage, getZoom());
249244
switch (flag) {
@@ -1923,11 +1918,7 @@ public String toString () {
19231918
* @noreference This method is not intended to be referenced by clients.
19241919
*/
19251920
public static Image win32_new(Device device, int type, long handle, int nativeZoom) {
1926-
Image image = new Image(device, nativeZoom);
1927-
image.type = type;
1928-
image.new ImageHandle(handle, nativeZoom);
1929-
image.device.registerResourceWithZoomSupport(image);
1930-
return image;
1921+
return new Image(device, type, handle, nativeZoom);
19311922
}
19321923

19331924
private abstract class AbstractImageProviderWrapper {
@@ -1947,6 +1938,63 @@ protected void destroy() {
19471938
}
19481939
}
19491940

1941+
private class ExistingImageHandleProviderWrapper extends AbstractImageProviderWrapper {
1942+
1943+
private final int width;
1944+
private final int height;
1945+
private final long handle;
1946+
private final int zoomForHandle;
1947+
1948+
public ExistingImageHandleProviderWrapper(long handle, int zoomForHandle) {
1949+
this.handle = handle;
1950+
this.zoomForHandle = zoomForHandle;
1951+
ImageHandle imageHandle = new ImageHandle(handle, zoomForHandle);
1952+
1953+
ImageData baseData = imageHandle.getImageData();
1954+
this.width = DPIUtil.scaleDown(baseData.width, zoomForHandle);
1955+
this.height = DPIUtil.scaleDown(baseData.height, zoomForHandle);
1956+
}
1957+
1958+
@Override
1959+
protected Rectangle getBounds(int zoom) {
1960+
Rectangle rectangle = new Rectangle(0, 0, width, height);
1961+
return DPIUtil.scaleUp(rectangle, zoom);
1962+
}
1963+
1964+
@Override
1965+
ImageData getImageData(int zoom) {
1966+
if (zoomLevelToImageHandle.isEmpty() || zoomLevelToImageHandle.containsKey(zoom)) {
1967+
return getImageMetadata(zoom).getImageData();
1968+
}
1969+
1970+
return getScaledImageData(zoom);
1971+
}
1972+
1973+
@Override
1974+
ImageHandle getImageMetadata(int zoom) {
1975+
if (zoomLevelToImageHandle.containsKey(zoom)) {
1976+
return zoomLevelToImageHandle.get(zoom);
1977+
} else {
1978+
ImageData resizedData = getImageData(zoom);
1979+
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
1980+
if (type == SWT.ICON && newData.getTransparencyType() != SWT.TRANSPARENCY_MASK) {
1981+
// If the original type was an icon with transparency mask and re-scaling leads
1982+
// to image data without transparency mask, this will create invalid images
1983+
// so this fallback will "repair" the image data by explicitly passing
1984+
// the transparency mask created from the scaled image data
1985+
return initIconHandle(device, newData, newData.getTransparencyMask(), zoom);
1986+
} else {
1987+
return init(newData, zoom);
1988+
}
1989+
}
1990+
}
1991+
1992+
@Override
1993+
AbstractImageProviderWrapper createCopy(Image image) {
1994+
return image.new ExistingImageHandleProviderWrapper(handle, zoomForHandle);
1995+
}
1996+
}
1997+
19501998
private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
19511999

19522000
protected abstract ElementAtZoom<ImageData> loadImageData(int zoom);

0 commit comments

Comments
 (0)