Skip to content

Commit

Permalink
Store nativeDeviceZoom in widgets instead of zoom for win32
Browse files Browse the repository at this point in the history
This contribution is to provide the nativeDeviceZoom to all the widgets
so that it can be used later on for e.g. font scaling and more.
Currently, the nativeDeviceZoom is only available via the shell, which
is not sufficient later when there is no shell available, e.g. GC.

Contributes to eclipse-platform#62 and eclipse-platform#127
  • Loading branch information
amartya4256 committed May 29, 2024
1 parent d3df796 commit d2d6655
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHei

void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
/* Refresh Image as per zoom level, if required. */
srcImage.handleDPIChange(DPIUtil.getDeviceZoom());
srcImage.handleDPIChange(DPIUtil.getNativeDeviceZoom());
if (data.gdipGraphics != 0) {
//TODO - cache bitmap
long [] gdipImage = srcImage.createGdipImage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ public final class Image extends Resource implements Drawable {
private int styleFlag = SWT.IMAGE_COPY;

/**
* Attribute to cache current device zoom level
* Attribute to cache current native zoom level
*/
private int currentDeviceZoom = 100;
private int currentNativeZoom = 100;

/**
* width of the image
Expand All @@ -161,7 +161,7 @@ public final class Image extends Resource implements Drawable {
*/
Image (Device device) {
super(device);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
}

/**
Expand Down Expand Up @@ -201,7 +201,7 @@ public final class Image extends Resource implements Drawable {
*/
public Image(Device device, int width, int height) {
super(device);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
width = DPIUtil.autoScaleUp (width);
height = DPIUtil.autoScaleUp (height);
init(width, height);
Expand Down Expand Up @@ -254,7 +254,7 @@ public Image(Device device, Image srcImage, int flag) {
this.imageDataProvider = srcImage.imageDataProvider;
this.imageFileNameProvider = srcImage.imageFileNameProvider;
this.styleFlag = srcImage.styleFlag | flag;
this.currentDeviceZoom = srcImage.currentDeviceZoom;
currentNativeZoom = srcImage.currentNativeZoom;
this.dataAtBaseZoom = srcImage.dataAtBaseZoom;
switch (flag) {
case SWT.IMAGE_COPY: {
Expand Down Expand Up @@ -293,7 +293,7 @@ public Image(Device device, Image srcImage, int flag) {
break;
}
case SWT.IMAGE_DISABLE: {
ImageData data = srcImage.getImageData(srcImage.currentDeviceZoom);
ImageData data = srcImage.getImageData(srcImage.getZoom());
PaletteData palette = data.palette;
RGB[] rgbs = new RGB[3];
rgbs[0] = device.getSystemColor(SWT.COLOR_BLACK).getRGB();
Expand Down Expand Up @@ -352,7 +352,7 @@ public Image(Device device, Image srcImage, int flag) {
break;
}
case SWT.IMAGE_GRAY: {
ImageData data = srcImage.getImageData(srcImage.currentDeviceZoom);
ImageData data = srcImage.getImageData(srcImage.getZoom());
PaletteData palette = data.palette;
ImageData newData = data;
if (!palette.isDirect) {
Expand Down Expand Up @@ -459,7 +459,7 @@ public Image(Device device, Image srcImage, int flag) {
public Image(Device device, Rectangle bounds) {
super(device);
if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
bounds = DPIUtil.autoScaleUp (bounds);
init(bounds.width, bounds.height);
init();
Expand Down Expand Up @@ -491,7 +491,7 @@ public Image(Device device, Rectangle bounds) {
public Image(Device device, ImageData data) {
super(device);
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
this.dataAtBaseZoom = new ElementAtZoom<>(data, 100);
data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data);
Expand Down Expand Up @@ -535,7 +535,7 @@ public Image(Device device, ImageData source, ImageData mask) {
if (source.width != mask.width || source.height != mask.height) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
this.dataAtBaseZoom = new ElementAtZoom<>(applyMask(source, ImageData.convertMask(mask)), 100);
source = DPIUtil.autoScaleUp(device, source);
mask = DPIUtil.autoScaleUp(device, mask);
Expand Down Expand Up @@ -599,7 +599,7 @@ public Image(Device device, ImageData source, ImageData mask) {
*/
public Image (Device device, InputStream stream) {
super(device);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
this.dataAtBaseZoom = new ElementAtZoom<>(new ImageData (stream), 100);
ImageData data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data);
Expand Down Expand Up @@ -641,7 +641,7 @@ public Image (Device device, InputStream stream) {
public Image (Device device, String filename) {
super(device);
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
this.dataAtBaseZoom = new ElementAtZoom<>(new ImageData (filename), 100);
ImageData data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data);
Expand Down Expand Up @@ -680,9 +680,9 @@ public Image (Device device, String filename) {
public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
super(device);
this.imageFileNameProvider = imageFileNameProvider;
currentDeviceZoom = DPIUtil.getDeviceZoom ();
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, currentDeviceZoom);
if (fileName.zoom() == currentDeviceZoom) {
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, getZoom());
if (fileName.zoom() == getZoom()) {
initNative (fileName.element());
if (this.handle == 0) init(new ImageData (fileName.element()));
} else {
Expand Down Expand Up @@ -724,26 +724,28 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
public Image(Device device, ImageDataProvider imageDataProvider) {
super(device);
this.imageDataProvider = imageDataProvider;
currentDeviceZoom = DPIUtil.getDeviceZoom ();
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom(imageDataProvider, currentDeviceZoom);
currentNativeZoom = DPIUtil.getNativeDeviceZoom();
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom(imageDataProvider, getZoom());
ImageData resizedData = DPIUtil.autoScaleImageData(device, data.element(), data.zoom());
init (resizedData);
init();
}

/**
* Update zoom and refresh the Image based on the zoom level, if required.
* Update zoom and refresh the Image based on the native zoom level, if required.
*
* @param deviceZoom zoom in % of the standard resolution the image shall be scaled for
* @param nativeZoom native zoom in % of the monitor on which the image is painted
*
* @return true if image is refreshed
*/
boolean handleDPIChange (int deviceZoom) {
boolean handleDPIChange (int nativeZoom) {
int newZoom = DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
int oldZoom = this.getZoom();
boolean refreshed = false;
if (imageFileNameProvider != null) {
if (deviceZoom != currentDeviceZoom) {
ElementAtZoom<String> filename = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, deviceZoom);
if (filename.zoom() == deviceZoom) {
if (newZoom != oldZoom) {
ElementAtZoom<String> filename = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, newZoom);
if (filename.zoom() == newZoom) {
/* Release current native resources */
destroy ();
initNative(filename.element());
Expand All @@ -758,27 +760,27 @@ boolean handleDPIChange (int deviceZoom) {
init ();
refreshed = true;
}
setCurrentDeviceZoom(deviceZoom);
setCurrentNativeZoom(nativeZoom);
}
} else if (imageDataProvider != null) {
if (deviceZoom != currentDeviceZoom) {
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, deviceZoom);
if (newZoom != oldZoom) {
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, newZoom);
/* Release current native resources */
destroy ();
ImageData resizedData = DPIUtil.autoScaleImageData (device, data.element(), data.zoom());
init(resizedData);
init();
refreshed = true;
setCurrentDeviceZoom(deviceZoom);
setCurrentNativeZoom(nativeZoom);
}
} else if (this.dataAtBaseZoom != null) { // Resizing is only possible with a cached base image
if (deviceZoom != currentDeviceZoom) {
ImageData resizedData = getImageData(deviceZoom);
if (newZoom != oldZoom) {
ImageData resizedData = getImageData(newZoom);
destroy ();
init(resizedData);
init();
refreshed = true;
setCurrentDeviceZoom(deviceZoom);
setCurrentNativeZoom(nativeZoom);
}
}
return refreshed;
Expand Down Expand Up @@ -1146,7 +1148,7 @@ public boolean equals (Object object) {
if (object == this) return true;
if (!(object instanceof Image)) return false;
Image image = (Image) object;
if (device != image.device || transparentPixel != image.transparentPixel || currentDeviceZoom != image.currentDeviceZoom) return false;
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) {
Expand Down Expand Up @@ -1243,8 +1245,8 @@ Rectangle getBounds(int zoom) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
// Read the bounds in pixels from native layer.
Rectangle bounds = getBoundsInPixelsFromNative();
if (bounds != null && zoom != currentDeviceZoom) {
bounds = DPIUtil.autoScaleBounds(bounds, zoom, currentDeviceZoom);
if (bounds != null && zoom != getZoom()) {
bounds = DPIUtil.autoScaleBounds(bounds, zoom, getZoom());
}
return bounds;
}
Expand Down Expand Up @@ -1347,8 +1349,8 @@ public ImageData getImageData() {
*/
public ImageData getImageData (int zoom) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);

if (zoom == currentDeviceZoom) {
int currentZoom = getZoom();
if (zoom == currentZoom) {
return getImageDataAtCurrentZoom();
} else if (imageDataProvider != null) {
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom);
Expand All @@ -1365,12 +1367,12 @@ public ImageData getImageData (int zoom) {
}
if (this.dataAtBaseZoom == null) {
// Cache data at base zoom before resizing it.
this.dataAtBaseZoom = new ElementAtZoom<>(getImageData(this.currentDeviceZoom), this.currentDeviceZoom);
this.dataAtBaseZoom = new ElementAtZoom<>(getImageData(currentZoom), currentZoom);
}
if (this.dataAtBaseZoom != null) {
return DPIUtil.autoScaleImageData(device, this.dataAtBaseZoom, zoom);
} else {
return DPIUtil.autoScaleImageData (device, getImageDataAtCurrentZoom (), zoom, currentDeviceZoom);
return DPIUtil.autoScaleImageData (device, getImageDataAtCurrentZoom (), zoom, currentZoom);
}
}

Expand Down Expand Up @@ -1685,7 +1687,7 @@ public int hashCode () {
if (imageDataProvider != null) {
return imageDataProvider.hashCode();
} else if (imageFileNameProvider != null) {
return Objects.hash(imageFileNameProvider, styleFlag, transparentPixel, currentDeviceZoom);
return Objects.hash(imageFileNameProvider, styleFlag, transparentPixel, getZoom());
} else {
return (int)handle;
}
Expand Down Expand Up @@ -2256,15 +2258,20 @@ public void setBackground(Color color) {
device.internal_dispose_GC(hDC, null);
}

private void setCurrentDeviceZoom(int newZoomFactor) {
if (this.currentDeviceZoom != newZoomFactor) {
this.currentDeviceZoom = newZoomFactor;
private void setCurrentNativeZoom(int newNativeZoom) {
int oldZoom = this.getZoom();
this.currentNativeZoom = newNativeZoom;
if (oldZoom != getZoom()) {
// width and height are tied to the current device zoom
// they must be reset the the zoom factor changes
width = height = -1;
}
}

private int getZoom() {
return DPIUtil.getZoomForAutoscaleProperty(currentNativeZoom);
}

/**
* Returns a string containing a concise, human-readable
* description of the receiver.
Expand Down Expand Up @@ -2319,7 +2326,7 @@ public static Image win32_new(Device device, int type, long handle) {
* @noreference This method is not intended to be referenced by clients.
*/
public static Image win32_new(Image image, int targetZoom) {
if (targetZoom != image.currentDeviceZoom) {
if (targetZoom != image.getZoom()) {
image.handleDPIChange(targetZoom);
}
return image;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ public void setFont (Font font) {
error (SWT.ERROR_INVALID_ARGUMENT);
}
Shell shell = parent.getShell();
this.font = font == null ? null : Font.win32_new(font, shell.getNativeZoom());
this.font = font == null ? null : Font.win32_new(font, shell.nativeZoom);
if (hasFocus ()) setIMEFont ();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ int defaultBackground () {
}

long defaultFont() {
return display.getSystemFont(getShell().getNativeZoom()).handle;
return display.getSystemFont(getShell().nativeZoom).handle;
}

int defaultForeground () {
Expand Down Expand Up @@ -1309,7 +1309,7 @@ public Font getFont () {
if (font != null) return font;
long hFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
if (hFont == 0) hFont = defaultFont ();
return Font.win32_new (display, hFont, getShell().getNativeZoom());
return Font.win32_new (display, hFont, getShell().nativeZoom);
}

/**
Expand Down Expand Up @@ -3314,7 +3314,7 @@ public void setCursor (Cursor cursor) {
}

void setDefaultFont () {
long hFont = display.getSystemFont (getShell().getNativeZoom()).handle;
long hFont = display.getSystemFont (getShell().nativeZoom).handle;
OS.SendMessage (handle, OS.WM_SETFONT, hFont, 0);
}

Expand Down Expand Up @@ -3416,7 +3416,7 @@ public void setFont (Font font) {
Font newFont = font;
if (newFont != null) {
if (newFont.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
newFont = Font.win32_new(newFont, getShell().getNativeZoom());
newFont = Font.win32_new(newFont, getShell().nativeZoom);
}
long hFont = 0;
if (font != null) {
Expand Down Expand Up @@ -4686,9 +4686,9 @@ public boolean setParent (Composite parent) {
if (OS.SetParent (topHandle, parent.handle) == 0) return false;
this.parent = parent;
// If parent changed, zoom level might need to be adjusted
if (parent.getZoom() != getZoom()) {
int oldZoom = getZoom();
int newZoom = parent.getZoom();
if (parent.nativeZoom != nativeZoom) {
int oldZoom = nativeZoom;
int newZoom = parent.nativeZoom;
float scalingFactor = 1f * newZoom / oldZoom;
DPIZoomChangeRegistry.applyChange(this, newZoom, scalingFactor);
}
Expand Down Expand Up @@ -4884,21 +4884,19 @@ LRESULT WM_DESTROY (long wParam, long lParam) {

LRESULT WM_DPICHANGED (long wParam, long lParam) {
// Map DPI to Zoom and compare
int nativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
int newSWTZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom);
int oldSWTZoom = getShell().getZoom();
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
int oldNativeZoom = getShell().nativeZoom;

// Throw the DPI change event if zoom value changes
if (newSWTZoom != oldSWTZoom) {
if (newNativeZoom != oldNativeZoom) {
Event event = new Event();
event.type = SWT.ZoomChanged;
event.widget = this;
event.detail = newSWTZoom;
event.detail = newNativeZoom;
event.doit = true;

if (DPIUtil.isAutoScaleOnRuntimeActive()) {
DPIUtil.setDeviceZoom (nativeZoom);
getShell().setNativeZoom(nativeZoom);
DPIUtil.setDeviceZoom (newNativeZoom);
}

notifyListeners(SWT.ZoomChanged, event);
Expand Down Expand Up @@ -5791,7 +5789,7 @@ private static void handleDPIChange(Widget widget, int newZoom, float scalingFac
if (!(widget instanceof Control control)) {
return;
}
resizeFont(control, control.getShell().getNativeZoom());
resizeFont(control, control.getShell().nativeZoom);

Image image = control.getBackgroundImage();
if (image != null) {
Expand Down
Loading

0 comments on commit d2d6655

Please sign in to comment.