Skip to content

Commit 34960df

Browse files
committed
[win32] Utilize temporary image handles
This commit adapts all places, where operation where executed with OS handles created for a specific zoom that could use any zoom. Therefor now any existing handle is used or, if none exists yet, a temporary handle is created and destroyed afterwards.
1 parent 48a2524 commit 34960df

File tree

1 file changed

+85
-63
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+85
-63
lines changed

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

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -253,32 +253,32 @@ public Image(Device device, Image srcImage, int flag) {
253253
case SWT.IMAGE_COPY: {
254254
switch (type) {
255255
case SWT.BITMAP:
256-
/* Get the HDC for the device */
257-
long hDC = device.internal_new_GC(null);
258-
259-
/* Copy the bitmap */
260-
long hdcSource = OS.CreateCompatibleDC(hDC);
261-
long hdcDest = OS.CreateCompatibleDC(hDC);
262-
long hOldSrc = OS.SelectObject(hdcSource, srcImageHandle);
263-
BITMAP bm = new BITMAP();
264-
OS.GetObject(srcImageHandle, BITMAP.sizeof, bm);
256+
/* Get the HDC for the device */
257+
long hDC = device.internal_new_GC(null);
258+
259+
/* Copy the bitmap */
260+
long hdcSource = OS.CreateCompatibleDC(hDC);
261+
long hdcDest = OS.CreateCompatibleDC(hDC);
262+
long hOldSrc = OS.SelectObject(hdcSource, srcImageHandle);
263+
BITMAP bm = new BITMAP();
264+
OS.GetObject(srcImageHandle, BITMAP.sizeof, bm);
265265
imageMetadata = new ImageHandle(OS.CreateCompatibleBitmap(hdcSource, rect.width, bm.bmBits != 0 ? -rect.height : rect.height), getZoom());
266-
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
267-
long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle);
268-
OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY);
269-
OS.SelectObject(hdcSource, hOldSrc);
270-
OS.SelectObject(hdcDest, hOldDest);
271-
OS.DeleteDC(hdcSource);
272-
OS.DeleteDC(hdcDest);
273-
274-
/* Release the HDC for the device */
275-
device.internal_dispose_GC(hDC, null);
266+
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
267+
long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle);
268+
OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY);
269+
OS.SelectObject(hdcSource, hOldSrc);
270+
OS.SelectObject(hdcDest, hOldDest);
271+
OS.DeleteDC(hdcSource);
272+
OS.DeleteDC(hdcDest);
273+
274+
/* Release the HDC for the device */
275+
device.internal_dispose_GC(hDC, null);
276276

277277
transparentPixel = srcImage.transparentPixel;
278278
break;
279279
case SWT.ICON:
280280
imageMetadata = new ImageHandle(OS.CopyImage(srcImageHandle, OS.IMAGE_ICON, rect.width, rect.height, 0), getZoom());
281-
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
281+
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
282282
break;
283283
default:
284284
SWT.error(SWT.ERROR_INVALID_IMAGE);
@@ -287,13 +287,13 @@ public Image(Device device, Image srcImage, int flag) {
287287
}
288288
case SWT.IMAGE_DISABLE: {
289289
ImageData data = srcImage.getImageData(srcImage.getZoom());
290-
ImageData newData = applyDisableImageData(data, rect.height, rect.width);
290+
ImageData newData = applyDisableImageData(data, rect.height, rect.width);
291291
init (newData, getZoom());
292292
break;
293293
}
294294
case SWT.IMAGE_GRAY: {
295295
ImageData data = srcImage.getImageData(srcImage.getZoom());
296-
ImageData newData = applyGrayImageData(data, rect.height, rect.width);
296+
ImageData newData = applyGrayImageData(data, rect.height, rect.width);
297297
init (newData, getZoom());
298298
break;
299299
}
@@ -1089,47 +1089,48 @@ public Color getBackground() {
10891089

10901090
/* Get the HDC for the device */
10911091
long hDC = device.internal_new_GC(null);
1092-
long handle = win32_getHandle(this, getZoom());
1093-
1094-
/* Compute the background color */
1095-
BITMAP bm = new BITMAP();
1096-
OS.GetObject(handle, BITMAP.sizeof, bm);
1097-
long hdcMem = OS.CreateCompatibleDC(hDC);
1098-
long hOldObject = OS.SelectObject(hdcMem, handle);
1099-
int red = 0, green = 0, blue = 0;
1100-
if (bm.bmBitsPixel <= 8) {
1101-
byte[] color = new byte[4];
1102-
OS.GetDIBColorTable(hdcMem, transparentPixel, 1, color);
1103-
blue = color[0] & 0xFF;
1104-
green = color[1] & 0xFF;
1105-
red = color[2] & 0xFF;
1106-
} else {
1107-
switch (bm.bmBitsPixel) {
1108-
case 16:
1109-
blue = (transparentPixel & 0x1F) << 3;
1110-
green = (transparentPixel & 0x3E0) >> 2;
1111-
red = (transparentPixel & 0x7C00) >> 7;
1112-
break;
1113-
case 24:
1114-
blue = (transparentPixel & 0xFF0000) >> 16;
1115-
green = (transparentPixel & 0xFF00) >> 8;
1116-
red = transparentPixel & 0xFF;
1117-
break;
1118-
case 32:
1119-
blue = (transparentPixel & 0xFF000000) >>> 24;
1120-
green = (transparentPixel & 0xFF0000) >> 16;
1121-
red = (transparentPixel & 0xFF00) >> 8;
1122-
break;
1123-
default:
1124-
return null;
1092+
return applyUsingAnyHandle(imageHandle -> {
1093+
long handle = imageHandle.handle;
1094+
/* Compute the background color */
1095+
BITMAP bm = new BITMAP();
1096+
OS.GetObject(handle, BITMAP.sizeof, bm);
1097+
long hdcMem = OS.CreateCompatibleDC(hDC);
1098+
long hOldObject = OS.SelectObject(hdcMem, handle);
1099+
int red = 0, green = 0, blue = 0;
1100+
if (bm.bmBitsPixel <= 8) {
1101+
byte[] color = new byte[4];
1102+
OS.GetDIBColorTable(hdcMem, transparentPixel, 1, color);
1103+
blue = color[0] & 0xFF;
1104+
green = color[1] & 0xFF;
1105+
red = color[2] & 0xFF;
1106+
} else {
1107+
switch (bm.bmBitsPixel) {
1108+
case 16:
1109+
blue = (transparentPixel & 0x1F) << 3;
1110+
green = (transparentPixel & 0x3E0) >> 2;
1111+
red = (transparentPixel & 0x7C00) >> 7;
1112+
break;
1113+
case 24:
1114+
blue = (transparentPixel & 0xFF0000) >> 16;
1115+
green = (transparentPixel & 0xFF00) >> 8;
1116+
red = transparentPixel & 0xFF;
1117+
break;
1118+
case 32:
1119+
blue = (transparentPixel & 0xFF000000) >>> 24;
1120+
green = (transparentPixel & 0xFF0000) >> 16;
1121+
red = (transparentPixel & 0xFF00) >> 8;
1122+
break;
1123+
default:
1124+
return null;
1125+
}
11251126
}
1126-
}
1127-
OS.SelectObject(hdcMem, hOldObject);
1128-
OS.DeleteDC(hdcMem);
1127+
OS.SelectObject(hdcMem, hOldObject);
1128+
OS.DeleteDC(hdcMem);
11291129

1130-
/* Release the HDC for the device */
1131-
device.internal_dispose_GC(hDC, null);
1132-
return Color.win32_new(device, (blue << 16) | (green << 8) | red);
1130+
/* Release the HDC for the device */
1131+
device.internal_dispose_GC(hDC, null);
1132+
return Color.win32_new(device, (blue << 16) | (green << 8) | red);
1133+
});
11331134
}
11341135

11351136
/**
@@ -1176,7 +1177,9 @@ Rectangle getBounds(int zoom) {
11761177
*/
11771178
@Deprecated
11781179
public Rectangle getBoundsInPixels() {
1179-
return getBounds(getZoom());
1180+
return applyUsingAnyHandle(imageHandle -> {
1181+
return imageHandle.getBounds();
1182+
});
11801183
}
11811184

11821185
/**
@@ -1258,7 +1261,9 @@ public ImageData getImageData (int zoom) {
12581261
*/
12591262
@Deprecated
12601263
public ImageData getImageDataAtCurrentZoom() {
1261-
return getImageMetadata(getZoom()).getImageData();
1264+
return applyUsingAnyHandle(imageHandle -> {
1265+
return imageHandle.getImageData();
1266+
});
12621267
}
12631268

12641269
/**
@@ -1832,6 +1837,19 @@ public String toString () {
18321837
return "Image {" + zoomLevelToImageHandle + "}";
18331838
}
18341839

1840+
<T> T applyUsingAnyHandle(Function<ImageHandle, T> function) {
1841+
if (zoomLevelToImageHandle.isEmpty()) {
1842+
ImageHandle temporaryHandle = this.imageProvider.newImageHandle(DPIUtil.getDeviceZoom());
1843+
try {
1844+
return function.apply(temporaryHandle);
1845+
} finally {
1846+
temporaryHandle.destroy();
1847+
}
1848+
} else {
1849+
return function.apply(zoomLevelToImageHandle.values().iterator().next());
1850+
}
1851+
}
1852+
18351853
/**
18361854
* Invokes platform specific functionality to allocate a new image.
18371855
* <p>
@@ -2558,6 +2576,10 @@ public ImageHandle(long handle, int zoom) {
25582576
setImageMetadataForHandle(this, zoom);
25592577
}
25602578

2579+
public Rectangle getBounds() {
2580+
return new Rectangle(0, 0, width, height);
2581+
}
2582+
25612583
private void setBackground(RGB color) {
25622584
if (transparentPixel == -1) return;
25632585

0 commit comments

Comments
 (0)