From 78609202731252f0024e6330cc94c52b05c1d146 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Thu, 16 Jan 2020 01:37:21 +0100
Subject: Bug 1422: Use own deviceZoomScaleUp(..) disregarding higher-toolkit's
compensation like 'DPIUtil.useCairoAutoScale()'
We can't use DPIUtil's 'autoScaleUp(..)' method on non-native DPI scaling platforms
as it uses a scale-factor of 1f if the higher toolkit compensates, i.e. 'DPIUtil.useCairoAutoScale()'.
Since NEWT uses X11 and GDI directly, which are not DPI scale-aware,
we have to drop the semnatics of 'DPIUtil.useCairoAutoScale()'
and merely use the actual 'deviceZoom'.
This was proposed by Marcel Au in the first place.
At least I understand these semantics by now.
+++
Additionally NewtCanvasSWT.SWTNativeWindow needs to return the 'deviceZoomScaleUp(..)'
values for returning its size in window- and pixel-units (surface).
---
.../com/jogamp/nativewindow/swt/SWTAccessor.java | 154 +++++++++++++++++++--
.../classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 28 +++-
2 files changed, 165 insertions(+), 17 deletions(-)
(limited to 'src')
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 0cf56c0c9..5a11ee338 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -49,7 +49,6 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.VisualIDHolder;
-
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
@@ -66,6 +65,7 @@ public class SWTAccessor {
private static final Method swt_scrollable_clientAreaInPixels;
private static final Method swt_control_locationInPixels;
private static final Method swt_control_sizeInPixels;
+ private static final Method swt_dpiutil_getScalingFactor;
private static final Field swt_control_handle;
private static final boolean swt_uses_long_handles;
@@ -186,6 +186,18 @@ public class SWTAccessor {
}
swt_scrollable_clientAreaInPixels = m;
+ m = null;
+ try {
+ m = DPIUtil.class.getDeclaredMethod("getScalingFactor");
+ m.setAccessible(true);
+ } catch (final Exception ex) {
+ m = null;
+ if( DEBUG ) {
+ System.err.println("getScalingFactor not implemented: "+ex.getMessage());
+ }
+ }
+ swt_dpiutil_getScalingFactor = m;
+
Field f = null;
if( !isOSX ) {
try {
@@ -396,17 +408,42 @@ public class SWTAccessor {
out.println("SWT: Platform: "+SWT.getPlatform()+", Version "+SWT.getVersion());
out.println("SWT: isX11 "+isX11+", isX11GTK "+isX11GTK+" (GTK Version: "+OS_gtk_version+")");
out.println("SWT: isOSX "+isOSX+", isWindows "+isWindows);
- out.println("SWT: Display.DPI "+d.getDPI()+", DPIUtil: scalingFactor "+getScalingFactor()+", deviceZoom "+DPIUtil.getDeviceZoom()+
- ", useCairoAutoScale "+DPIUtil.useCairoAutoScale());
+ out.println("SWT: DeviceZoom: "+DPIUtil.getDeviceZoom()+", deviceZoomScalingFactor "+getDeviceZoomScalingFactor());
+ out.println("SWT: Display.DPI "+d.getDPI()+"; DPIUtil: autoScalingFactor "+
+ getAutoScalingFactor()+" (use-swt "+(null != swt_dpiutil_getScalingFactor)+
+ "), useCairoAutoScale "+DPIUtil.useCairoAutoScale());
}
- public static float getScalingFactor() {
+ //
+ // SWT DPIUtil Compatible auto-scale functionality
+ //
+ /**
+ * Returns SWT compatible auto scale-factor, used by {@link DPIUtil}
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static float getAutoScalingFactor() throws NativeWindowException {
+ if( null != swt_dpiutil_getScalingFactor ) {
+ try {
+ return (float) swt_dpiutil_getScalingFactor.invoke(null);
+ } catch (final Throwable e) {
+ throw new NativeWindowException(e);
+ }
+ }
+ // Mimick original code ..
final int deviceZoom = DPIUtil.getDeviceZoom();
if ( 100 == deviceZoom || DPIUtil.useCairoAutoScale() ) {
return 1f;
}
return deviceZoom/100f;
}
+ /**
+ * Returns SWT auto scaled-up value {@code v}, compatible with {@link DPIUtil#autoScaleUp(int)}
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
public static int autoScaleUp (final int v) {
final int deviceZoom = DPIUtil.getDeviceZoom();
if (100 == deviceZoom || DPIUtil.useCairoAutoScale()) {
@@ -415,22 +452,118 @@ public class SWTAccessor {
final float scaleFactor = deviceZoom/100f;
return Math.round (v * scaleFactor);
}
- public static com.jogamp.nativewindow.util.Point autoScaleUp (final com.jogamp.nativewindow.util.Point v) {
+ /**
+ * Returns SWT auto scaled-down value {@code v}, compatible with {@link DPIUtil#autoScaleDown(int)}
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static int autoScaleDown (final int v) {
+ final int deviceZoom = DPIUtil.getDeviceZoom();
+ if (100 == deviceZoom || DPIUtil.useCairoAutoScale()) {
+ return v;
+ }
+ final float scaleFactor = deviceZoom/100f;
+ return Math.round (v / scaleFactor);
+ }
+
+ //
+ // SWT DPIUtil derived deviceZoom scale functionality,
+ // not considering the higher-toolkit's compensation like 'DPIUtil.useCairoAutoScale()'
+ //
+ /**
+ * Returns SWT derived scale-factor based on {@link DPIUtil#getDeviceZoom()}
+ * only, not considering higher-toolkit's compensation like {@link DPIUtil#useCairoAutoScale()}.
+ *
+ * This method should be used instead of {@link #getAutoScalingFactor()}
+ * for native toolkits not caring about DPI scaling like X11 or GDI.
+ *
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static float getDeviceZoomScalingFactor() {
+ final int deviceZoom = DPIUtil.getDeviceZoom();
+ if ( 100 == deviceZoom ) {
+ return 1f;
+ }
+ return deviceZoom/100f;
+ }
+ /**
+ * Returns SWT derived scaled-up value {@code v}, based on {@link DPIUtil#getDeviceZoom()}
+ * only, not considering higher-toolkit's compensation like {@link DPIUtil#useCairoAutoScale()}.
+ *
+ * This method should be used instead of {@link #autoScaleUp(int)}
+ * for native toolkits not caring about DPI scaling like X11 or GDI.
+ *
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static int deviceZoomScaleUp (final int v) {
+ final int deviceZoom = DPIUtil.getDeviceZoom();
+ if (100 == deviceZoom) {
+ return v;
+ }
+ final float scaleFactor = deviceZoom/100f;
+ return Math.round (v * scaleFactor);
+ }
+ /**
+ * Returns SWT derived scaled-down value {@code v}, based on {@link DPIUtil#getDeviceZoom()}
+ * only, not considering higher-toolkit's compensation like {@link DPIUtil#useCairoAutoScale()}.
+ *
+ * This method should be used instead of {@link #autoScaleDown(int)}
+ * for native toolkits not caring about DPI scaling like X11 or GDI.
+ *
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static int deviceZoomScaleDown (final int v) {
+ final int deviceZoom = DPIUtil.getDeviceZoom();
+ if (100 == deviceZoom) {
+ return v;
+ }
+ final float scaleFactor = deviceZoom/100f;
+ return Math.round (v / scaleFactor);
+ }
+ /**
+ * Returns SWT derived scaled-up value {@code v}, based on {@link DPIUtil#getDeviceZoom()}
+ * only, not considering higher-toolkit's compensation like {@link DPIUtil#useCairoAutoScale()}.
+ *
+ * This method should be used instead of {@link #autoScaleUp(com.jogamp.nativewindow.util.Point)}
+ * for native toolkits not caring about DPI scaling like X11 or GDI.
+ *
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static com.jogamp.nativewindow.util.Point deviceZoomScaleUp (final com.jogamp.nativewindow.util.Point v) {
final int deviceZoom = DPIUtil.getDeviceZoom();
- if (100 == deviceZoom || DPIUtil.useCairoAutoScale() || null == v) {
+ if (100 == deviceZoom || null == v) {
return v;
}
final float scaleFactor = deviceZoom/100f;
return v.set(Math.round(v.getX() * scaleFactor), Math.round(v.getY() * scaleFactor));
}
- public static com.jogamp.nativewindow.util.Rectangle autoScaleUp (final com.jogamp.nativewindow.util.Rectangle v) {
+ /**
+ * Returns SWT derived scaled-down value {@code v}, based on {@link DPIUtil#getDeviceZoom()}
+ * only, not considering higher-toolkit's compensation like {@link DPIUtil#useCairoAutoScale()}.
+ *
+ * This method should be used instead of {@link #autoScaleDown(com.jogamp.nativewindow.util.Point)}
+ * for native toolkits not caring about DPI scaling like X11 or GDI.
+ *
+ *
+ * We need to keep track of SWT's implementation in this regard!
+ *
+ */
+ public static com.jogamp.nativewindow.util.Point deviceZoomScaleDown (final com.jogamp.nativewindow.util.Point v) {
final int deviceZoom = DPIUtil.getDeviceZoom();
- if (100 == deviceZoom || DPIUtil.useCairoAutoScale() || null == v) {
+ if (100 == deviceZoom || null == v) {
return v;
}
final float scaleFactor = deviceZoom/100f;
- return v.set(Math.round(v.getX() * scaleFactor), Math.round(v.getY() * scaleFactor),
- Math.round(v.getWidth() * scaleFactor), Math.round(v.getHeight() * scaleFactor));
+ return v.set(Math.round(v.getX() / scaleFactor), Math.round(v.getY() / scaleFactor));
}
/**
@@ -451,6 +584,7 @@ public class SWTAccessor {
* Note to Eclipse authors: Scaling up the fonts and images hardly works on GTK/SWT/Eclipse.
* GDK_SCALE, GDK_DPI_SCALE and swt.autoScale produce inconsistent results with Eclipse.
* Broken High-DPI for .. some years now.
+ * This is especially true for using native high-dpi w/ scaling-factor 1f.
*
*
* Requires SWT >= 3.105 (DPIUtil)
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index 0e58b389d..3bcf4fdab 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -179,8 +179,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC
/**
* Set's the NEWT {@link Window}'s size using {@link Window#setSize(int, int)}.
*
- * For all non-native DPI autoscale platforms, it utilizes {@link SWTAccessor#autoScaleUp(Point)}
- * by multiplying the given {@link Rectangle} size to emulate DPI scaling, see Bug 1422.
+ * For all non-native DPI autoscale platforms method uses {@link SWTAccessor#deviceZoomScaleUp(Point)},
+ * which multiplies the given {@link Rectangle} size with {@link SWTAccessor#getDeviceZoomScalingFactor()}
+ * to emulate DPI scaling, see Bug 1422.
+ *
+ *
+ * Otherwise this method uses the given {@link Rectangle} as-is.
*
*
* Currently native DPI autoscale platforms are
@@ -193,12 +197,22 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC
*/
private final void setNewtChildSize(final Rectangle r) {
if( !SWTAccessor.isOSX ) {
- final Point p = SWTAccessor.autoScaleUp(new Point(r.width, r.height));
+ final Point p = SWTAccessor.deviceZoomScaleUp(new Point(r.width, r.height));
newtChild.setSize(p.getX(), p.getY());
} else {
newtChild.setSize(r.width, r.height);
}
}
+ /**
+ * See {@link #setNewtChildSize(Rectangle)}
+ */
+ private final int newtScaleUp(final int v) {
+ if( !SWTAccessor.isOSX ) {
+ return SWTAccessor.deviceZoomScaleUp(v);
+ } else {
+ return v;
+ }
+ }
private final Listener swtListener = new Listener () {
@Override
public void handleEvent (final Event event) {
@@ -642,12 +656,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC
@Override
public int getWidth() {
- return clientAreaWindow.width;
+ return newtScaleUp(clientAreaWindow.width);
}
@Override
public int getHeight() {
- return clientAreaWindow.height;
+ return newtScaleUp(clientAreaWindow.height);
}
@Override
@@ -666,12 +680,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC
@Override
public int getSurfaceWidth() {
- return clientAreaPixels.width;
+ return newtScaleUp(clientAreaPixels.width);
}
@Override
public int getSurfaceHeight() {
- return clientAreaPixels.height;
+ return newtScaleUp(clientAreaPixels.height);
}
@Override
--
cgit v1.2.3