Skip to content

Commit 52375f4

Browse files
committed
[win32] Introduce ZoomContext in Image
This commit extends the internal zoom used in Image in the windows implementation to a complex object. This is preparatory work to provide a consistent behavior independent of the auto scale mode, e.g. when an Image is drawn with a GC.
1 parent 032fa73 commit 52375f4

File tree

1 file changed

+67
-55
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+67
-55
lines changed

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

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -803,11 +803,12 @@ private ImageData applyGrayImageData(ImageData data, int pHeight, int pWidth) {
803803
return newData;
804804
}
805805

806-
private ImageHandle getImageMetadata(int zoom) {
806+
private ImageHandle getImageMetadata(ZoomContext zoomContext) {
807+
int zoom = zoomContext.targetZoom;
807808
if (zoomLevelToImageHandle.get(zoom) != null) {
808809
return zoomLevelToImageHandle.get(zoom);
809810
}
810-
return imageProvider.newImageHandle(zoom);
811+
return imageProvider.newImageHandle(zoomContext);
811812
}
812813

813814

@@ -828,10 +829,10 @@ private ImageHandle getImageMetadata(int zoom) {
828829
* @noreference This method is not intended to be referenced by clients.
829830
*/
830831
public static long win32_getHandle (Image image, int zoom) {
831-
if(image.isDisposed()) {
832+
if (image.isDisposed()) {
832833
return 0L;
833834
}
834-
return image.getImageMetadata(zoom).handle;
835+
return image.getImageMetadata(new ZoomContext(zoom)).handle;
835836
}
836837

837838
/**
@@ -1265,7 +1266,7 @@ public ImageData getImageData (int zoom) {
12651266
if (zoomLevelToImageHandle.containsKey(zoom)) {
12661267
return zoomLevelToImageHandle.get(zoom).getImageData();
12671268
}
1268-
return this.imageProvider.newImageData(zoom);
1269+
return this.imageProvider.newImageData(new ZoomContext(zoom));
12691270
}
12701271

12711272

@@ -1742,7 +1743,7 @@ public long internal_new_GC (GCData data) {
17421743
return this.imageProvider.configureGCData(data);
17431744
}
17441745

1745-
private long configureGC(GCData data, int zoom) {
1746+
private long configureGC(GCData data, ZoomContext zoomContext) {
17461747
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
17471748
/*
17481749
* Create a new GC that can draw into the image.
@@ -1753,7 +1754,7 @@ private long configureGC(GCData data, int zoom) {
17531754
}
17541755

17551756
if (Device.strictChecks) {
1756-
checkImageTypeForValidCustomDrawing(zoom);
1757+
checkImageTypeForValidCustomDrawing(zoomContext.targetZoom());
17571758
}
17581759
/* Create a compatible HDC for the device */
17591760
long hDC = device.internal_new_GC(null);
@@ -1770,9 +1771,9 @@ private long configureGC(GCData data, int zoom) {
17701771
data.style |= SWT.LEFT_TO_RIGHT;
17711772
}
17721773
data.device = device;
1773-
data.nativeZoom = zoom;
1774+
data.nativeZoom = zoomContext.nativeZoom();
17741775
data.image = this;
1775-
data.font = SWTFontProvider.getSystemFont(device, zoom);
1776+
data.font = SWTFontProvider.getSystemFont(device, zoomContext.nativeZoom());
17761777
}
17771778
return imageDC;
17781779
}
@@ -1882,7 +1883,7 @@ public String toString () {
18821883

18831884
<T> T applyUsingAnyHandle(Function<ImageHandle, T> function) {
18841885
if (zoomLevelToImageHandle.isEmpty()) {
1885-
ImageHandle temporaryHandle = this.imageProvider.newImageHandle(DPIUtil.getDeviceZoom());
1886+
ImageHandle temporaryHandle = this.imageProvider.newImageHandle(new ZoomContext(DPIUtil.getDeviceZoom(), DPIUtil.getNativeDeviceZoom()));
18861887
try {
18871888
return function.apply(temporaryHandle);
18881889
} finally {
@@ -1913,42 +1914,49 @@ public static Image win32_new(Device device, int type, long handle, int nativeZo
19131914
return new Image(device, type, handle, nativeZoom);
19141915
}
19151916

1917+
private record ZoomContext(int targetZoom, int nativeZoom) {
1918+
1919+
private ZoomContext(int targetZoom) {
1920+
this(targetZoom, targetZoom);
1921+
}
1922+
}
1923+
19161924
private abstract class AbstractImageProviderWrapper {
19171925

19181926
protected abstract Rectangle getBounds(int zoom);
19191927

19201928
protected long configureGCData(GCData data) {
1921-
return configureGC(data, 100);
1929+
return configureGC(data, new ZoomContext(100));
19221930
}
19231931

19241932
public Collection<Integer> getPreservedZoomLevels() {
19251933
return Collections.emptySet();
19261934
}
19271935

1928-
abstract ImageData newImageData(int zoom);
1936+
abstract ImageData newImageData(ZoomContext zoomContext);
19291937

19301938
abstract AbstractImageProviderWrapper createCopy(Image image);
19311939

19321940
ImageData getScaledImageData (int zoom) {
19331941
TreeSet<Integer> availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet());
19341942
int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom));
1935-
return DPIUtil.scaleImageData(device, getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
1943+
return DPIUtil.scaleImageData(device, getImageMetadata(new ZoomContext(closestZoom)).getImageData(), zoom, closestZoom);
19361944
}
19371945

1938-
protected ImageHandle newImageHandle(int zoom) {
1939-
ImageData resizedData = getImageData(zoom);
1940-
return newImageHandle(resizedData, zoom);
1946+
protected ImageHandle newImageHandle(ZoomContext zoomContext) {
1947+
ImageData resizedData = getImageData(zoomContext.targetZoom);
1948+
return newImageHandle(resizedData, zoomContext);
19411949
}
19421950

1943-
protected final ImageHandle newImageHandle(ImageData data, int zoom) {
1951+
protected final ImageHandle newImageHandle(ImageData data, ZoomContext zoomContext) {
19441952
if (type == SWT.ICON && data.getTransparencyType() != SWT.TRANSPARENCY_MASK) {
19451953
// If the original type was an icon with transparency mask and re-scaling leads
19461954
// to image data without transparency mask, this will create invalid images
19471955
// so this fallback will "repair" the image data by explicitly passing
19481956
// the transparency mask created from the scaled image data
1949-
return initIconHandle(device, data, data.getTransparencyMask(), zoom);
1957+
return initIconHandle(device, data, data.getTransparencyMask(), zoomContext.targetZoom);
19501958
} else {
1951-
return init(data, zoom);
1959+
return init(data, zoomContext.targetZoom);
19521960
}
19531961
}
19541962
}
@@ -1977,8 +1985,8 @@ protected Rectangle getBounds(int zoom) {
19771985
}
19781986

19791987
@Override
1980-
ImageData newImageData(int zoom) {
1981-
return getScaledImageData(zoom);
1988+
ImageData newImageData(ZoomContext zoomContext) {
1989+
return getScaledImageData(zoomContext.targetZoom);
19821990
}
19831991

19841992
@Override
@@ -2000,34 +2008,34 @@ private abstract class ImageFromImageDataProviderWrapper extends AbstractImagePr
20002008
void initImage() {
20012009
// As the init call configured some Image attributes (e.g. type)
20022010
// it must be called
2003-
newImageData(100);
2011+
newImageData(new ZoomContext(100));
20042012
}
20052013

20062014
@Override
2007-
ImageData newImageData(int zoom) {
2015+
ImageData newImageData(ZoomContext zoomContext) {
20082016
Function<Integer, ImageData> imageDataRetrieval = zoomToRetrieve -> {
2009-
ImageHandle handle = initializeHandleFromSource(zoomToRetrieve);
2017+
ImageHandle handle = initializeHandleFromSource(zoomContext);
20102018
ImageData data = handle.getImageData();
20112019
handle.destroy();
20122020
return data;
20132021
};
2014-
return cachedImageData.computeIfAbsent(zoom, imageDataRetrieval);
2022+
return cachedImageData.computeIfAbsent(zoomContext.targetZoom, imageDataRetrieval);
20152023
}
20162024

20172025
@Override
2018-
protected ImageHandle newImageHandle(int zoom) {
2019-
ImageData cachedData = cachedImageData.remove(zoom);
2026+
protected ImageHandle newImageHandle(ZoomContext zoomContext) {
2027+
ImageData cachedData = cachedImageData.remove(zoomContext.targetZoom);
20202028
if (cachedData != null) {
2021-
return newImageHandle(cachedData, zoom);
2029+
return newImageHandle(cachedData, zoomContext);
20222030
}
2023-
return initializeHandleFromSource(zoom);
2031+
return initializeHandleFromSource(zoomContext);
20242032
}
20252033

2026-
private ImageHandle initializeHandleFromSource(int zoom) {
2027-
ElementAtZoom<ImageData> imageDataAtZoom = loadImageData(zoom);
2028-
ImageData imageData = DPIUtil.scaleImageData(device, imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
2034+
private ImageHandle initializeHandleFromSource(ZoomContext zoomContext) {
2035+
ElementAtZoom<ImageData> imageDataAtZoom = loadImageData(zoomContext.targetZoom);
2036+
ImageData imageData = DPIUtil.scaleImageData(device, imageDataAtZoom.element(), zoomContext.targetZoom, imageDataAtZoom.zoom());
20292037
imageData = adaptImageDataIfDisabledOrGray(imageData);
2030-
return newImageHandle(imageData, zoom);
2038+
return newImageHandle(imageData, zoomContext);
20312039
}
20322040

20332041
}
@@ -2149,7 +2157,7 @@ public Collection<Integer> getPreservedZoomLevels() {
21492157

21502158
@Override
21512159
protected long configureGCData(GCData data) {
2152-
return configureGC(data, DPIUtil.getDeviceZoom());
2160+
return configureGC(data, new ZoomContext(DPIUtil.getDeviceZoom()));
21532161
}
21542162

21552163
@Override
@@ -2159,31 +2167,33 @@ protected Rectangle getBounds(int zoom) {
21592167
}
21602168

21612169
@Override
2162-
ImageData newImageData(int zoom) {
2170+
ImageData newImageData(ZoomContext zoomContext) {
2171+
int zoom = zoomContext.targetZoom;
21632172
if (zoomLevelToImageHandle.isEmpty()) {
21642173
return createBaseHandle(zoom).getImageData();
21652174
}
21662175
// if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
21672176
// be a destructive operation. Therefor, a new handle is created for the requested zoom
21682177
if (memGC != null) {
2169-
return newImageHandle(zoom).getImageData();
2178+
return newImageHandle(zoomContext).getImageData();
21702179
}
21712180
return getScaledImageData(zoom);
21722181
}
21732182

21742183
@Override
2175-
protected ImageHandle newImageHandle(int zoom) {
2184+
protected ImageHandle newImageHandle(ZoomContext zoomContext) {
2185+
int zoom = zoomContext.targetZoom;
21762186
if (zoomLevelToImageHandle.isEmpty()) {
21772187
return createBaseHandle(zoom);
21782188
}
21792189
if (memGC != null) {
21802190
GC currentGC = memGC;
21812191
memGC = null;
21822192
createHandle(zoom);
2183-
currentGC.refreshFor(new DrawableWrapper(Image.this, zoom), zoom);
2193+
currentGC.refreshFor(new DrawableWrapper(Image.this, zoomContext), zoom);
21842194
return zoomLevelToImageHandle.get(zoom);
21852195
}
2186-
return super.newImageHandle(zoom);
2196+
return super.newImageHandle(zoomContext);
21872197
}
21882198
private ImageHandle createBaseHandle(int zoom) {
21892199
baseZoom = zoom;
@@ -2272,19 +2282,20 @@ Object getProvider() {
22722282
}
22732283

22742284
@Override
2275-
ImageData newImageData(int zoom) {
2285+
ImageData newImageData(ZoomContext zoomContext) {
22762286
Function<Integer, ImageData> imageDataRetrival = zoomToRetrieve -> {
22772287
ImageHandle handle = initializeHandleFromSource(zoomToRetrieve);
22782288
ImageData data = handle.getImageData();
22792289
handle.destroy();
22802290
return data;
22812291
};
2282-
return cachedImageData.computeIfAbsent(zoom, imageDataRetrival);
2292+
return cachedImageData.computeIfAbsent(zoomContext.targetZoom, imageDataRetrival);
22832293
}
22842294

22852295

22862296
@Override
2287-
protected ImageHandle newImageHandle(int zoom) {
2297+
protected ImageHandle newImageHandle(ZoomContext zoomContext) {
2298+
int zoom = zoomContext.targetZoom;
22882299
ImageData cachedData = cachedImageData.remove(zoom);
22892300
if (cachedData != null) {
22902301
return init(cachedData, zoom);
@@ -2294,7 +2305,7 @@ protected ImageHandle newImageHandle(int zoom) {
22942305

22952306
private ImageHandle initializeHandleFromSource(int zoom) {
22962307
ElementAtZoom<ImageData> imageDataAtZoom = loadImageData(zoom);
2297-
ImageData imageData = DPIUtil.scaleImageData (device,imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
2308+
ImageData imageData = DPIUtil.scaleImageData (device, imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
22982309
imageData = adaptImageDataIfDisabledOrGray(imageData);
22992310
return init(imageData, zoom);
23002311
}
@@ -2313,7 +2324,7 @@ private class ImageFileNameProviderWrapper extends BaseImageProviderWrapper<Imag
23132324
super(provider, ImageFileNameProvider.class);
23142325
// Checks for the contract of the passed provider require
23152326
// checking for valid image data creation
2316-
newImageData(DPIUtil.getDeviceZoom());
2327+
newImageData(new ZoomContext(DPIUtil.getDeviceZoom()));
23172328
}
23182329

23192330
@Override
@@ -2567,7 +2578,7 @@ private class ImageGcDrawerWrapper extends DynamicImageProviderWrapper {
25672578
private ImageGcDrawer drawer;
25682579
private int width;
25692580
private int height;
2570-
private int currentZoom = 100;
2581+
private ZoomContext currentZoom = new ZoomContext(100);
25712582

25722583
ImageGcDrawerWrapper(ImageGcDrawer imageGcDrawer, int width, int height) {
25732584
checkProvider(imageGcDrawer, ImageGcDrawer.class);
@@ -2588,13 +2599,14 @@ protected long configureGCData(GCData data) {
25882599
}
25892600

25902601
@Override
2591-
ImageData newImageData(int zoom) {
2592-
return getImageMetadata(zoom).getImageData();
2602+
ImageData newImageData(ZoomContext zoomContext) {
2603+
return getImageMetadata(zoomContext).getImageData();
25932604
}
25942605

25952606
@Override
2596-
protected ImageHandle newImageHandle(int zoom) {
2597-
currentZoom = zoom;
2607+
protected ImageHandle newImageHandle(ZoomContext zoomContext) {
2608+
currentZoom = zoomContext;
2609+
int zoom = zoomContext.targetZoom;
25982610
int gcStyle = drawer.getGcStyle();
25992611
Image image;
26002612
if ((gcStyle & SWT.TRANSPARENT) != 0) {
@@ -2607,10 +2619,10 @@ protected ImageHandle newImageHandle(int zoom) {
26072619
} else {
26082620
image = new Image(device, width, height);
26092621
}
2610-
GC gc = new GC(new DrawableWrapper(image, zoom), gcStyle);
2622+
GC gc = new GC(new DrawableWrapper(image, zoomContext), gcStyle);
26112623
try {
26122624
drawer.drawOn(gc, width, height);
2613-
ImageData imageData = image.getImageMetadata(zoom).getImageData();
2625+
ImageData imageData = image.getImageData(zoom);
26142626
drawer.postProcess(imageData);
26152627
ImageData newData = adaptImageDataIfDisabledOrGray(imageData);
26162628
return init(newData, zoom);
@@ -2644,16 +2656,16 @@ public boolean equals(Object otherProvider) {
26442656

26452657
private static class DrawableWrapper implements Drawable {
26462658
private final Image image;
2647-
private final int zoom;
2659+
private final ZoomContext zoomContext;
26482660

2649-
public DrawableWrapper(Image image, int zoom) {
2661+
public DrawableWrapper(Image image, ZoomContext zoomContext) {
26502662
this.image = image;
2651-
this.zoom = zoom;
2663+
this.zoomContext = zoomContext;
26522664
}
26532665

26542666
@Override
26552667
public long internal_new_GC(GCData data) {
2656-
return this.image.configureGC(data, zoom);
2668+
return this.image.configureGC(data, zoomContext);
26572669
}
26582670

26592671
@Override

0 commit comments

Comments
 (0)