diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageGcDrawer.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageGcDrawer.java
index 78388ef93bc..95f2466cd50 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageGcDrawer.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageGcDrawer.java
@@ -45,6 +45,7 @@ public interface ImageGcDrawer {
* @param imageData The resulting ImageData after drawOn
was called
*/
default void postProcess(ImageData imageData) {
+ imageData.data = null;
}
/**
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 a78bb198666..20e365cfd42 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
@@ -1911,6 +1911,47 @@ protected final ImageHandle newImageHandle(ImageData data, int zoom) {
return init(data, zoom);
}
}
+
+ protected final ImageHandle createBaseHandle(int zoom, int width, int height) {
+ long handle = initBaseHandle(zoom, width, height);
+ ImageHandle imageHandle = new ImageHandle(handle, zoom);
+ zoomLevelToImageHandle.put(zoom, imageHandle);
+ return imageHandle;
+ }
+
+
+ private long initBaseHandle(int zoom, int width, int height) {
+ if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ int scaledWidth = DPIUtil.scaleUp (width, zoom);
+ int scaledHeight = DPIUtil.scaleUp (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 {
@@ -2121,7 +2162,8 @@ protected Rectangle getBounds(int zoom) {
@Override
ImageData newImageData(int zoom) {
if (zoomLevelToImageHandle.isEmpty()) {
- return createBaseHandle(zoom).getImageData();
+ baseZoom = zoom;
+ return createBaseHandle(zoom, width, height).getImageData();
}
return getScaledImageData(zoom);
}
@@ -2129,51 +2171,13 @@ ImageData newImageData(int zoom) {
@Override
protected ImageHandle newImageHandle(int zoom) {
if (zoomLevelToImageHandle.isEmpty()) {
- return createBaseHandle(zoom);
+ baseZoom = zoom;
+ return createBaseHandle(zoom, width, height);
}
return super.newImageHandle(zoom);
}
- private ImageHandle createBaseHandle(int zoom) {
- long handle = initBaseHandle(zoom);
- baseZoom = zoom;
- ImageHandle imageHandle = new ImageHandle(handle, zoom);
- zoomLevelToImageHandle.put(zoom, imageHandle);
- return imageHandle;
- }
- private long initBaseHandle(int zoom) {
- if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
- int scaledWidth = DPIUtil.scaleUp (width, zoom);
- int scaledHeight = DPIUtil.scaleUp (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;
- }
@Override
AbstractImageProviderWrapper createCopy(Image image) {
@@ -2541,28 +2545,29 @@ ImageData newImageData(int zoom) {
protected ImageHandle newImageHandle(int zoom) {
currentZoom = zoom;
int gcStyle = drawer.getGcStyle();
- Image image;
if ((gcStyle & SWT.TRANSPARENT) != 0) {
int scaledHeight = DPIUtil.scaleUp(height, zoom);
int scaledWidth = DPIUtil.scaleUp(width, zoom);
/* 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, zoom);
+ init(resultData, zoom);
} else {
- image = new Image(device, width, height);
- }
- GC gc = new GC(new DrawableWrapper(image, zoom), gcStyle);
+ createBaseHandle(zoom, width, height);
+ };
+ GC gc = new GC(new DrawableWrapper(Image.this, zoom), gcStyle);
try {
gc.data.nativeZoom = zoom;
drawer.drawOn(gc, width, height);
- ImageData imageData = image.getImageMetadata(zoom).getImageData();
+ ImageData imageData = Image.this.getImageMetadata(zoom).getImageData();
drawer.postProcess(imageData);
- ImageData newData = adaptImageDataIfDisabledOrGray(imageData);
- return init(newData, zoom);
+ if(imageData.data != null) {
+ zoomLevelToImageHandle.get(zoom).destroy();
+ init(imageData, zoom);
+ }
+ return zoomLevelToImageHandle.get(zoom);
} finally {
gc.dispose();
- image.dispose();
}
}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java
index c19b6e172b4..4757053b346 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java
@@ -1075,6 +1075,39 @@ public void test_imageDataSameViaProviderAndSimpleData() {
dataImage.dispose();
}
+@Test
+public void test_ImageWithImageGcDrawerWrapper() {
+ Image image = new Image(display, 16, 16);
+ GC gc = new GC(image);
+ gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
+ gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
+ gc.fillRectangle(0, 0, 16, 16);
+ gc.dispose();
+ image.getImageData().transparentPixel = display.getSystemColor(SWT.COLOR_BLACK).getAlpha();
+ ImageData imageDataForSimpleImageWithGcOperation = image.getImageData();
+
+ final ImageGcDrawer imageGcDrawerWithPostProcess = new ImageGcDrawer() {
+ @Override
+ public void drawOn(GC gc, int width, int height) {
+ gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
+ gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
+ gc.fillRectangle(0, 0, 16, 16);
+ }
+
+ @Override
+ public void postProcess(ImageData imageData) {
+ imageData.transparentPixel = display.getSystemColor(SWT.COLOR_BLACK).getAlpha();
+ }
+ };
+ Image imageWithGCDrawerWrapper = new Image(display, imageGcDrawerWithPostProcess, 16, 16);
+ ImageData imageDataForImageWithGcDrawer = imageWithGCDrawerWrapper.getImageData();
+
+ assertEquals(0, imageDataComparator().compare(imageDataForSimpleImageWithGcOperation, imageDataForImageWithGcDrawer));
+
+ image.dispose();
+ imageWithGCDrawerWrapper.dispose();
+}
+
private Comparator imageDataComparator() {
return Comparator.comparingInt(d -> d.width) //