Skip to content

Commit 266e975

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 97855ad commit 266e975

File tree

3 files changed

+93
-50
lines changed

3 files changed

+93
-50
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageGcDrawer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public interface ImageGcDrawer {
4545
* @param imageData The resulting ImageData after <code>drawOn</code> was called
4646
*/
4747
default void postProcess(ImageData imageData) {
48+
imageData.data = null;
4849
}
4950

5051
/**

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
@@ -1951,6 +1951,46 @@ protected final ImageHandle newImageHandle(ImageData data, int zoom) {
19511951
return init(data, zoom);
19521952
}
19531953
}
1954+
1955+
protected final ImageHandle createHandle(int width, int height, int zoom) {
1956+
long handle = initHandle(width, height, zoom);
1957+
ImageHandle imageHandle = new ImageHandle(handle, zoom);
1958+
zoomLevelToImageHandle.put(zoom, imageHandle);
1959+
return imageHandle;
1960+
}
1961+
1962+
private long initHandle(int width, int height, int zoom) {
1963+
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
1964+
int scaledWidth = Win32DPIUtils.pointToPixel (width, zoom);
1965+
int scaledHeight = Win32DPIUtils.pointToPixel (height, zoom);
1966+
long hDC = device.internal_new_GC(null);
1967+
long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight);
1968+
/*
1969+
* Feature in Windows. CreateCompatibleBitmap() may fail
1970+
* for large images. The fix is to create a DIB section
1971+
* in that case.
1972+
*/
1973+
if (newHandle == 0) {
1974+
int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL);
1975+
int planes = OS.GetDeviceCaps(hDC, OS.PLANES);
1976+
int depth = bits * planes;
1977+
if (depth < 16) depth = 16;
1978+
if (depth > 24) depth = 24;
1979+
newHandle = createDIB(scaledWidth, scaledHeight, depth);
1980+
}
1981+
if (newHandle != 0) {
1982+
long memDC = OS.CreateCompatibleDC(hDC);
1983+
long hOldBitmap = OS.SelectObject(memDC, newHandle);
1984+
OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY);
1985+
OS.SelectObject(memDC, hOldBitmap);
1986+
OS.DeleteDC(memDC);
1987+
}
1988+
device.internal_dispose_GC(hDC, null);
1989+
if (newHandle == 0) {
1990+
SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError());
1991+
}
1992+
return newHandle;
1993+
}
19541994
}
19551995

19561996
private class ExistingImageHandleProviderWrapper extends AbstractImageProviderWrapper {
@@ -2179,55 +2219,15 @@ protected ImageHandle newImageHandle(int zoom) {
21792219
if (memGC != null) {
21802220
GC currentGC = memGC;
21812221
memGC = null;
2182-
createHandle(zoom);
2222+
createHandle(this.width, this.height, zoom);
21832223
currentGC.refreshFor(new DrawableWrapper(Image.this, zoom), zoom);
21842224
return zoomLevelToImageHandle.get(zoom);
21852225
}
21862226
return super.newImageHandle(zoom);
21872227
}
21882228
private ImageHandle createBaseHandle(int zoom) {
21892229
baseZoom = zoom;
2190-
return createHandle(zoom);
2191-
}
2192-
2193-
private ImageHandle createHandle(int zoom) {
2194-
long handle = initHandle(zoom);
2195-
ImageHandle imageHandle = new ImageHandle(handle, zoom);
2196-
zoomLevelToImageHandle.put(zoom, imageHandle);
2197-
return imageHandle;
2198-
}
2199-
2200-
private long initHandle(int zoom) {
2201-
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
2202-
int scaledWidth = Win32DPIUtils.pointToPixel (width, zoom);
2203-
int scaledHeight = Win32DPIUtils.pointToPixel (height, zoom);
2204-
long hDC = device.internal_new_GC(null);
2205-
long newHandle = OS.CreateCompatibleBitmap(hDC, scaledWidth, scaledHeight);
2206-
/*
2207-
* Feature in Windows. CreateCompatibleBitmap() may fail
2208-
* for large images. The fix is to create a DIB section
2209-
* in that case.
2210-
*/
2211-
if (newHandle == 0) {
2212-
int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL);
2213-
int planes = OS.GetDeviceCaps(hDC, OS.PLANES);
2214-
int depth = bits * planes;
2215-
if (depth < 16) depth = 16;
2216-
if (depth > 24) depth = 24;
2217-
newHandle = createDIB(scaledWidth, scaledHeight, depth);
2218-
}
2219-
if (newHandle != 0) {
2220-
long memDC = OS.CreateCompatibleDC(hDC);
2221-
long hOldBitmap = OS.SelectObject(memDC, newHandle);
2222-
OS.PatBlt(memDC, 0, 0, scaledWidth, scaledHeight, OS.PATCOPY);
2223-
OS.SelectObject(memDC, hOldBitmap);
2224-
OS.DeleteDC(memDC);
2225-
}
2226-
device.internal_dispose_GC(hDC, null);
2227-
if (newHandle == 0) {
2228-
SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError());
2229-
}
2230-
return newHandle;
2230+
return createHandle(this.width, this.height, zoom);
22312231
}
22322232

22332233
@Override
@@ -2596,27 +2596,28 @@ ImageData newImageData(int zoom) {
25962596
protected ImageHandle newImageHandle(int zoom) {
25972597
currentZoom = zoom;
25982598
int gcStyle = drawer.getGcStyle();
2599-
Image image;
26002599
if ((gcStyle & SWT.TRANSPARENT) != 0) {
26012600
int scaledHeight = Win32DPIUtils.pointToPixel(height, zoom);
26022601
int scaledWidth = Win32DPIUtils.pointToPixel(width, zoom);
26032602
/* Create a 24 bit image data with alpha channel */
26042603
final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
26052604
resultData.alphaData = new byte [scaledWidth * scaledHeight];
2606-
image = new Image(device, resultData, zoom);
2605+
init(resultData, zoom);
26072606
} else {
2608-
image = new Image(device, width, height);
2607+
createHandle(width, height, zoom);
26092608
}
2610-
GC gc = new GC(new DrawableWrapper(image, zoom), gcStyle);
2609+
GC gc = new GC(new DrawableWrapper(Image.this, zoom), gcStyle);
26112610
try {
26122611
drawer.drawOn(gc, width, height);
2613-
ImageData imageData = image.getImageMetadata(zoom).getImageData();
2612+
ImageData imageData = Image.this.getImageMetadata(zoom).getImageData();
26142613
drawer.postProcess(imageData);
2615-
ImageData newData = adaptImageDataIfDisabledOrGray(imageData);
2616-
return init(newData, zoom);
2614+
if(imageData.data != null) { // dont make it null in ImageGCDrawerWrapper instead find something else
2615+
zoomLevelToImageHandle.get(zoom).destroy();
2616+
init(imageData, zoom);
2617+
}
2618+
return zoomLevelToImageHandle.get(zoom);
26172619
} finally {
26182620
gc.dispose();
2619-
image.dispose();
26202621
}
26212622
}
26222623

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,5 +1136,46 @@ private Comparator<ImageData> imageDataComparator() {
11361136
});
11371137
}
11381138

1139+
@Test
1140+
public void test_ImageWithImageGcDrawerWrapper() {
1141+
// Create baseline image using direct GC operations
1142+
Image baselineImage = gcOperationOnImage();
1143+
ImageData expectedImageData = baselineImage.getImageData();
1144+
1145+
// Create image using ImageGcDrawer wrapper
1146+
Image imageWithDrawer = new Image(display, gcOperationViaGcDrawer(), 16, 16);
1147+
ImageData actualImageData = imageWithDrawer.getImageData();
1148+
1149+
// Compare the two images
1150+
assertEquals(0, imageDataComparator().compare(expectedImageData, actualImageData));
1151+
1152+
// Cleanup
1153+
baselineImage.dispose();
1154+
imageWithDrawer.dispose();
1155+
}
1156+
1157+
private Image gcOperationOnImage() {
1158+
Image image = new Image(display, 16, 16);
1159+
GC gc = new GC(image);
1160+
try {
1161+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
1162+
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
1163+
gc.fillRectangle(0, 0, 16, 16);
1164+
} finally {
1165+
gc.dispose();
1166+
}
1167+
//image.getImageData().transparentPixel = display.getSystemColor(SWT.COLOR_BLACK).getAlpha();
1168+
return image;
1169+
}
1170+
1171+
private ImageGcDrawer gcOperationViaGcDrawer() {
1172+
return (gc, width, height) -> {
1173+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
1174+
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
1175+
gc.fillRectangle(0, 0, width, height);
1176+
};
1177+
}
1178+
1179+
11391180
}
11401181

0 commit comments

Comments
 (0)