diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index d3b23074009..7eaaaa9d36b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -780,23 +780,7 @@ private ImageHandle getImageMetadata(int zoom) { if (zoomLevelToImageHandle.get(zoom) != null) { return zoomLevelToImageHandle.get(zoom); } - if (imageProvider != null) { - return imageProvider.getImageMetadata(zoom); - } else { - ImageData resizedData = getImageData(zoom); - ImageData newData = adaptImageDataIfDisabledOrGray(resizedData); - if (type == SWT.ICON && newData.getTransparencyType() != SWT.TRANSPARENCY_MASK) { - // If the original type was an icon with transparency mask and re-scaling leads - // to image data without transparency mask, this will create invalid images - // so this fallback will "repair" the image data by explicitly passing - // the transparency mask created from the scaled image data - initIconHandle(this.device, newData, newData.getTransparencyMask(), zoom); - } else { - init(newData, zoom); - } - init(); - } - return zoomLevelToImageHandle.get(zoom); + return imageProvider.newImageHandle(zoom); } @@ -999,9 +983,7 @@ public static long win32_getHandle (Image image, int zoom) { void destroy () { device.deregisterResourceWithZoomSupport(this); if (memGC != null) memGC.dispose(); - if (this.imageProvider != null) { - this.imageProvider.destroy(); - } + this.imageProvider.destroy(); destroyHandle(); memGC = null; } @@ -1055,11 +1037,7 @@ public boolean equals (Object object) { if (!(object instanceof Image)) return false; Image image = (Image) object; if (device != image.device || transparentPixel != image.transparentPixel || getZoom() != image.getZoom()) return false; - if (imageProvider != null && image.imageProvider != null) { - return (styleFlag == image.styleFlag) && imageProvider.equals(image.imageProvider); - } else { - return win32_getHandle(this, getZoom()) == win32_getHandle(image, getZoom()); - } + return (styleFlag == image.styleFlag) && imageProvider.equals(image.imageProvider); } /** @@ -1156,13 +1134,8 @@ Rectangle getBounds(int zoom) { ImageHandle imageMetadata = zoomLevelToImageHandle.get(zoom); Rectangle rectangle = new Rectangle(0, 0, imageMetadata.width, imageMetadata.height); return DPIUtil.scaleBounds(rectangle, zoom, imageMetadata.zoom); - } else if (this.imageProvider != null) { - return this.imageProvider.getBounds(zoom); - } else { - ImageHandle imageMetadata = zoomLevelToImageHandle.values().iterator().next(); - Rectangle rectangle = new Rectangle(0, 0, imageMetadata.width, imageMetadata.height); - return DPIUtil.scaleBounds(rectangle, zoom, imageMetadata.zoom); } + return this.imageProvider.getBounds(zoom); } /** @@ -1236,25 +1209,7 @@ public ImageData getImageData() { */ public ImageData getImageData (int zoom) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (zoomLevelToImageHandle.containsKey(zoom)) { - return zoomLevelToImageHandle.get(zoom).getImageData(); - } - if (imageProvider != null) { - return imageProvider.getImageData(zoom); - } - - return getScaledImageData(zoom); -} - -private ImageData getScaledImageData (int zoom) { - // if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would - // be a destructive operation. Therefor, always the current image data must be returned - if (memGC != null) { - return getImageDataAtCurrentZoom(); - } - TreeSet availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet()); - int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom)); - return scaleImageData(getImageMetadata(closestZoom).getImageData(), zoom, closestZoom); + return imageProvider.getImageData(zoom); } @@ -1294,10 +1249,7 @@ public ImageData getImageDataAtCurrentZoom() { */ @Override public int hashCode () { - if(imageProvider != null) { - return imageProvider.hashCode(); - } - return (int)win32_getHandle(this, getZoom()); + return imageProvider.hashCode(); } static long createDIB(int width, int height, int depth) { @@ -1794,10 +1746,7 @@ public void internal_dispose_GC (long hDC, GCData data) { */ @Override public boolean isDisposed() { - if (this.imageProvider != null) { - return this.imageProvider.isDisposed(); - } - return zoomLevelToImageHandle.isEmpty(); + return this.imageProvider.isDisposed(); } /** @@ -1918,10 +1867,42 @@ private abstract class AbstractImageProviderWrapper { private boolean isDestroyed; protected abstract Rectangle getBounds(int zoom); - abstract ImageData getImageData(int zoom); - abstract ImageHandle getImageMetadata(int zoom); + + protected final ImageData getImageData(int zoom) { + if (zoomLevelToImageHandle.containsKey(zoom)) { + return zoomLevelToImageHandle.get(zoom).getImageData(); + } + return newImageData(zoom); + } + + abstract ImageData newImageData(int zoom); + abstract AbstractImageProviderWrapper createCopy(Image image); + ImageData getScaledImageData (int zoom) { + // if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would + // be a destructive operation. Therefor, always the current image data must be returned + if (memGC != null) { + return getImageDataAtCurrentZoom(); + } + TreeSet availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet()); + int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom)); + return scaleImageData(getImageMetadata(closestZoom).getImageData(), zoom, closestZoom); + } + + protected ImageHandle newImageHandle(int zoom) { + ImageData resizedData = getImageData(zoom); + if (type == SWT.ICON && resizedData.getTransparencyType() != SWT.TRANSPARENCY_MASK) { + // If the original type was an icon with transparency mask and re-scaling leads + // to image data without transparency mask, this will create invalid images + // so this fallback will "repair" the image data by explicitly passing + // the transparency mask created from the scaled image data + return initIconHandle(device, resizedData, resizedData.getTransparencyMask(), zoom); + } else { + return init(resizedData, zoom); + } + } + protected boolean isDisposed() { return !isInitialized || isDestroyed; } @@ -1955,33 +1936,10 @@ protected Rectangle getBounds(int zoom) { } @Override - ImageData getImageData(int zoom) { - if (zoomLevelToImageHandle.isEmpty() || zoomLevelToImageHandle.containsKey(zoom)) { - return getImageMetadata(zoom).getImageData(); - } - + ImageData newImageData(int zoom) { return getScaledImageData(zoom); } - @Override - ImageHandle getImageMetadata(int zoom) { - if (zoomLevelToImageHandle.containsKey(zoom)) { - return zoomLevelToImageHandle.get(zoom); - } else { - ImageData resizedData = getImageData(zoom); - ImageData newData = adaptImageDataIfDisabledOrGray(resizedData); - if (type == SWT.ICON && newData.getTransparencyType() != SWT.TRANSPARENCY_MASK) { - // If the original type was an icon with transparency mask and re-scaling leads - // to image data without transparency mask, this will create invalid images - // so this fallback will "repair" the image data by explicitly passing - // the transparency mask created from the scaled image data - return initIconHandle(device, newData, newData.getTransparencyMask(), zoom); - } else { - return init(newData, zoom); - } - } - } - @Override AbstractImageProviderWrapper createCopy(Image image) { return image.new ExistingImageHandleProviderWrapper(handle, zoomForHandle); @@ -2001,26 +1959,13 @@ void initImage() { } @Override - ImageData getImageData(int zoom) { - if (zoomLevelToImageHandle.containsKey(zoom)) { - return zoomLevelToImageHandle.get(zoom).getImageData(); - } + ImageData newImageData(int zoom) { if (!zoomLevelToImageHandle.isEmpty()) { return getScaledImageData(zoom); } ElementAtZoom loadedImageData = loadImageData(zoom); - return DPIUtil.scaleImageData(device, loadedImageData, zoom); - } - - @Override - ImageHandle getImageMetadata(int zoom) { - if (zoomLevelToImageHandle.containsKey(zoom)) { - return zoomLevelToImageHandle.get(zoom); - } else { - ImageData scaledImageData = getImageData(zoom); - ImageHandle imageHandle = init(scaledImageData, zoom); - return imageHandle; - } + ImageData scaledImageData = DPIUtil.scaleImageData(device, loadedImageData, zoom); + return adaptImageDataIfDisabledOrGray(scaledImageData); } } @@ -2133,29 +2078,26 @@ protected Rectangle getBounds(int zoom) { } @Override - ImageData getImageData(int zoom) { - if (zoomLevelToImageHandle.isEmpty() || zoomLevelToImageHandle.containsKey(zoom)) { - return getImageMetadata(zoom).getImageData(); + ImageData newImageData(int zoom) { + if (zoomLevelToImageHandle.isEmpty()) { + return createBaseHandle(zoom).getImageData(); } - return getScaledImageData(zoom); } @Override - ImageHandle getImageMetadata(int zoom) { + protected ImageHandle newImageHandle(int zoom) { if (zoomLevelToImageHandle.isEmpty()) { - long handle = initBaseHandle(zoom); - ImageHandle imageHandle = new ImageHandle(handle, zoom); - zoomLevelToImageHandle.put(zoom, imageHandle); - return imageHandle; - } else if(zoomLevelToImageHandle.containsKey(zoom)) { - return zoomLevelToImageHandle.get(zoom); - } else { - ImageData resizedData = getImageData(zoom); - ImageData newData = adaptImageDataIfDisabledOrGray(resizedData); - init(newData, zoom); - return zoomLevelToImageHandle.get(zoom); + return createBaseHandle(zoom); } + return super.newImageHandle(zoom); + } + + private ImageHandle createBaseHandle(int zoom) { + long handle = initBaseHandle(zoom); + ImageHandle imageHandle = new ImageHandle(handle, zoom); + zoomLevelToImageHandle.put(zoom, imageHandle); + return imageHandle; } private long initBaseHandle(int zoom) { @@ -2233,7 +2175,7 @@ Object getProvider() { } @Override - final ImageData getImageData(int zoom) { + ImageData newImageData(int zoom) { Function imageDataRetrival = zoomToRetrieve -> { ImageHandle handle = initializeHandleFromSource(zoomToRetrieve); ImageData data = handle.getImageData(); @@ -2243,8 +2185,9 @@ final ImageData getImageData(int zoom) { return cachedImageData.computeIfAbsent(zoom, imageDataRetrival); } + @Override - final ImageHandle getImageMetadata(int zoom) { + protected ImageHandle newImageHandle(int zoom) { ImageData cachedData = cachedImageData.remove(zoom); if (cachedData != null) { return init(cachedData, zoom); @@ -2280,7 +2223,7 @@ protected ElementAtZoom loadImageData(int zoom) { // Load at appropriate zoom via loader if (fileForZoom.zoom() != zoom && ImageDataLoader.canLoadAtZoom(fileForZoom.element(), fileForZoom.zoom(), zoom)) { ElementAtZoom imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom); - return new ElementAtZoom<>(adaptImageDataIfDisabledOrGray(imageDataAtZoom.element()), zoom); + return new ElementAtZoom<>(imageDataAtZoom.element(), zoom); } // Load at file zoom (native or via loader) and rescale @@ -2539,12 +2482,12 @@ protected Rectangle getBounds(int zoom) { } @Override - ImageData getImageData(int zoom) { + ImageData newImageData(int zoom) { return getImageMetadata(zoom).getImageData(); } @Override - ImageHandle getImageMetadata(int zoom) { + protected ImageHandle newImageHandle(int zoom) { initialNativeZoom = zoom; Image image = new Image(device, width, height, zoom); GC gc = new GC(image, drawer.getGcStyle()); @@ -2554,12 +2497,11 @@ ImageHandle getImageMetadata(int zoom) { ImageData imageData = image.getImageMetadata(zoom).getImageData(); drawer.postProcess(imageData); ImageData newData = adaptImageDataIfDisabledOrGray(imageData); - init(newData, zoom); + return init(newData, zoom); } finally { gc.dispose(); image.dispose(); } - return zoomLevelToImageHandle.get(zoom); } @Override