Skip to content

Commit fb7e37d

Browse files
committed
[Win32] Replace ImageHandle class hierarchy with interfaces
To ensure proper restricted access to specific functionality of Image's internal ImageHandle class, a hierarchy of classes with different visibilities is currently used. To better express that there is just a single type to instantiate and that access restriction is supposed to be done by only providing specific methods to specific consumers, this change replaces the existing class hierarchy with a single implementation class and a conversion of the existing other classes with interfaces. It also further restricts access to several methods of ImageHandle (zoom(), bounds(), isDisposed()) that are not required to be public.
1 parent 9602bf0 commit fb7e37d

File tree

1 file changed

+66
-45
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+66
-45
lines changed

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

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public String toString() {
201201
}
202202

203203
private class HandleAtSize {
204-
private ImageHandle handleContainer = null;
204+
private InternalImageHandle handleContainer = null;
205205
private DestroyableImageHandle temporaryHandleContainer = null;
206206
private int requestedWidth = -1;
207207
private int requestedHeight = -1;
@@ -235,7 +235,7 @@ private boolean isReusable(int width, int height) {
235235
|| (handleContainer.height() == height && handleContainer.height() == width);
236236
}
237237

238-
private Optional<ImageHandle> createHandleAtExactSize(int width, int height) {
238+
private Optional<InternalImageHandle> createHandleAtExactSize(int width, int height) {
239239
Optional<ImageData> imageData = imageProvider.loadImageDataAtExactSize(width, height);
240240
if (imageData.isPresent()) {
241241
ImageData adaptedData = adaptImageDataIfDisabledOrGray(imageData.get());
@@ -245,12 +245,12 @@ private Optional<ImageHandle> createHandleAtExactSize(int width, int height) {
245245
return Optional.empty();
246246
}
247247

248-
private ImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, int heightHint) {
248+
private InternalImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, int heightHint) {
249249
Rectangle bounds = getBounds(100);
250250
int imageZoomForWidth = 100 * widthHint / bounds.width;
251251
int imageZoomForHeight = 100 * heightHint / bounds.height;
252252
int imageZoom = DPIUtil.getZoomForAutoscaleProperty(Math.max(imageZoomForWidth, imageZoomForHeight));
253-
ImageHandle bestFittingHandle = imageHandleManager.get(imageZoom);
253+
InternalImageHandle bestFittingHandle = imageHandleManager.get(imageZoom);
254254
if (bestFittingHandle == null) {
255255
ImageData bestFittingImageData = imageProvider.loadImageData(imageZoom).element();
256256
ImageData adaptedData = adaptImageDataIfDisabledOrGray(bestFittingImageData);
@@ -362,7 +362,7 @@ public Image(Device device, Image srcImage, int flag) {
362362
case SWT.IMAGE_COPY: {
363363
switch (type) {
364364
case SWT.BITMAP:
365-
for (ImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
365+
for (InternalImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
366366
Rectangle rect = imageHandle.bounds();
367367
long srcImageHandle = imageHandle.handle();
368368
/* Get the HDC for the device */
@@ -379,8 +379,8 @@ public Image(Device device, Image srcImage, int flag) {
379379
OS.CreateCompatibleBitmap(hdcSource, rect.width,
380380
bm.bmBits != 0 ? -rect.height : rect.height),
381381
imageHandle.zoom(), imageHandle.transparentPixel()));
382-
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
383-
long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle);
382+
if (imageMetadata.handle() == 0) SWT.error(SWT.ERROR_NO_HANDLES);
383+
long hOldDest = OS.SelectObject(hdcDest, imageMetadata.handle());
384384
OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY);
385385
OS.SelectObject(hdcSource, hOldSrc);
386386
OS.SelectObject(hdcDest, hOldDest);
@@ -392,13 +392,13 @@ public Image(Device device, Image srcImage, int flag) {
392392
}
393393
break;
394394
case SWT.ICON:
395-
for (ImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
395+
for (InternalImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
396396
Rectangle rect = imageHandle.bounds();
397397
imageMetadata = imageHandleManager.getOrCreate(imageHandle.zoom(),
398398
() -> new DestroyableImageHandle(
399399
OS.CopyImage(imageHandle.handle(), OS.IMAGE_ICON, rect.width, rect.height, 0),
400400
imageHandle.zoom(), imageHandle.transparentPixel()));
401-
if (imageMetadata.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
401+
if (imageMetadata.handle() == 0) SWT.error(SWT.ERROR_NO_HANDLES);
402402
}
403403
break;
404404
default:
@@ -407,7 +407,7 @@ public Image(Device device, Image srcImage, int flag) {
407407
break;
408408
}
409409
case SWT.IMAGE_DISABLE: {
410-
for (ImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
410+
for (InternalImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
411411
Rectangle rect = imageHandle.bounds();
412412
ImageData data = srcImage.getImageData(imageHandle.zoom());
413413
ImageData newData = applyDisableImageData(data, rect.height, rect.width);
@@ -416,7 +416,7 @@ public Image(Device device, Image srcImage, int flag) {
416416
break;
417417
}
418418
case SWT.IMAGE_GRAY: {
419-
for (ImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
419+
for (InternalImageHandle imageHandle : srcImage.imageHandleManager.getAllImageHandles()) {
420420
Rectangle rect = imageHandle.bounds();
421421
ImageData data = srcImage.getImageData(imageHandle.zoom());
422422
ImageData newData = applyGrayImageData(data, rect.height, rect.width);
@@ -1305,7 +1305,7 @@ public Rectangle getBounds() {
13051305
Rectangle getBounds(int zoom) {
13061306
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
13071307
if (imageHandleManager.contains(zoom)) {
1308-
ImageHandle imageMetadata = imageHandleManager.get(zoom);
1308+
InternalImageHandle imageMetadata = imageHandleManager.get(zoom);
13091309
Rectangle rectangle = new Rectangle(0, 0, imageMetadata.width(), imageMetadata.height());
13101310
return Win32DPIUtils.scaleBounds(rectangle, zoom, imageMetadata.zoom());
13111311
}
@@ -1329,7 +1329,7 @@ Rectangle getBounds(int zoom) {
13291329
*/
13301330
@Deprecated(since = "2025-09", forRemoval = true)
13311331
public Rectangle getBoundsInPixels() {
1332-
return applyUsingAnyHandle(ImageHandle::bounds);
1332+
return applyUsingAnyHandle(InternalImageHandle::bounds);
13331333
}
13341334

13351335
/**
@@ -2863,57 +2863,93 @@ public void internal_dispose_GC(long handle, GCData data) {
28632863
}
28642864
}
28652865

2866-
abstract class ImageHandle {
2866+
interface ImageHandle {
2867+
long handle();
2868+
2869+
int width();
2870+
2871+
int height();
2872+
2873+
int transparentPixel();
2874+
2875+
int transparentColor();
2876+
2877+
void setTransparentColor(int transparentColor);
2878+
}
2879+
2880+
private interface InternalImageHandle extends ImageHandle {
2881+
int zoom();
2882+
2883+
Rectangle bounds();
2884+
2885+
void setBackground(RGB rgb);
2886+
2887+
ImageData getImageData();
2888+
2889+
boolean isDisposed();
2890+
}
2891+
2892+
private class DestroyableImageHandle implements InternalImageHandle {
28672893
private final long handle;
28682894
private final int zoom;
28692895
private final int height;
28702896
private final int width;
28712897
private final int transparentPixel;
28722898
private int transparentColor = -1;
2899+
private boolean isDisposed;
28732900

2874-
ImageHandle(long handle, int zoom, int transparentPixel) {
2901+
DestroyableImageHandle(long handle, int zoom, int transparentPixel) {
28752902
this.handle = handle;
28762903
this.zoom = zoom;
28772904
Point bounds = getBoundsInPixelsFromNative();
28782905
this.width = bounds.x;
28792906
this.height = bounds.y;
28802907
this.transparentPixel = transparentPixel;
2908+
if (backgroundColor != null) {
2909+
setBackground(backgroundColor);
2910+
}
28812911
}
28822912

2883-
long handle() {
2913+
@Override
2914+
public long handle() {
28842915
return isDisposed() ? 0 : handle;
28852916
}
28862917

2887-
int width() {
2918+
@Override
2919+
public int width() {
28882920
return width;
28892921
}
28902922

2891-
int height() {
2923+
@Override
2924+
public int height() {
28922925
return height;
28932926
}
28942927

2895-
Rectangle bounds() {
2928+
@Override
2929+
public Rectangle bounds() {
28962930
return new Rectangle(0, 0, width, height);
28972931
}
28982932

2899-
int zoom() {
2933+
@Override
2934+
public int zoom() {
29002935
return zoom;
29012936
}
29022937

2903-
int transparentPixel() {
2938+
@Override
2939+
public int transparentPixel() {
29042940
return transparentPixel;
29052941
}
29062942

2907-
int transparentColor() {
2943+
@Override
2944+
public int transparentColor() {
29082945
return transparentColor;
29092946
}
29102947

2911-
void setTransparentColor(int transparentColor) {
2948+
@Override
2949+
public void setTransparentColor(int transparentColor) {
29122950
this.transparentColor = transparentColor;
29132951
}
29142952

2915-
abstract boolean isDisposed();
2916-
29172953
private Point getBoundsInPixelsFromNative() {
29182954
switch (type) {
29192955
case SWT.BITMAP:
@@ -2936,17 +2972,10 @@ private Point getBoundsInPixelsFromNative() {
29362972
return null;
29372973
}
29382974
}
2939-
}
29402975

2941-
private abstract class InternalImageHandle extends ImageHandle {
2942-
InternalImageHandle(long handle, int zoom, int transparentPixel) {
2943-
super(handle, zoom, transparentPixel);
2944-
if (backgroundColor != null) {
2945-
setBackground(backgroundColor);
2946-
}
2947-
}
29482976

2949-
void setBackground(RGB color) {
2977+
@Override
2978+
public void setBackground(RGB color) {
29502979
if (transparentPixel() == -1) return;
29512980

29522981
/* Get the HDC for the device */
@@ -2971,7 +3000,8 @@ void setBackground(RGB color) {
29713000
device.internal_dispose_GC(hDC, null);
29723001
}
29733002

2974-
ImageData getImageData() {
3003+
@Override
3004+
public ImageData getImageData() {
29753005
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
29763006
BITMAP bm;
29773007
int depth, width, height;
@@ -3246,17 +3276,9 @@ ImageData getImageData() {
32463276
return null;
32473277
}
32483278
}
3249-
}
3250-
3251-
private class DestroyableImageHandle extends InternalImageHandle {
3252-
private boolean isDisposed;
3253-
3254-
DestroyableImageHandle(long handle, int zoom, int transparentPixel) {
3255-
super(handle, zoom, transparentPixel);
3256-
}
32573279

32583280
@Override
3259-
boolean isDisposed() {
3281+
public boolean isDisposed() {
32603282
return isDisposed;
32613283
}
32623284

@@ -3270,5 +3292,4 @@ void destroy() {
32703292
}
32713293
}
32723294

3273-
32743295
}

0 commit comments

Comments
 (0)