Skip to content

Commit a8d8a82

Browse files
Use the existing image to initialize the GC in ImageGcDrawerWrapper
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.
1 parent 9faeb19 commit a8d8a82

File tree

2 files changed

+84
-50
lines changed

2 files changed

+84
-50
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,6 +1911,47 @@ protected final ImageHandle newImageHandle(ImageData data, int zoom) {
19111911
return init(data, zoom);
19121912
}
19131913
}
1914+
1915+
protected final ImageHandle createBaseHandle(int zoom, int width, int height) {
1916+
long handle = initBaseHandle(zoom, width, height);
1917+
ImageHandle imageHandle = new ImageHandle(handle, zoom);
1918+
zoomLevelToImageHandle.put(zoom, imageHandle);
1919+
return imageHandle;
1920+
}
1921+
1922+
1923+
private long initBaseHandle(int zoom, int width, int height) {
1924+
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
1925+
int scaledWidth = DPIUtil.scaleUp (width, zoom);
1926+
int scaledHeight = DPIUtil.scaleUp (height, zoom);
1927+
long hDC = device.internal_new_GC(null);
1928+
long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight);
1929+
/*
1930+
* Feature in Windows. CreateCompatibleBitmap() may fail
1931+
* for large images. The fix is to create a DIB section
1932+
* in that case.
1933+
*/
1934+
if (newHandle == 0) {
1935+
int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL);
1936+
int planes = OS.GetDeviceCaps(hDC, OS.PLANES);
1937+
int depth = bits * planes;
1938+
if (depth < 16) depth = 16;
1939+
if (depth > 24) depth = 24;
1940+
newHandle = createDIB(scaledWidth, scaledHeight, depth);
1941+
}
1942+
if (newHandle != 0) {
1943+
long memDC = OS.CreateCompatibleDC(hDC);
1944+
long hOldBitmap = OS.SelectObject(memDC, newHandle);
1945+
OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY);
1946+
OS.SelectObject(memDC, hOldBitmap);
1947+
OS.DeleteDC(memDC);
1948+
}
1949+
device.internal_dispose_GC(hDC, null);
1950+
if (newHandle == 0) {
1951+
SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError());
1952+
}
1953+
return newHandle;
1954+
}
19141955
}
19151956

19161957
private class ExistingImageHandleProviderWrapper extends AbstractImageProviderWrapper {
@@ -2121,59 +2162,22 @@ protected Rectangle getBounds(int zoom) {
21212162
@Override
21222163
ImageData newImageData(int zoom) {
21232164
if (zoomLevelToImageHandle.isEmpty()) {
2124-
return createBaseHandle(zoom).getImageData();
2165+
baseZoom = zoom;
2166+
return createBaseHandle(zoom, width, height).getImageData();
21252167
}
21262168
return getScaledImageData(zoom);
21272169
}
21282170

21292171
@Override
21302172
protected ImageHandle newImageHandle(int zoom) {
21312173
if (zoomLevelToImageHandle.isEmpty()) {
2132-
return createBaseHandle(zoom);
2174+
baseZoom = zoom;
2175+
return createBaseHandle(zoom, width, height);
21332176
}
21342177
return super.newImageHandle(zoom);
21352178
}
21362179

2137-
private ImageHandle createBaseHandle(int zoom) {
2138-
long handle = initBaseHandle(zoom);
2139-
baseZoom = zoom;
2140-
ImageHandle imageHandle = new ImageHandle(handle, zoom);
2141-
zoomLevelToImageHandle.put(zoom, imageHandle);
2142-
return imageHandle;
2143-
}
21442180

2145-
private long initBaseHandle(int zoom) {
2146-
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
2147-
int scaledWidth = DPIUtil.scaleUp (width, zoom);
2148-
int scaledHeight = DPIUtil.scaleUp (height, zoom);
2149-
long hDC = device.internal_new_GC(null);
2150-
long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight);
2151-
/*
2152-
* Feature in Windows. CreateCompatibleBitmap() may fail
2153-
* for large images. The fix is to create a DIB section
2154-
* in that case.
2155-
*/
2156-
if (newHandle == 0) {
2157-
int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL);
2158-
int planes = OS.GetDeviceCaps(hDC, OS.PLANES);
2159-
int depth = bits * planes;
2160-
if (depth < 16) depth = 16;
2161-
if (depth > 24) depth = 24;
2162-
newHandle = createDIB(scaledWidth, scaledHeight, depth);
2163-
}
2164-
if (newHandle != 0) {
2165-
long memDC = OS.CreateCompatibleDC(hDC);
2166-
long hOldBitmap = OS.SelectObject(memDC, newHandle);
2167-
OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY);
2168-
OS.SelectObject(memDC, hOldBitmap);
2169-
OS.DeleteDC(memDC);
2170-
}
2171-
device.internal_dispose_GC(hDC, null);
2172-
if (newHandle == 0) {
2173-
SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError());
2174-
}
2175-
return newHandle;
2176-
}
21772181

21782182
@Override
21792183
AbstractImageProviderWrapper createCopy(Image image) {
@@ -2541,28 +2545,25 @@ ImageData newImageData(int zoom) {
25412545
protected ImageHandle newImageHandle(int zoom) {
25422546
currentZoom = zoom;
25432547
int gcStyle = drawer.getGcStyle();
2544-
Image image;
25452548
if ((gcStyle & SWT.TRANSPARENT) != 0) {
25462549
int scaledHeight = DPIUtil.scaleUp(height, zoom);
25472550
int scaledWidth = DPIUtil.scaleUp(width, zoom);
25482551
/* Create a 24 bit image data with alpha channel */
25492552
final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
25502553
resultData.alphaData = new byte [scaledWidth * scaledHeight];
2551-
image = new Image(device, resultData, zoom);
2554+
init(resultData, zoom);
25522555
} else {
2553-
image = new Image(device, width, height);
2554-
}
2555-
GC gc = new GC(new DrawableWrapper(image, zoom), gcStyle);
2556+
createBaseHandle(zoom, width, height);
2557+
};
2558+
GC gc = new GC(new DrawableWrapper(Image.this, zoom), gcStyle);
25562559
try {
25572560
gc.data.nativeZoom = zoom;
25582561
drawer.drawOn(gc, width, height);
2559-
ImageData imageData = image.getImageMetadata(zoom).getImageData();
2562+
ImageData imageData = Image.this.getImageMetadata(zoom).getImageData();
25602563
drawer.postProcess(imageData);
2561-
ImageData newData = adaptImageDataIfDisabledOrGray(imageData);
2562-
return init(newData, zoom);
2564+
return zoomLevelToImageHandle.get(zoom);
25632565
} finally {
25642566
gc.dispose();
2565-
image.dispose();
25662567
}
25672568
}
25682569

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,39 @@ public void test_imageDataSameViaProviderAndSimpleData() {
10751075
dataImage.dispose();
10761076
}
10771077

1078+
@Test
1079+
public void test_ImageWithImageGcDrawerWrapper() {
1080+
Image image = new Image(display, 16, 16);
1081+
GC gc = new GC(image);
1082+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
1083+
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
1084+
gc.fillRectangle(0, 0, 16, 16);
1085+
gc.dispose();
1086+
image.getImageData().transparentPixel = display.getSystemColor(SWT.COLOR_BLACK).getAlpha();
1087+
ImageData imageDataForSimpleImageWithGcOperation = image.getImageData();
1088+
1089+
final ImageGcDrawer imageGcDrawerWithPostProcess = new ImageGcDrawer() {
1090+
@Override
1091+
public void drawOn(GC gc, int width, int height) {
1092+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
1093+
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
1094+
gc.fillRectangle(0, 0, 16, 16);
1095+
}
1096+
1097+
@Override
1098+
public void postProcess(ImageData imageData) {
1099+
imageData.transparentPixel = display.getSystemColor(SWT.COLOR_BLACK).getAlpha();
1100+
}
1101+
};
1102+
Image imageWithGCDrawerWrapper = new Image(display, imageGcDrawerWithPostProcess, 16, 16);
1103+
ImageData imageDataForImageWithGcDrawer = imageWithGCDrawerWrapper.getImageData();
1104+
1105+
assertEquals(0, imageDataComparator().compare(imageDataForSimpleImageWithGcOperation, imageDataForImageWithGcDrawer));
1106+
1107+
image.dispose();
1108+
imageWithGCDrawerWrapper.dispose();
1109+
}
1110+
10781111

10791112
private Comparator<ImageData> imageDataComparator() {
10801113
return Comparator.<ImageData>comparingInt(d -> d.width) //

0 commit comments

Comments
 (0)