Skip to content

Commit a07629a

Browse files
committed
[Win32] Simplify and clean up Pattern
- Rename isDestroyed field to disposed (conventional Java boolean field naming) - Move null/disposed checks for gradient colors into the constructor where they belong, per the existing Javadoc contract - Use computeIfAbsent in getPatternHandle, removing the redundant newPatternHandle helper method - Extract colorRefToArgb helper to replace duplicated COLORREF->ARGB bit-manipulation in BasePatternHandle - Remove >> 0 no-op shifts in the midColor calculation - Use enhanced switch (arrow form) in PatternHandle.destroy() - Remove misleading public modifier from private inner class constructors - Fix cleanupBitmap: remove dead array-length guard, null the field before freeing to prevent double-free on repeated destroy() calls
1 parent 9b0b255 commit a07629a

1 file changed

Lines changed: 34 additions & 42 deletions

File tree

  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

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

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class Pattern extends Resource {
4848

4949
private final Map<Integer, PatternHandle> zoomToHandle = new HashMap<>();
5050

51-
private boolean isDestroyed;
51+
private boolean disposed;
5252

5353
/**
5454
* Constructs a new Pattern given an image. Drawing with the resulting
@@ -168,6 +168,10 @@ public Pattern(Device device, float x1, float y1, float x2, float y2, Color colo
168168
*/
169169
public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
170170
super(device);
171+
if (color1 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
172+
if (color1.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
173+
if (color2 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
174+
if (color2.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
171175
this.baseX1 = x1;
172176
this.baseX2 = x2;
173177
this.baseY1 = y1;
@@ -181,18 +185,8 @@ public Pattern(Device device, float x1, float y1, float x2, float y2, Color colo
181185
this.device.registerResourceWithZoomSupport(this);
182186
}
183187

184-
private PatternHandle newPatternHandle(int zoom) {
185-
if (image != null) {
186-
return new ImagePatternHandle(zoom);
187-
}
188-
return new BasePatternHandle(zoom);
189-
}
190-
191188
private PatternHandle getPatternHandle(int zoom) {
192-
if (!zoomToHandle.containsKey(zoom)) {
193-
zoomToHandle.put(zoom, newPatternHandle(zoom));
194-
}
195-
return zoomToHandle.get(zoom);
189+
return zoomToHandle.computeIfAbsent(zoom, z -> image != null ? new ImagePatternHandle(z) : new BasePatternHandle(z));
196190
}
197191

198192
long getHandle(int zoom) {
@@ -204,7 +198,7 @@ void destroy() {
204198
device.deregisterResourceWithZoomSupport(this);
205199
zoomToHandle.values().forEach(PatternHandle::destroy);
206200
zoomToHandle.clear();
207-
this.isDestroyed = true;
201+
disposed = true;
208202
}
209203

210204
@Override
@@ -238,7 +232,7 @@ Pattern copy() {
238232
*/
239233
@Override
240234
public boolean isDisposed() {
241-
return isDestroyed;
235+
return disposed;
242236
}
243237

244238
/**
@@ -253,8 +247,16 @@ public String toString() {
253247
return "Pattern {" + zoomToHandle + "}";
254248
}
255249

250+
/**
251+
* Converts a Win32 COLORREF value (0x00BBGGRR) and an alpha byte into a
252+
* GDI+ ARGB color value (0xAARRGGBB).
253+
*/
254+
private static int colorRefToArgb(int colorRef, int alpha) {
255+
return ((alpha & 0xFF) << 24) | ((colorRef >> 16) & 0xFF) | (colorRef & 0xFF00) | ((colorRef & 0xFF) << 16);
256+
}
257+
256258
private class BasePatternHandle extends PatternHandle {
257-
public BasePatternHandle(int zoom) {
259+
BasePatternHandle(int zoom) {
258260
super(zoom);
259261
}
260262

@@ -265,19 +267,17 @@ long createHandle(int zoom) {
265267
float y1 = Win32DPIUtils.pointToPixel(baseY1, zoom);
266268
float x2 = Win32DPIUtils.pointToPixel(baseX2, zoom);
267269
float y2 = Win32DPIUtils.pointToPixel(baseY2, zoom);
268-
if (color1 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
269270
if (color1.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
270-
if (color2 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
271271
if (color2.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
272272
device.checkGDIP();
273273
int colorRef1 = color1.handle;
274-
int foreColor = ((alpha1 & 0xFF) << 24) | ((colorRef1 >> 16) & 0xFF) | (colorRef1 & 0xFF00) | ((colorRef1 & 0xFF) << 16);
274+
int foreColor = colorRefToArgb(colorRef1, alpha1);
275275
if (x1 == x2 && y1 == y2) {
276276
handle = Gdip.SolidBrush_new(foreColor);
277277
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
278278
} else {
279279
int colorRef2 = color2.handle;
280-
int backColor = ((alpha2 & 0xFF) << 24) | ((colorRef2 >> 16) & 0xFF) | (colorRef2 & 0xFF00) | ((colorRef2 & 0xFF) << 16);
280+
int backColor = colorRefToArgb(colorRef2, alpha2);
281281
PointF p1 = new PointF();
282282
p1.X = x1;
283283
p1.Y = y1;
@@ -288,7 +288,7 @@ long createHandle(int zoom) {
288288
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
289289
if (alpha1 != 0xFF || alpha2 != 0xFF) {
290290
int a = (int)((alpha1 & 0xFF) * 0.5f + (alpha2 & 0xFF) * 0.5f);
291-
int r = (int)(((colorRef1 & 0xFF) >> 0) * 0.5f + ((colorRef2 & 0xFF) >> 0) * 0.5f);
291+
int r = (int)((colorRef1 & 0xFF) * 0.5f + (colorRef2 & 0xFF) * 0.5f);
292292
int g = (int)(((colorRef1 & 0xFF00) >> 8) * 0.5f + ((colorRef2 & 0xFF00) >> 8) * 0.5f);
293293
int b = (int)(((colorRef1 & 0xFF0000) >> 16) * 0.5f + ((colorRef2 & 0xFF0000) >> 16) * 0.5f);
294294
int midColor = a << 24 | r << 16 | g << 8 | b;
@@ -302,7 +302,7 @@ long createHandle(int zoom) {
302302
private class ImagePatternHandle extends PatternHandle {
303303
private long[] gdipImage;
304304

305-
public ImagePatternHandle(int zoom) {
305+
ImagePatternHandle(int zoom) {
306306
super(zoom);
307307
}
308308

@@ -327,40 +327,32 @@ protected void destroy() {
327327
}
328328

329329
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]);
330+
if (gdipImage == null) return;
331+
long[] image = gdipImage;
332+
gdipImage = null;
333+
Gdip.Bitmap_delete(image[0]);
334+
if (image[1] != 0) {
335+
long hHeap = OS.GetProcessHeap();
336+
OS.HeapFree(hHeap, 0, image[1]);
336337
}
337338
}
338339
}
339340

340341
private abstract class PatternHandle {
341342
private final long handle;
342343

343-
public PatternHandle(int zoom) {
344+
PatternHandle(int zoom) {
344345
this.handle = createHandle(zoom);
345346
}
346347

347348
abstract long createHandle(int zoom);
348349

349350
protected void destroy() {
350-
int type = Gdip.Brush_GetType(handle);
351-
switch (type) {
352-
case Gdip.BrushTypeSolidColor:
353-
Gdip.SolidBrush_delete(handle);
354-
break;
355-
case Gdip.BrushTypeHatchFill:
356-
Gdip.HatchBrush_delete(handle);
357-
break;
358-
case Gdip.BrushTypeLinearGradient:
359-
Gdip.LinearGradientBrush_delete(handle);
360-
break;
361-
case Gdip.BrushTypeTextureFill:
362-
Gdip.TextureBrush_delete(handle);
363-
break;
351+
switch (Gdip.Brush_GetType(handle)) {
352+
case Gdip.BrushTypeSolidColor -> Gdip.SolidBrush_delete(handle);
353+
case Gdip.BrushTypeHatchFill -> Gdip.HatchBrush_delete(handle);
354+
case Gdip.BrushTypeLinearGradient -> Gdip.LinearGradientBrush_delete(handle);
355+
case Gdip.BrushTypeTextureFill -> Gdip.TextureBrush_delete(handle);
364356
}
365357
}
366358
}

0 commit comments

Comments
 (0)