Skip to content

Commit 1b54d33

Browse files
HeikoKlareCopilot
andcommitted
[Win32] Replace magic GDI+ image arrays
Use a small record to carry the temporary GDI+ bitmap together with its optional heap-backed pixel buffer, and centralize cleanup at the value boundary. Also update Pattern cleanup to track bitmap ownership explicitly instead of relying on the returned array length. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 75a088f commit 1b54d33

3 files changed

Lines changed: 39 additions & 36 deletions

File tree

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

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,10 +1326,23 @@ void apply() {
13261326
}
13271327

13281328
private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, ImageHandle tempImageHandle) {
1329-
if (data.gdipGraphics != 0) {
1330-
//TODO - cache bitmap
1331-
long [] gdipImage = srcImage.createGdipImageFromHandle(tempImageHandle);
1332-
long img = gdipImage[0];
1329+
if (data.gdipGraphics == 0) {
1330+
switch (srcImage.type) {
1331+
case SWT.BITMAP:
1332+
drawBitmap(srcImage, tempImageHandle, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight,
1333+
simple);
1334+
break;
1335+
case SWT.ICON:
1336+
drawIcon(tempImageHandle.handle(), srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple);
1337+
break;
1338+
}
1339+
return;
1340+
}
1341+
1342+
//TODO - cache bitmap
1343+
Image.GdipImage gdipImage = srcImage.createGdipImageFromHandle(tempImageHandle);
1344+
try {
1345+
long img = gdipImage.bitmap();
13331346
int imgWidth = Gdip.Image_GetWidth(img);
13341347
int imgHeight = Gdip.Image_GetHeight(img);
13351348

@@ -1380,21 +1393,8 @@ private void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int src
13801393
Gdip.Graphics_Restore(data.gdipGraphics, gstate);
13811394
}
13821395
Gdip.ImageAttributes_delete(attrib);
1383-
Gdip.Bitmap_delete(img);
1384-
if (gdipImage[1] != 0) {
1385-
long hHeap = OS.GetProcessHeap ();
1386-
OS.HeapFree(hHeap, 0, gdipImage[1]);
1387-
}
1388-
return;
1389-
}
1390-
switch (srcImage.type) {
1391-
case SWT.BITMAP:
1392-
drawBitmap(srcImage, tempImageHandle, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight,
1393-
simple);
1394-
break;
1395-
case SWT.ICON:
1396-
drawIcon(tempImageHandle.handle(), srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple);
1397-
break;
1396+
} finally {
1397+
gdipImage.destroy();
13981398
}
13991399
}
14001400

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -969,15 +969,22 @@ public static void drawAtSize(GC gc, ImageData imageData, int width, int height)
969969
imageToDraw.dispose();
970970
});
971971
}
972+
record GdipImage(long bitmap, long pixels) {
973+
void destroy() {
974+
Gdip.Bitmap_delete(bitmap);
975+
if (pixels != 0) {
976+
long hHeap = OS.GetProcessHeap();
977+
OS.HeapFree(hHeap, 0, pixels);
978+
}
979+
}
980+
}
972981

973-
974-
975-
long [] createGdipImage(Integer zoom) {
982+
GdipImage createGdipImage(Integer zoom) {
976983
ImageHandle handle = this.getHandle(zoom, zoom);
977984
return createGdipImageFromHandle(handle);
978985
}
979986

980-
long[] createGdipImageFromHandle(ImageHandle imageHandle) {
987+
GdipImage createGdipImageFromHandle(ImageHandle imageHandle) {
981988
long handle = imageHandle.handle();
982989
int transparentPixel = imageHandle.transparentPixel();
983990
switch (type) {
@@ -1071,9 +1078,9 @@ long[] createGdipImageFromHandle(ImageHandle imageHandle) {
10711078
OS.DeleteObject(memHdc);
10721079
OS.DeleteObject(memDib);
10731080
int pixelFormat = hasAlpha ? Gdip.PixelFormat32bppPARGB : Gdip.PixelFormat32bppARGB;
1074-
return new long []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, pixelFormat, pixels), pixels};
1081+
return new GdipImage(Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, pixelFormat, pixels), pixels);
10751082
}
1076-
return new long []{Gdip.Bitmap_new(handle, 0), 0};
1083+
return new GdipImage(Gdip.Bitmap_new(handle, 0), 0);
10771084
}
10781085
case SWT.ICON: {
10791086
/*
@@ -1139,7 +1146,7 @@ long[] createGdipImageFromHandle(ImageHandle imageHandle) {
11391146
}
11401147
if (iconInfo.hbmColor != 0) OS.DeleteObject(iconInfo.hbmColor);
11411148
if (iconInfo.hbmMask != 0) OS.DeleteObject(iconInfo.hbmMask);
1142-
return new long []{img, pixels};
1149+
return new GdipImage(img, pixels);
11431150
}
11441151
default: SWT.error(SWT.ERROR_INVALID_IMAGE);
11451152
}

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

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import org.eclipse.swt.*;
1919
import org.eclipse.swt.internal.*;
2020
import org.eclipse.swt.internal.gdip.*;
21-
import org.eclipse.swt.internal.win32.*;
2221

2322
/**
2423
* Instances of this class represent patterns to use while drawing. Patterns
@@ -300,7 +299,7 @@ long createHandle(int zoom) {
300299
}
301300

302301
private class ImagePatternHandle extends PatternHandle {
303-
private long[] gdipImage;
302+
private Image.GdipImage gdipImage;
304303

305304
public ImagePatternHandle(int zoom) {
306305
super(zoom);
@@ -309,7 +308,7 @@ public ImagePatternHandle(int zoom) {
309308
@Override
310309
long createHandle(int zoom) {
311310
gdipImage = image.createGdipImage(zoom);
312-
long img = gdipImage[0];
311+
long img = gdipImage.bitmap();
313312
int width = Gdip.Image_GetWidth(img);
314313
int height = Gdip.Image_GetHeight(img);
315314
long handle = Gdip.TextureBrush_new(img, Gdip.WrapModeTile, 0, 0, width, height);
@@ -327,13 +326,10 @@ protected void destroy() {
327326
}
328327

329328
private void cleanupBitmap() {
330-
if (gdipImage.length < 2) return;
331-
long img = gdipImage[0];
332-
Gdip.Bitmap_delete(img);
333-
if (gdipImage[1] != 0) {
334-
long hHeap = OS.GetProcessHeap ();
335-
OS.HeapFree(hHeap, 0, gdipImage[1]);
336-
}
329+
if (gdipImage == null) return;
330+
Image.GdipImage tempGdipImage = gdipImage;
331+
gdipImage = null;
332+
tempGdipImage.destroy();
337333
}
338334
}
339335

0 commit comments

Comments
 (0)