lots of code to handle scaling on Windows; also for #378

This commit is contained in:
Ben Fry
2022-02-13 08:46:16 -05:00
parent c175233ccb
commit fa741e29d0
2 changed files with 78 additions and 34 deletions
+69 -33
View File
@@ -733,7 +733,7 @@ public class PApplet implements PConstants {
*/
static public final String ARGS_SKETCH_FOLDER = "--sketch-path";
static public final String ARGS_DENSITY = "--density";
static public final String ARGS_UI_SCALE = "--ui-scale";
/**
* When run externally to a PdeEditor,
@@ -785,11 +785,9 @@ public class PApplet implements PConstants {
boolean fullScreen;
int display = -1; // use default
// GraphicsDevice[] displayDevices;
// Unlike the others above, needs to be public to support
// the pixelWidth and pixelHeight fields.
public int pixelDensity = 1;
int suggestedDensity = -1;
boolean present;
@@ -10181,19 +10179,6 @@ public class PApplet implements PConstants {
uncaughtThrowable = e;
});
/*
if (platform == WINDOWS) {
// Set DPI scaling to either 1 or 2, but avoid fractional versions like
// 125% and 250% that make things look gross, or even 300% since that
// is not even a thing.
int dpi = java.awt.Toolkit.getDefaultToolkit().getScreenResolution(); // no longer possible to set prop after this line
System.out.println("dpi came back " + dpi);
int scaleFactor = constrain(dpi / 96, 1, 2);
System.out.println("setting scale factor to " + scaleFactor);
System.setProperty("sun.java2d.uiscale", String.valueOf(scaleFactor));
}
*/
// This doesn't work, need to mess with Info.plist instead
/*
// In an exported application, add the Contents/Java folder to the
@@ -10234,10 +10219,8 @@ public class PApplet implements PConstants {
boolean hideStop = false;
int displayNum = -1; // use default
// boolean fullScreen = false;
boolean present = false;
// boolean spanDisplays = false;
int density = -1;
float uiScale = 0;
String param, value;
String folder = calcSketchPath();
@@ -10286,13 +10269,10 @@ public class PApplet implements PConstants {
} else if (param.equals(ARGS_LOCATION)) {
location = parseInt(split(value, ','));
} else if (param.equals(ARGS_DENSITY)) {
density = parseInt(value, -1);
if (density == -1) {
System.err.println("Could not parse " + value + " for " + ARGS_DENSITY);
} else if (density != 1 && density != 2) {
density = -1;
System.err.println(ARGS_DENSITY + " should be 1 or 2");
} else if (param.equals(ARGS_UI_SCALE)) {
uiScale = parseFloat(value, 0);
if (uiScale == 0) {
System.err.println("Could not parse " + value + " for " + ARGS_UI_SCALE);
}
}
@@ -10300,9 +10280,6 @@ public class PApplet implements PConstants {
if (args[argIndex].equals(ARGS_PRESENT)) {
present = true;
// } else if (args[argIndex].equals(ARGS_SPAN_DISPLAYS)) {
// spanDisplays = true;
} else if (args[argIndex].equals(ARGS_HIDE_STOP)) {
hideStop = true;
@@ -10317,6 +10294,29 @@ public class PApplet implements PConstants {
argIndex++;
}
if (platform == WINDOWS) {
// Set DPI scaling to either 1 or 2, but avoid fractional
// settings such as 125% and 250% that make things look gross.
// Also applies to 300% since that is not even a thing.
// no longer possible to set prop after this line initializes AWT
//int dpi = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
// Attempt to get the resolution using a helper app. This code is
// fairly conservative: if there is trouble, we go with the default.
if (uiScale == 0) {
int dpi = getWindowsDPI();
if (dpi != 0) {
uiScale = constrain(dpi / 96, 1, 2);
}
}
if (uiScale != 0) {
System.setProperty("sun.java2d.uiScale", String.valueOf(uiScale));
} else {
System.err.println("Could not identify Windows DPI, not setting sun.java2d.uiScale");
}
}
if (!disableAWT) {
ShimAWT.initRun();
}
@@ -10357,10 +10357,6 @@ public class PApplet implements PConstants {
// (and most likely, from the PDE's preference setting).
sketch.display = displayNum;
// Set the suggested density that is coming from command line
// (most likely set from the PDE based on a system DPI scaling)
sketch.suggestedDensity = density;
sketch.present = present;
// For 3.0.1, moved this above handleSettings() so that loadImage() can be
@@ -10526,6 +10522,46 @@ public class PApplet implements PConstants {
}
/**
* Find the location of fenster.exe by walking through java.library.path.
* (It will be on the path because it's part of core/library/windows-amd64)
*/
static private String findFenster() {
String libraryPath = System.getProperty("java.library.path");
// Should not be null, but cannot assume
if (libraryPath != null) {
String[] folders = split(libraryPath, ';');
// Usually, the most relevant paths will be at the front of the list,
// so hopefully this will not walk several entries.
for (String folder : folders) {
File file = new File(folder, "fenster.exe");
if (file.exists()) {
return file.getAbsolutePath();
}
}
}
return null;
}
/**
* Get the display scaling for Windows by calling out to a helper app.
* https://github.com/processing/processing4/tree/master/build/windows/fenster
*/
static private int getWindowsDPI() {
String fensterPath = findFenster();
if (fensterPath != null) {
StringList stdout = new StringList();
StringList stderr = new StringList();
int result = exec(stdout, stderr, fensterPath);
if (result == 0) {
return parseInt(stdout.join(""), 0);
}
}
return 0;
}
/**
* Convenience method for Python Mode to run an already-constructed sketch.
* This makes it makes it easy to launch a sketch in Jython:
@@ -24,7 +24,6 @@ package processing.mode.java.runner;
import processing.app.*;
import processing.app.exec.StreamRedirectThread;
import processing.app.ui.Toolkit;
import processing.core.*;
import processing.data.StringList;
import processing.mode.java.JavaBuild;
@@ -33,6 +32,7 @@ import processing.mode.java.JavaEditor;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Toolkit;
import java.io.*;
import java.net.ConnectException;
import java.net.InetAddress;
@@ -490,9 +490,17 @@ public class Runner implements MessageConsumer {
// removed for 3.0a6 because it would break the args passed to sketches.
params.append(PApplet.ARGS_SKETCH_FOLDER + "=" + build.getSketchPath());
/*
if (Toolkit.zoom(100) >= 200) { // Use 100 to bypass possible rounding in zoom()
params.append(PApplet.ARGS_DENSITY + "=2");
}
*/
if (Platform.isWindows()) {
// Pass the DPI setting to the app to avoid using the helper app.
int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
int uiScale = PApplet.constrain(dpi / 96, 1, 2);
params.append(PApplet.ARGS_UI_SCALE + "=" + uiScale);
}
params.append(build.getSketchClassName());
}