Skip to content

Commit ad0aa6b

Browse files
akoch-yattaHeikoKlare
authored andcommitted
[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 6517c9e commit ad0aa6b

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

+65-17
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public final class Image extends Resource implements Drawable {
111111
/**
112112
* AbstractImageProvider to avail right ImageProvider (ImageDataProvider or ImageFileNameProvider)
113113
*/
114-
private AbstractImageProviderWrapper imageProvider;
114+
private final AbstractImageProviderWrapper imageProvider;
115115

116116
/**
117117
* Style flag used to differentiate normal, gray-scale and disabled images based
@@ -138,16 +138,13 @@ public final class Image extends Resource implements Drawable {
138138

139139
private Map<Integer, ImageHandle> zoomLevelToImageHandle = new HashMap<>();
140140

141-
/**
142-
* Prevents uninitialized instances from being created outside the package.
143-
*/
144-
Image (Device device) {
145-
this(device, DPIUtil.getNativeDeviceZoom());
146-
}
147-
148-
private Image (Device device, int nativeZoom) {
141+
private Image (Device device, int type, long handle, int nativeZoom) {
149142
super(device);
150143
initialNativeZoom = nativeZoom;
144+
this.type = type;
145+
this.imageProvider = new ExistingImageHandleProviderWrapper(handle, nativeZoom);
146+
this.isInitialized = true;
147+
this.device.registerResourceWithZoomSupport(this);
151148
}
152149

153150
/**
@@ -243,9 +240,7 @@ public Image(Device device, Image srcImage, int flag) {
243240
initialNativeZoom = srcImage.initialNativeZoom;
244241
Rectangle rect = srcImage.getBounds(getZoom());
245242
this.type = srcImage.type;
246-
if(srcImage.imageProvider != null) {
247-
this.imageProvider = srcImage.imageProvider.createCopy(this);
248-
}
243+
this.imageProvider = srcImage.imageProvider.createCopy(this);
249244
this.styleFlag = srcImage.styleFlag | flag;
250245
long srcImageHandle = win32_getHandle(srcImage, getZoom());
251246
switch (flag) {
@@ -1916,11 +1911,7 @@ public String toString () {
19161911
* @noreference This method is not intended to be referenced by clients.
19171912
*/
19181913
public static Image win32_new(Device device, int type, long handle, int nativeZoom) {
1919-
Image image = new Image(device, nativeZoom);
1920-
image.type = type;
1921-
image.new ImageHandle(handle, nativeZoom);
1922-
image.device.registerResourceWithZoomSupport(image);
1923-
return image;
1914+
return new Image(device, type, handle, nativeZoom);
19241915
}
19251916

19261917
private abstract class AbstractImageProviderWrapper {
@@ -1940,6 +1931,63 @@ protected void destroy() {
19401931
}
19411932
}
19421933

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

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

0 commit comments

Comments
 (0)