From abc68c934e430b828f692c707553175ce2278685 Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Mon, 11 Aug 2025 14:46:44 +0200 Subject: [PATCH 1/3] Use the existing image to initialize the GC in ImageGcDrawerWrapper For Windows, In ImageGCDrawerWrapper#newImageHandle, we create a new image with existing data to initialize the GC, instead we could use the existing image object and the base handle should be created as it is done in PlainImageDataProvider. For GTK and Cocoa, We use init methods to create new handles instead of creating a new Image object. --- .../cocoa/org/eclipse/swt/graphics/Image.java | 10 +- .../gtk/org/eclipse/swt/graphics/Image.java | 10 +- .../win32/org/eclipse/swt/graphics/Image.java | 107 ++++++++---------- 3 files changed, 57 insertions(+), 70 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java index 0dc7f5e36d5..108c6c785b2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java @@ -903,24 +903,22 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height) private ImageData drawWithImageGcDrawer(ImageGcDrawer imageGcDrawer, int width, int height, int zoom) { int gcStyle = imageGcDrawer.getGcStyle(); - Image image; if ((gcStyle & SWT.TRANSPARENT) != 0) { /* Create a 24 bit image data with alpha channel */ final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); resultData.alphaData = new byte [width * height]; - image = new Image(device, resultData); + init(resultData, zoom); } else { - image = new Image(device, width, height); + init(width, height); } - GC gc = new GC(image, gcStyle); + GC gc = new GC(Image.this, gcStyle); try { imageGcDrawer.drawOn(gc, width, height); - ImageData imageData = image.getImageData(zoom); + ImageData imageData = Image.this.getImageData(zoom); imageGcDrawer.postProcess(imageData); return imageData; } finally { gc.dispose(); - image.dispose(); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index f77c83f79e9..ace2873e576 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1169,24 +1169,22 @@ public ImageData getImageData (int zoom) { private ImageData drawWithImageGcDrawer(int width, int height, int zoom) { int gcStyle = imageGcDrawer.getGcStyle(); - Image image; if ((gcStyle & SWT.TRANSPARENT) != 0) { /* Create a 24 bit image data with alpha channel */ final ImageData resultData = new ImageData(width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); resultData.alphaData = new byte [width * height]; - image = new Image(device, resultData, zoom); + init(resultData, zoom); } else { - image = new Image(device, width, height); + init(width, height); } - GC gc = new GC(image, gcStyle); + GC gc = new GC(Image.this, gcStyle); try { imageGcDrawer.drawOn(gc, width, height); - ImageData imageData = image.getImageData(zoom); + ImageData imageData = Image.this.getImageData(zoom); imageGcDrawer.postProcess(imageData); return imageData; } finally { gc.dispose(); - image.dispose(); } } 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 84147c25e0c..188c93a335a 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 @@ -380,14 +380,6 @@ public Image(Device device, ImageData data) { this.device.registerResourceWithZoomSupport(this); } -private Image(Device device, ImageData data, int zoom) { - super(device); - if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.imageProvider = new PlainImageDataProviderWrapper(data, zoom); - init(); - this.device.registerResourceWithZoomSupport(this); -} - /** * Constructs an instance of this class, whose type is * SWT.ICON, from the two given ImageData @@ -1957,6 +1949,46 @@ protected final ImageHandle newImageHandle(ImageData data, ZoomContext zoomConte return init(data, zoomContext.targetZoom()); } } + + protected final ImageHandle createHandle(int width, int height, int zoom) { + long handle = initHandle(width, height, zoom); + ImageHandle imageHandle = new ImageHandle(handle, zoom); + zoomLevelToImageHandle.put(zoom, imageHandle); + return imageHandle; + } + + private long initHandle(int width, int height, int zoom) { + if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + int scaledWidth = Win32DPIUtils.pointToPixel (width, zoom); + int scaledHeight = Win32DPIUtils.pointToPixel (height, zoom); + long hDC = device.internal_new_GC(null); + long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight); + /* + * Feature in Windows. CreateCompatibleBitmap() may fail + * for large images. The fix is to create a DIB section + * in that case. + */ + if (newHandle == 0) { + int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL); + int planes = OS.GetDeviceCaps(hDC, OS.PLANES); + int depth = bits * planes; + if (depth < 16) depth = 16; + if (depth > 24) depth = 24; + newHandle = createDIB(scaledWidth, scaledHeight, depth); + } + if (newHandle != 0) { + long memDC = OS.CreateCompatibleDC(hDC); + long hOldBitmap = OS.SelectObject(memDC, newHandle); + OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY); + OS.SelectObject(memDC, hOldBitmap); + OS.DeleteDC(memDC); + } + device.internal_dispose_GC(hDC, null); + if (newHandle == 0) { + SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError()); + } + return newHandle; + } } private class ExistingImageHandleProviderWrapper extends AbstractImageProviderWrapper { @@ -2196,7 +2228,7 @@ protected ImageHandle newImageHandle(ZoomContext zoomContext) { if (memGC.getZoom() != targetZoom) { GC currentGC = memGC; memGC = null; - createHandle(targetZoom); + createHandle(this.width, this.height, targetZoom); currentGC.refreshFor(new DrawableWrapper(Image.this, zoomContext)); } return zoomLevelToImageHandle.get(targetZoom); @@ -2205,47 +2237,7 @@ protected ImageHandle newImageHandle(ZoomContext zoomContext) { } private ImageHandle createBaseHandle(int zoom) { baseZoom = zoom; - return createHandle(zoom); - } - - private ImageHandle createHandle(int zoom) { - long handle = initHandle(zoom); - ImageHandle imageHandle = new ImageHandle(handle, zoom); - zoomLevelToImageHandle.put(zoom, imageHandle); - return imageHandle; - } - - private long initHandle(int zoom) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - int scaledWidth = Win32DPIUtils.pointToPixel (width, zoom); - int scaledHeight = Win32DPIUtils.pointToPixel (height, zoom); - long hDC = device.internal_new_GC(null); - long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight); - /* - * Feature in Windows. CreateCompatibleBitmap() may fail - * for large images. The fix is to create a DIB section - * in that case. - */ - if (newHandle == 0) { - int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL); - int planes = OS.GetDeviceCaps(hDC, OS.PLANES); - int depth = bits * planes; - if (depth < 16) depth = 16; - if (depth > 24) depth = 24; - newHandle = createDIB(scaledWidth, scaledHeight, depth); - } - if (newHandle != 0) { - long memDC = OS.CreateCompatibleDC(hDC); - long hOldBitmap = OS.SelectObject(memDC, newHandle); - OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY); - OS.SelectObject(memDC, hOldBitmap); - OS.DeleteDC(memDC); - } - device.internal_dispose_GC(hDC, null); - if (newHandle == 0) { - SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError()); - } - return newHandle; + return createHandle(this.width, this.height, zoom); } @Override @@ -2621,27 +2613,26 @@ protected ImageHandle newImageHandle(ZoomContext zoomContext) { currentZoom = zoomContext; int targetZoom = zoomContext.targetZoom(); int gcStyle = drawer.getGcStyle(); - Image image; if ((gcStyle & SWT.TRANSPARENT) != 0) { int scaledHeight = Win32DPIUtils.pointToPixel(height, targetZoom); int scaledWidth = Win32DPIUtils.pointToPixel(width, targetZoom); /* Create a 24 bit image data with alpha channel */ final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000)); resultData.alphaData = new byte [scaledWidth * scaledHeight]; - image = new Image(device, resultData, targetZoom); + init(resultData, targetZoom); } else { - image = new Image(device, width, height); + createHandle(width, height, targetZoom); } - GC gc = new GC(new DrawableWrapper(image, zoomContext), gcStyle); + GC gc = new GC(new DrawableWrapper(Image.this, zoomContext), gcStyle); try { drawer.drawOn(gc, width, height); - ImageData imageData = image.getImageData(targetZoom); + ImageData imageData = Image.this.getImageData(targetZoom); drawer.postProcess(imageData); - ImageData newData = adaptImageDataIfDisabledOrGray(imageData); - return init(newData, targetZoom); + zoomLevelToImageHandle.get(targetZoom).destroy(); + init(imageData, targetZoom); + return zoomLevelToImageHandle.get(targetZoom); } finally { gc.dispose(); - image.dispose(); } } From 64f5fd24928459b36c61fe473c04acccb341d485 Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Fri, 19 Sep 2025 14:02:09 +0200 Subject: [PATCH 2/3] This commit is to find out what exactly issue is in gtk --- .../Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index ace2873e576..3dc47180e91 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1452,7 +1452,11 @@ private void init(ImageData image, int zoom) { @Override public long internal_new_GC (GCData data) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (type != SWT.BITMAP || memGC != null) { + if (type != SWT.BITMAP) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + if(memGC != null) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } long gc = Cairo.cairo_create(surface); From 01ddea2f14e56bf5ee6f1a57d90f29a8cbdd2acc Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Fri, 19 Sep 2025 14:04:20 +0200 Subject: [PATCH 3/3] this too --- .../Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index 3dc47180e91..11156820dd9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1453,7 +1453,7 @@ private void init(ImageData image, int zoom) { public long internal_new_GC (GCData data) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (type != SWT.BITMAP) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "The type is " + type); } if(memGC != null) {