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