From 570f321f175a752e1069d20338bc3d835dab018e Mon Sep 17 00:00:00 2001 From: Andreas Koch Date: Tue, 6 May 2025 12:16:38 +0200 Subject: [PATCH] [win32] Adapt/copy all handles on Image copy This commit adapts and copies all handles in the copy constructor in Image. As each image now manages possibly more than one OS handles at the same time in the windows implementation, it is important to apply the operation on all of them. --- .../win32/org/eclipse/swt/graphics/Image.java | 76 +++++++++++-------- .../org/eclipse/swt/snippets/Snippet382.java | 67 ++++++++++------ 2 files changed, 87 insertions(+), 56 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 f2b96c560b1..90714c8dc80 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 @@ -244,41 +244,45 @@ public Image(Device device, Image srcImage, int flag) { if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); initialNativeZoom = srcImage.initialNativeZoom; - Rectangle rect = srcImage.getBounds(getZoom()); this.type = srcImage.type; this.imageProvider = srcImage.imageProvider.createCopy(this); this.styleFlag = srcImage.styleFlag | flag; - long srcImageHandle = win32_getHandle(srcImage, getZoom()); switch (flag) { case SWT.IMAGE_COPY: { switch (type) { case SWT.BITMAP: - /* Get the HDC for the device */ - long hDC = device.internal_new_GC(null); - - /* Copy the bitmap */ - long hdcSource = OS.CreateCompatibleDC(hDC); - long hdcDest = OS.CreateCompatibleDC(hDC); - long hOldSrc = OS.SelectObject(hdcSource, srcImageHandle); - BITMAP bm = new BITMAP(); - OS.GetObject(srcImageHandle, BITMAP.sizeof, bm); - imageMetadata = new ImageHandle(OS.CreateCompatibleBitmap(hdcSource, rect.width, bm.bmBits != 0 ? -rect.height : rect.height), getZoom()); - if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle); - OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY); - OS.SelectObject(hdcSource, hOldSrc); - OS.SelectObject(hdcDest, hOldDest); - OS.DeleteDC(hdcSource); - OS.DeleteDC(hdcDest); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - + for (ImageHandle imageHandle : srcImage.zoomLevelToImageHandle.values()) { + Rectangle rect = imageHandle.getBounds(); + long srcImageHandle = imageHandle.handle; + /* Get the HDC for the device */ + long hDC = device.internal_new_GC(null); + + /* Copy the bitmap */ + long hdcSource = OS.CreateCompatibleDC(hDC); + long hdcDest = OS.CreateCompatibleDC(hDC); + long hOldSrc = OS.SelectObject(hdcSource, srcImageHandle); + BITMAP bm = new BITMAP(); + OS.GetObject(srcImageHandle, BITMAP.sizeof, bm); + imageMetadata = new ImageHandle(OS.CreateCompatibleBitmap(hdcSource, rect.width, bm.bmBits != 0 ? -rect.height : rect.height), imageHandle.zoom); + if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); + long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle); + OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY); + OS.SelectObject(hdcSource, hOldSrc); + OS.SelectObject(hdcDest, hOldDest); + OS.DeleteDC(hdcSource); + OS.DeleteDC(hdcDest); + + /* Release the HDC for the device */ + device.internal_dispose_GC(hDC, null); + } transparentPixel = srcImage.transparentPixel; break; case SWT.ICON: - imageMetadata = new ImageHandle(OS.CopyImage(srcImageHandle, OS.IMAGE_ICON, rect.width, rect.height, 0), getZoom()); - if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); + for (ImageHandle imageHandle : srcImage.zoomLevelToImageHandle.values()) { + Rectangle rect = imageHandle.getBounds(); + imageMetadata = new ImageHandle(OS.CopyImage(imageHandle.handle, OS.IMAGE_ICON, rect.width, rect.height, 0), imageHandle.zoom); + if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); + } break; default: SWT.error(SWT.ERROR_INVALID_IMAGE); @@ -286,15 +290,21 @@ public Image(Device device, Image srcImage, int flag) { break; } case SWT.IMAGE_DISABLE: { - ImageData data = srcImage.getImageData(srcImage.getZoom()); - ImageData newData = applyDisableImageData(data, rect.height, rect.width); - init (newData, getZoom()); + for (ImageHandle imageHandle : srcImage.zoomLevelToImageHandle.values()) { + Rectangle rect = imageHandle.getBounds(); + ImageData data = srcImage.getImageData(imageHandle.zoom); + ImageData newData = applyDisableImageData(data, rect.height, rect.width); + init (newData, imageHandle.zoom); + } break; } case SWT.IMAGE_GRAY: { - ImageData data = srcImage.getImageData(srcImage.getZoom()); - ImageData newData = applyGrayImageData(data, rect.height, rect.width); - init (newData, getZoom()); + for (ImageHandle imageHandle : srcImage.zoomLevelToImageHandle.values()) { + Rectangle rect = imageHandle.getBounds(); + ImageData data = srcImage.getImageData(imageHandle.zoom); + ImageData newData = applyGrayImageData(data, rect.height, rect.width); + init (newData, imageHandle.zoom); + } break; } default: @@ -2558,6 +2568,10 @@ public ImageHandle(long handle, int zoom) { setImageMetadataForHandle(this, zoom); } + public Rectangle getBounds() { + return new Rectangle(0, 0, width, height); + } + private void setBackground(RGB color) { if (transparentPixel == -1) return; diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java index bb639b08287..502f14dfe65 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet382.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.swt.snippets; +import java.util.function.*; + import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.*; @@ -65,8 +67,8 @@ public static void main (String [] args) { final Display display = new Display (); final Image imageWithFileNameProvider = new Image (display, filenameProvider); - final Image disabledImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_DISABLE); - final Image greyImageWithFileNameProvider = new Image (display,imageWithFileNameProvider, SWT.IMAGE_GRAY); + final Supplier disabledImageWithFileNameProvider = () -> new Image (display,imageWithFileNameProvider, SWT.IMAGE_DISABLE); + final Supplier greyImageWithFileNameProvider = () -> new Image (display,imageWithFileNameProvider, SWT.IMAGE_GRAY); final Image imageWithDataProvider = new Image (display, imageDataProvider); final Image disabledImageWithDataProvider = new Image (display,imageWithDataProvider, SWT.IMAGE_DISABLE); @@ -76,6 +78,10 @@ public static void main (String [] args) { final Image disabledImageWithData = new Image (display,imageWithData, SWT.IMAGE_DISABLE); final Image greyImageWithData = new Image (display,imageWithData, SWT.IMAGE_GRAY); + final Supplier imageWithDataCopy = () -> new Image (display, imageWithDataProvider, SWT.IMAGE_COPY); + final Supplier disabledImageWithDataCopy = () -> new Image (display,disabledImageWithDataProvider, SWT.IMAGE_COPY); + final Supplier greyImageWithDataCopy = () -> new Image (display,greyImageWithDataProvider, SWT.IMAGE_COPY); + final ImageGcDrawer imageGcDrawer = (gc, width, height) -> { gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillRectangle(0, 0, width, height); @@ -111,42 +117,53 @@ public void handleEvent(Event e) { if (e.type == SWT.Paint) { GC mainGC = e.gc; GCData gcData = mainGC.getGCData(); - + gcData.nativeZoom = 100; try { + mainGC.drawText("--ImageFileNameProvider--", 20, 20); drawImages(mainGC, gcData, "Normal",40, imageWithFileNameProvider); - drawImages(mainGC, gcData, "Disabled",80, disabledImageWithFileNameProvider); - drawImages(mainGC, gcData, "Greyed",120, greyImageWithFileNameProvider); - - drawImages(mainGC, gcData, "Normal",160, imageWithDataProvider); - drawImages(mainGC, gcData, "Disabled",200, disabledImageWithDataProvider); - drawImages(mainGC, gcData, "Greyed",240, greyImageWithDataProvider); - - drawImages(mainGC, gcData, "Normal",280, imageWithDataProvider); - drawImages(mainGC, gcData, "Disabled",320, disabledImageWithData); - drawImages(mainGC, gcData, "Greyed",360, greyImageWithData); - - drawImages(mainGC, gcData, "Normal", 400, imageWithGcDrawer); - drawImages(mainGC, gcData, "Disabled", 440, disabledImageWithGcDrawer); - drawImages(mainGC, gcData, "Greyed", 480, greyImageWithGcDrawer); - - drawImages(mainGC, gcData, "Normal", 520, imageWithTransparentGcDrawer); - drawImages(mainGC, gcData, "Disabled", 560, disabledImageWithTransparentGcDrawer); - drawImages(mainGC, gcData, "Greyed", 600, greyImageWithTransparentGcDrawer); + drawImages(mainGC, gcData, "Disabled",80, disabledImageWithFileNameProvider.get()); + drawImages(mainGC, gcData, "Greyed",120, greyImageWithFileNameProvider.get()); + + mainGC.drawText("--ImageDataProvider--", 20, 150); + drawImages(mainGC, gcData, "Normal",180, imageWithDataProvider); + drawImages(mainGC, gcData, "Disabled",220, disabledImageWithDataProvider); + drawImages(mainGC, gcData, "Greyed",260, greyImageWithDataProvider); + + mainGC.drawText("--Image with ImageData--", 20, 290); + drawImages(mainGC, gcData, "Normal",320, imageWithData); + drawImages(mainGC, gcData, "Disabled",360, disabledImageWithData); + drawImages(mainGC, gcData, "Greyed",400, greyImageWithData); + + mainGC.drawText("--ImageDataProvider Copy--", 20, 430); + drawImages(mainGC, gcData, "Normal",460, imageWithDataCopy.get()); + drawImages(mainGC, gcData, "Disabled",500, disabledImageWithDataCopy.get()); + drawImages(mainGC, gcData, "Greyed",540, greyImageWithDataCopy.get()); + + mainGC.drawText("--ImageGcDrawer--", 20, 570); + drawImages(mainGC, gcData, "Normal", 600, imageWithGcDrawer); + drawImages(mainGC, gcData, "Disabled", 640, disabledImageWithGcDrawer); + drawImages(mainGC, gcData, "Greyed", 680, greyImageWithGcDrawer); + + mainGC.drawText("--Transparent ImageGcDrawer--", 20, 710); + drawImages(mainGC, gcData, "Normal", 740, imageWithTransparentGcDrawer); + drawImages(mainGC, gcData, "Disabled", 780, disabledImageWithTransparentGcDrawer); + drawImages(mainGC, gcData, "Greyed", 820, greyImageWithTransparentGcDrawer); } finally { mainGC.dispose (); } } } - private void drawImages(GC mainGC, GCData gcData, String text, int y, final Image imageWithFileNameProvider) { + private void drawImages(GC mainGC, GCData gcData, String text, int y, final Image image) { gcData.nativeZoom = 100; mainGC.drawText(text, 0, y); - mainGC.drawImage(imageWithFileNameProvider, 50, y); + mainGC.drawImage(image, 50, y); gcData.nativeZoom = 150; - mainGC.drawImage(imageWithFileNameProvider, 100, (int) (y/1.5)); + mainGC.drawImage(image, 100, (int) (y/1.5)); gcData.nativeZoom = 200; - mainGC.drawImage(imageWithFileNameProvider, 150, y/2); + mainGC.drawImage(image, 150, y/2); + gcData.nativeZoom = 100; } }; shell.addListener(SWT.Paint, l);