JNA Windows Scaling (#45)

JNA Windows Scaling
This commit is contained in:
Ben Fry
2020-01-07 13:44:49 -05:00
committed by GitHub
4 changed files with 70 additions and 17 deletions
+4 -4
View File
@@ -411,9 +411,9 @@ public class Platform {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
static public int getSystemDPI() {
return inst.getSystemDPI();
static public float getSystemZoom() {
return inst.getSystemZoom();
}
}
@@ -54,6 +54,8 @@ import processing.app.Preferences;
public class DefaultPlatform {
Base base;
private final float ZOOM_DEFAULT_SIZING = 1;
private final int DEFAULT_DPI = 96;
public void initBase(Base base) {
this.base = base;
@@ -157,8 +159,34 @@ public class DefaultPlatform {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public int getSystemDPI() {
return 96;
/**
* Get the zoom or display scaling requested by the operating system.
*
* <p>
* Get the operating system zoom setting that Processing may use to resize
* internal elements depending on user preferences. Note that some operating
* systems will perform zooming in a way that is transparent to the
* the applications. If that is the case, this will return 1. Otherwise,
* the operating system will not automatically resize UI elements and this
* will return a value other than 1, meaning that Processing may need to
* resize elements on its own depending on user preferences.
* </p>
*
* <p>
* Note that this may be distinct from the system DPI and some operating
* systems may report a DPI of 96 while also requesting a display zooming of
* 125%. However, others may not report a "display scaling" but provide a
* DPI of 120 when the elements should have a 125% zoom. This will use the
* preferred method of determining the appropriate zoom given the platform
* in use. Using this system display scaling percentage approach instead of
* returning DPI directly is preferred after JEP 263.
* </p>
*
* @return The zoom level where 1.0 means 100% (no zoom) and 1.25 means
* 125% (25% additional zoom).
*/
public float getSystemZoom() {
return ZOOM_DEFAULT_SIZING;
}
}
@@ -22,14 +22,15 @@
package processing.app.platform;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Optional;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Shell32Util;
import com.sun.jna.platform.win32.ShlObj;
import com.sun.jna.platform.win32.*;
import processing.app.Base;
import processing.app.Messages;
@@ -61,10 +62,16 @@ public class WindowsPlatform extends DefaultPlatform {
"\\" + APP_NAME.toLowerCase() + ".exe \"%1\"";
static final String REG_DOC = APP_NAME + ".Document";
// Starting with Java 9, the scaling is done automatically. If DPI is
// used to scaling within the application, one ends up with 2x the
// expected scale. See JEP 263.
private static final int WINDOWS_NATIVE_DPI = 96;
private static final float RESOLUTION_AT_NO_SCALE = 96;
private static final int VERTRES = 10;
private static final int DESKTOPVERTRES = 117;
private Optional<Float> cachedDisplayScaling;
public WindowsPlatform() {
super();
cachedDisplayScaling = Optional.empty();
}
public void initBase(Base base) {
super.initBase(base);
@@ -629,10 +636,28 @@ public class WindowsPlatform extends DefaultPlatform {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public float getSystemZoom() {
if (cachedDisplayScaling.isEmpty()) {
cachedDisplayScaling = Optional.of(calculateSystemZoom());
}
public int getSystemDPI() {
// Note that this is supported "natively" within Java - See JEP 263.
return WINDOWS_NATIVE_DPI;
return cachedDisplayScaling.get();
}
private float calculateSystemZoom() {
WinDef.HDC hdc = GDI32.INSTANCE.CreateCompatibleDC(null);
if (hdc == null) {
float resolution = Toolkit.getDefaultToolkit().getScreenResolution();
return resolution / RESOLUTION_AT_NO_SCALE;
}
float virtualResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, VERTRES);
float logicalResolution = GDI32.INSTANCE.GetDeviceCaps(hdc, DESKTOPVERTRES);
GDI32.INSTANCE.DeleteDC(hdc);
return logicalResolution / virtualResolution;
}
}
+1 -1
View File
@@ -851,7 +851,7 @@ public class Toolkit {
static private float parseZoom() {
if (Preferences.getBoolean("editor.zoom.auto")) {
float newZoom = Platform.getSystemDPI() / 96f;
float newZoom = Platform.getSystemZoom();
String percentSel = ((int) (newZoom*100)) + "%";
Preferences.set("editor.zoom", percentSel);
return newZoom;