From 53c1278f0c1cb23664895aacd2d1a5ced97ddf3a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Jan 2020 08:45:10 -0500 Subject: [PATCH] remove the last usages of AWT in PApplet (fixes #55) --- core/src/processing/awt/ShimAWT.java | 98 +++++++++++++++++++++++++++ core/src/processing/core/PApplet.java | 69 +++++++++---------- core/src/processing/core/PImage.java | 4 +- core/todo.txt | 2 + 4 files changed, 137 insertions(+), 36 deletions(-) diff --git a/core/src/processing/awt/ShimAWT.java b/core/src/processing/awt/ShimAWT.java index 4c5ee5bb7..238293867 100644 --- a/core/src/processing/awt/ShimAWT.java +++ b/core/src/processing/awt/ShimAWT.java @@ -15,6 +15,12 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.awt.DisplayMode; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.geom.AffineTransform; + import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFileChooser; @@ -45,6 +51,98 @@ public class ShimAWT implements PConstants { this.sketch = sketch; } */ + static private ShimAWT instance; + + private GraphicsDevice[] displayDevices; + + private int displayWidth; + private int displayHeight; + + + /** Only needed for display functions */ + static private ShimAWT getInstance() { + if (instance == null) { + instance = new ShimAWT(); + } + return instance; + } + + + private ShimAWT() { + // Need the list of display devices to be queried already for usage below. + // https://github.com/processing/processing/issues/3295 + // https://github.com/processing/processing/issues/3296 + // Not doing this from a static initializer because it may cause + // PApplet to cache and the values to stick through subsequent runs. + // Instead make it a runtime thing and a local variable. + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice device = ge.getDefaultScreenDevice(); + displayDevices = ge.getScreenDevices(); + +// // Default or unparsed will be -1, spanning will be 0, actual displays will +// // be numbered from 1 because it's too weird to say "display 0" in prefs. +// if (display > 0 && display <= displayDevices.length) { +// device = displayDevices[display-1]; +// } + // When this was called, display will always be unset (even in 3.x), + // since this happens before settings() is called. + + // Set displayWidth and displayHeight for people still using those. + DisplayMode displayMode = device.getDisplayMode(); + displayWidth = displayMode.getWidth(); + displayHeight = displayMode.getHeight(); + } + + + static public int getDisplayWidth() { + return getInstance().displayWidth; + } + + + static public int getDisplayHeight() { + return getInstance().displayHeight; + } + + + static public int getDisplayCount() { + return getInstance().displayDevices.length; + } + + + static public int getDisplayDensity(int num) { + return getInstance().displayDensityImpl(num); + } + + + /* + private int displayDensityImpl() { + if (display != SPAN && (fullScreen || present)) { + return displayDensity(display); + } + // walk through all displays, use 2 if any display is 2 + for (int i = 0; i < displayDevices.length; i++) { + if (displayDensity(i+1) == 2) { + return 2; + } + } + // If nobody's density is 2 then everyone is 1 + return 1; + } + */ + + + private int displayDensityImpl(int display) { + if (display > 0 && display <= displayDevices.length) { + GraphicsConfiguration graphicsConfig = + displayDevices[display - 1].getDefaultConfiguration(); + AffineTransform tx = graphicsConfig.getDefaultTransform(); + return (int) Math.round(tx.getScaleX()); + } + + System.err.println("Display " + display + " does not exist, " + + "returning 1 for displayDensity(" + display + ")"); + return 1; // not the end of the world, so don't throw a RuntimeException + } static public PImage loadImage(PApplet sketch, String filename, Object... args) { diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 16b4a132a..56d7c9253 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -24,19 +24,6 @@ package processing.core; -// before calling settings() to get displayWidth/Height -import java.awt.DisplayMode; -// handleSettings() and displayDensity() -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.geom.AffineTransform; - -// loadXML() error handling -import javax.xml.parsers.ParserConfigurationException; - -import org.xml.sax.SAXException; - import java.io.*; import java.lang.reflect.*; import java.net.*; @@ -51,6 +38,10 @@ import java.util.concurrent.ThreadFactory; import java.util.regex.*; import java.util.zip.*; +// loadXML() error handling +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXException; + // TODO have this removed by 4.0 final import processing.awt.ShimAWT; @@ -811,7 +802,7 @@ public class PApplet implements PConstants { boolean fullScreen; int display = -1; // use default - GraphicsDevice[] displayDevices; +// GraphicsDevice[] displayDevices; // Unlike the others above, needs to be public to support // the pixelWidth and pixelHeight fields. public int pixelDensity = 1; @@ -854,25 +845,11 @@ public class PApplet implements PConstants { insideSettings = true; if (!disableAWT) { - // Need the list of display devices to be queried already for usage below. - // https://github.com/processing/processing/issues/3295 - // https://github.com/processing/processing/issues/3296 - // Not doing this from a static initializer because it may cause - // PApplet to cache and the values to stick through subsequent runs. - // Instead make it a runtime thing and a local variable. - GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice device = ge.getDefaultScreenDevice(); - displayDevices = ge.getScreenDevices(); - - // Default or unparsed will be -1, spanning will be 0, actual displays will - // be numbered from 1 because it's too weird to say "display 0" in prefs. - if (display > 0 && display <= displayDevices.length) { - device = displayDevices[display-1]; - } - // Set displayWidth and displayHeight for people still using those. - DisplayMode displayMode = device.getDisplayMode(); - displayWidth = displayMode.getWidth(); - displayHeight = displayMode.getHeight(); + displayWidth = ShimAWT.getDisplayWidth(); + displayHeight = ShimAWT.getDisplayHeight(); + } else { + // https://github.com/processing/processing4/issues/57 + System.err.println("AWT disabled, displayWidth/displayHeight will be 0"); } // Here's where size(), fullScreen(), smooth(N) and noSmooth() might @@ -1016,8 +993,16 @@ public class PApplet implements PConstants { if (display != SPAN && (fullScreen || present)) { return displayDensity(display); } + + int displayCount = 0; + if (!disableAWT) { + displayCount = ShimAWT.getDisplayCount(); + } else { + // https://github.com/processing/processing4/issues/57 + System.err.println("display count needs to be implemented for non-AWT"); + } // walk through all displays, use 2 if any display is 2 - for (int i = 0; i < displayDevices.length; i++) { + for (int i = 0; i < displayCount; i++) { if (displayDensity(i+1) == 2) { return 2; } @@ -1032,6 +1017,10 @@ public class PApplet implements PConstants { * (1-indexed to match the Preferences dialog box) */ public int displayDensity(int display) { + if (!disableAWT) { + return ShimAWT.getDisplayDensity(display); + } + /* if (display > 0 && display <= displayDevices.length) { GraphicsConfiguration graphicsConfig = displayDevices[display - 1].getDefaultConfiguration(); @@ -1041,6 +1030,9 @@ public class PApplet implements PConstants { System.err.println("Display " + display + " does not exist, " + "returning 1 for displayDensity(" + display + ")"); + */ + // https://github.com/processing/processing4/issues/57 + System.err.println("displayDensity() unavailable because AWT is disabled"); return 1; // not the end of the world, so don't throw a RuntimeException } @@ -14947,6 +14939,15 @@ public class PApplet implements PConstants { } + /** + * Check the alpha on an image, using a really primitive loop. + */ + public void checkAlpha() { + if (recorder != null) recorder.checkAlpha(); + g.checkAlpha(); + } + + /** * ( begin auto-generated from PImage_get.xml ) * diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index 01fc83a66..d8b2df750 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -2827,7 +2827,7 @@ int testFunction(int dst, int src) { } - static public PImage loadTIFF(InputStream input) { + static public PImage loadTIFF(InputStream input) { // ignore byte tiff[] = PApplet.loadBytes(input); if ((tiff[42] != tiff[102]) || // width/height in both places @@ -2931,7 +2931,7 @@ int testFunction(int dst, int src) { * https://github.com/processing/processing/issues/2096 * Please help! */ - static public PImage loadTGA(InputStream input) throws IOException { + static public PImage loadTGA(InputStream input) throws IOException { // ignore byte[] header = new byte[18]; int offset = 0; do { diff --git a/core/todo.txt b/core/todo.txt index 4c9436fac..f06427e5d 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -19,6 +19,8 @@ X make the switch to getModifiersEx() instead of getModifiers() X pass all modifiers to the KeyEvent and MouseEvent constructors X though they aren't even being stored, so what's the point? X https://github.com/processing/processing4/issues/4 +X Remove all usage of AWT from PApplet +X https://github.com/processing/processing4/issues/55 contribs X remove redundant boxing and casting