From b2c3a8447c7fed4e674f6794e788aa8ff273620f Mon Sep 17 00:00:00 2001 From: Andreas Koch Date: Tue, 6 May 2025 12:27:36 +0200 Subject: [PATCH] [win32] Utilize temporary image handles This commit adapts all places, where operation where executed with OS handles created for a specific zoom that could use any zoom. Therefor now any existing handle is used or, if none exists yet, a temporary handle is created and destroyed afterwards. --- .../win32/org/eclipse/swt/graphics/Image.java | 96 +++++++++++-------- 1 file changed, 55 insertions(+), 41 deletions(-) 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 90714c8dc80..7263a283a15 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 @@ -1099,47 +1099,49 @@ public Color getBackground() { /* Get the HDC for the device */ long hDC = device.internal_new_GC(null); - long handle = win32_getHandle(this, getZoom()); - - /* Compute the background color */ - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - long hdcMem = OS.CreateCompatibleDC(hDC); - long hOldObject = OS.SelectObject(hdcMem, handle); - int red = 0, green = 0, blue = 0; - if (bm.bmBitsPixel <= 8) { - byte[] color = new byte[4]; - OS.GetDIBColorTable(hdcMem, transparentPixel, 1, color); - blue = color[0] & 0xFF; - green = color[1] & 0xFF; - red = color[2] & 0xFF; - } else { - switch (bm.bmBitsPixel) { - case 16: - blue = (transparentPixel & 0x1F) << 3; - green = (transparentPixel & 0x3E0) >> 2; - red = (transparentPixel & 0x7C00) >> 7; - break; - case 24: - blue = (transparentPixel & 0xFF0000) >> 16; - green = (transparentPixel & 0xFF00) >> 8; - red = transparentPixel & 0xFF; - break; - case 32: - blue = (transparentPixel & 0xFF000000) >>> 24; - green = (transparentPixel & 0xFF0000) >> 16; - red = (transparentPixel & 0xFF00) >> 8; - break; - default: - return null; + return applyUsingAnyHandle(imageHandle -> { + long handle = imageHandle.handle; + /* Compute the background color */ + BITMAP bm = new BITMAP(); + OS.GetObject(handle, BITMAP.sizeof, bm); + long hdcMem = OS.CreateCompatibleDC(hDC); + long hOldObject = OS.SelectObject(hdcMem, handle); + int red = 0, green = 0, blue = 0; + if (bm.bmBitsPixel <= 8) { + byte[] color = new byte[4]; + OS.GetDIBColorTable(hdcMem, transparentPixel, 1, color); + blue = color[0] & 0xFF; + green = color[1] & 0xFF; + red = color[2] & 0xFF; + } else { + switch (bm.bmBitsPixel) { + case 16: + blue = (transparentPixel & 0x1F) << 3; + green = (transparentPixel & 0x3E0) >> 2; + red = (transparentPixel & 0x7C00) >> 7; + break; + case 24: + blue = (transparentPixel & 0xFF0000) >> 16; + green = (transparentPixel & 0xFF00) >> 8; + red = transparentPixel & 0xFF; + break; + case 32: + blue = (transparentPixel & 0xFF000000) >>> 24; + green = (transparentPixel & 0xFF0000) >> 16; + red = (transparentPixel & 0xFF00) >> 8; + break; + default: + return null; + } } - } - OS.SelectObject(hdcMem, hOldObject); - OS.DeleteDC(hdcMem); + OS.SelectObject(hdcMem, hOldObject); + OS.DeleteDC(hdcMem); - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - return Color.win32_new(device, (blue << 16) | (green << 8) | red); + + /* Release the HDC for the device */ + device.internal_dispose_GC(hDC, null); + return Color.win32_new(device, (blue << 16) | (green << 8) | red); + }); } /** @@ -1186,7 +1188,7 @@ Rectangle getBounds(int zoom) { */ @Deprecated public Rectangle getBoundsInPixels() { - return getBounds(getZoom()); + return applyUsingAnyHandle(ImageHandle::getBounds); } /** @@ -1268,7 +1270,7 @@ public ImageData getImageData (int zoom) { */ @Deprecated public ImageData getImageDataAtCurrentZoom() { - return getImageMetadata(getZoom()).getImageData(); + return applyUsingAnyHandle(ImageHandle::getImageData); } /** @@ -1842,6 +1844,18 @@ public String toString () { return "Image {" + zoomLevelToImageHandle + "}"; } + T applyUsingAnyHandle(Function function) { + if (zoomLevelToImageHandle.isEmpty()) { + ImageHandle temporaryHandle = this.imageProvider.newImageHandle(DPIUtil.getDeviceZoom()); + try { + return function.apply(temporaryHandle); + } finally { + temporaryHandle.destroy(); + } + } + return function.apply(zoomLevelToImageHandle.values().iterator().next()); +} + /** * Invokes platform specific functionality to allocate a new image. *