Skip to content

Refactor Image for Readability #1667

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.eclipse.swt.internal.DPIUtil.*;
import org.eclipse.swt.internal.gdip.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.widgets.*;

/**
* Instances of this class are graphics which have been prepared
Expand Down Expand Up @@ -101,14 +100,9 @@ public final class Image extends Resource implements Drawable {
GC memGC;

/**
* ImageFileNameProvider to provide file names at various Zoom levels
*/
private ImageFileNameProvider imageFileNameProvider;

/**
* ImageDataProvider to provide ImageData at various Zoom levels
* AbstractImageProvider to avail right ImageProvider (ImageDataProvider or ImageFileNameProvider)
*/
private ImageDataProvider imageDataProvider;
private AbstractImageProviderWrapper imageProvider;

/**
* Style flag used to differentiate normal, gray-scale and disabled images based
Expand Down Expand Up @@ -228,8 +222,9 @@ public Image(Device device, Image srcImage, int flag) {
if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
Rectangle rect = srcImage.getBoundsInPixels();
this.type = srcImage.type;
this.imageDataProvider = srcImage.imageDataProvider;
this.imageFileNameProvider = srcImage.imageFileNameProvider;
if(srcImage.imageProvider != null) {
this.imageProvider = srcImage.imageProvider.createCopy(this);
}
this.styleFlag = srcImage.styleFlag | flag;
initialNativeZoom = srcImage.initialNativeZoom;
long srcImageHandle = win32_getHandle(srcImage, getZoom());
Expand Down Expand Up @@ -547,7 +542,7 @@ public Image (Device device, String filename) {
*/
public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
super(device);
this.imageFileNameProvider = imageFileNameProvider;
this.imageProvider = new ImageFileNameProviderWrapper(imageFileNameProvider);
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, getZoom());
if (fileName.zoom() == getZoom()) {
Expand Down Expand Up @@ -594,7 +589,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
*/
public Image(Device device, ImageDataProvider imageDataProvider) {
super(device);
this.imageDataProvider = imageDataProvider;
this.imageProvider = new ImageDataProviderWrapper(imageDataProvider);
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom(imageDataProvider, getZoom());
ImageData resizedData = DPIUtil.scaleImageData(device, data.element(), getZoom(), data.zoom());
Expand Down Expand Up @@ -750,26 +745,8 @@ private ImageHandle getImageMetadata(int zoom) {
if (zoomLevelToImageHandle.get(zoom) != null) {
return zoomLevelToImageHandle.get(zoom);
}

if (imageFileNameProvider != null) {
ElementAtZoom<String> imageCandidate = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, zoom);
ImageData imageData = new ImageData (imageCandidate.element());
if (imageCandidate.zoom() == zoom) {
/* Release current native resources */
ImageHandle imageMetadata = initNative(imageCandidate.element(), zoom);
if (imageMetadata == null) init(imageData, zoom);
init();
} else {
ImageData resizedData = DPIUtil.scaleImageData(device, imageData, zoom, imageCandidate.zoom());
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
init(newData, zoom);
}
} else if (imageDataProvider != null) {
ElementAtZoom<ImageData> imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom);
ImageData resizedData = DPIUtil.scaleImageData (device, imageCandidate.element(), zoom, imageCandidate.zoom());
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
init(newData, zoom);
init();
if (imageProvider != null) {
return imageProvider.getImageMetadata(zoom);
} else {
ImageData resizedData = getImageData(zoom);
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
Expand Down Expand Up @@ -1208,10 +1185,8 @@ public boolean equals (Object object) {
if (!(object instanceof Image)) return false;
Image image = (Image) object;
if (device != image.device || transparentPixel != image.transparentPixel || getZoom() != image.getZoom()) return false;
if (imageDataProvider != null && image.imageDataProvider != null) {
return (styleFlag == image.styleFlag) && imageDataProvider.equals (image.imageDataProvider);
} else if (imageFileNameProvider != null && image.imageFileNameProvider != null) {
return (styleFlag == image.styleFlag) && imageFileNameProvider.equals (image.imageFileNameProvider);
if (imageProvider != null && image.imageProvider != null) {
return (styleFlag == image.styleFlag) && imageProvider.equals(image.imageProvider);
} else {
return win32_getHandle(this, getZoom()) == win32_getHandle(image, getZoom());
}
Expand Down Expand Up @@ -1387,15 +1362,8 @@ public ImageData getImageData (int zoom) {
int currentZoom = getZoom();
if (zoom == currentZoom) {
return getImageDataAtCurrentZoom();
} else if (imageDataProvider != null) {
ElementAtZoom<ImageData> data;
try (StaticZoomUpdater unused = new StaticZoomUpdater(zoom)) {
data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom);
}
return DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom());
} else if (imageFileNameProvider != null) {
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, zoom);
return DPIUtil.scaleImageData (device, new ImageData (fileName.element()), zoom, fileName.zoom());
} else if (imageProvider != null) {
return imageProvider.getImageData(zoom);
}

// if a GC is initialized with an Image (memGC != null), the image data must not be resized, because it would
Expand Down Expand Up @@ -1442,13 +1410,10 @@ public ImageData getImageDataAtCurrentZoom() {
*/
@Override
public int hashCode () {
if (imageDataProvider != null) {
return imageDataProvider.hashCode();
} else if (imageFileNameProvider != null) {
return Objects.hash(imageFileNameProvider, styleFlag, transparentPixel, getZoom());
} else {
return (int)win32_getHandle(this, getZoom());
if(imageProvider != null) {
return imageProvider.hashCode();
}
return (int)win32_getHandle(this, getZoom());
}

void init(int width, int height) {
Expand Down Expand Up @@ -2070,24 +2035,109 @@ public static Image win32_new(Device device, int type, long handle) {
return image;
}

// This class is only used for a workaround and will be removed again
private class StaticZoomUpdater implements AutoCloseable {
private final boolean updateStaticZoom;
private final int currentNativeDeviceZoom;
private abstract class AbstractImageProviderWrapper {
abstract Object getProvider();
abstract ImageData getImageData(int zoom);
abstract ImageHandle getImageMetadata(int zoom);
abstract AbstractImageProviderWrapper createCopy(Image image);

private StaticZoomUpdater(int targetZoom) {
this.currentNativeDeviceZoom = DPIUtil.getNativeDeviceZoom();
this.updateStaticZoom = this.currentNativeDeviceZoom != targetZoom && device instanceof Display display && display.isRescalingAtRuntime();
if (updateStaticZoom) {
DPIUtil.setDeviceZoom(targetZoom);
}
@Override
public int hashCode() {
return getProvider().hashCode();
}

@Override
public boolean equals(Object otherProvider) {
return otherProvider instanceof AbstractImageProviderWrapper aip //
&& getProvider().equals(aip.getProvider());
}
}

private class ImageFileNameProviderWrapper extends AbstractImageProviderWrapper {

/**
* ImageFileNameProvider to provide file names at various Zoom levels
*/
private final ImageFileNameProvider provider;

ImageFileNameProviderWrapper(ImageFileNameProvider provider) {
this.provider = Objects.requireNonNull(provider);
}

@Override
public void close() {
if (updateStaticZoom) {
DPIUtil.setDeviceZoom(currentNativeDeviceZoom);
ImageData getImageData(int zoom) {
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (provider, zoom);
return DPIUtil.scaleImageData (device, new ImageData (fileName.element()), zoom, fileName.zoom());
}

@Override
ImageHandle getImageMetadata(int zoom) {
ElementAtZoom<String> imageCandidate = DPIUtil.validateAndGetImagePathAtZoom (provider, zoom);
ImageData imageData = new ImageData (imageCandidate.element());
if (imageCandidate.zoom() == zoom) {
/* Release current native resources */
ImageHandle imageMetadata = initNative(imageCandidate.element(), zoom);
if (imageMetadata == null) init(imageData, zoom);
init();
} else {
ImageData resizedData = DPIUtil.scaleImageData(device, imageData, zoom, imageCandidate.zoom());
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
init(newData, zoom);
}
return zoomLevelToImageHandle.get(zoom);
}

@Override
Object getProvider() {
return provider;
}

@Override
public int hashCode() {
return Objects.hash(provider, styleFlag, transparentPixel, getZoom());
}

@Override
ImageFileNameProviderWrapper createCopy(Image image) {
return image.new ImageFileNameProviderWrapper(provider);
}
}

private class ImageDataProviderWrapper extends AbstractImageProviderWrapper {

/**
* ImageDataProvider to provide ImageData at various Zoom levels
*/
private final ImageDataProvider provider;

ImageDataProviderWrapper(ImageDataProvider provider) {
this.provider = Objects.requireNonNull(provider);
}

@Override
ImageData getImageData(int zoom) {
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (provider, zoom);
return DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom());
}

@Override
ImageHandle getImageMetadata(int zoom) {
ElementAtZoom<ImageData> imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (provider, zoom);
ImageData resizedData = DPIUtil.scaleImageData (device, imageCandidate.element(), zoom, imageCandidate.zoom());
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
init(newData, zoom);
init();
return zoomLevelToImageHandle.get(zoom);
}

@Override
Object getProvider() {
return provider;
}

@Override
ImageDataProviderWrapper createCopy(Image image) {
return image.new ImageDataProviderWrapper(provider);
}
}

Expand Down
Loading