Merge pull request #5011 from JakubValtar/blow-up

Window placement and pixel density cleanup
This commit is contained in:
Ben Fry
2017-04-21 16:57:20 -04:00
committed by GitHub
9 changed files with 293 additions and 314 deletions
+33 -35
View File
@@ -409,8 +409,6 @@ public class PGraphicsJava2D extends PGraphics {
checkSettings();
resetMatrix(); // reset model matrix
vertexCount = 0;
g2.scale(pixelDensity, pixelDensity);
}
@@ -1573,8 +1571,8 @@ public class PGraphicsJava2D extends PGraphics {
// Nuke the cache if the image was resized
if (cash != null) {
if (who.width != cash.image.getWidth() ||
who.height != cash.image.getHeight()) {
if (who.pixelWidth != cash.image.getWidth() ||
who.pixelHeight != cash.image.getHeight()) {
cash = null;
}
}
@@ -1601,12 +1599,17 @@ public class PGraphicsJava2D extends PGraphics {
// This might be a PGraphics that hasn't been drawn to yet.
// Can't just bail because the cache has been created above.
// https://github.com/processing/processing/issues/2208
who.pixels = new int[who.width * who.height];
who.pixels = new int[who.pixelWidth * who.pixelHeight];
}
cash.update(who, tint, tintColor);
who.setModified(false);
}
u1 *= who.pixelDensity;
v1 *= who.pixelDensity;
u2 *= who.pixelDensity;
v2 *= who.pixelDensity;
g2.drawImage(((ImageCache) getCache(who)).image,
(int) x1, (int) y1, (int) x2, (int) y2,
u1, v1, u2, v2, null);
@@ -1674,14 +1677,14 @@ public class PGraphicsJava2D extends PGraphics {
// in the alpha channel when drawn to the screen.
// https://github.com/processing/processing/issues/2030
if (image == null) {
image = new BufferedImage(source.width, source.height,
image = new BufferedImage(source.pixelWidth, source.pixelHeight,
BufferedImage.TYPE_INT_ARGB);
}
WritableRaster wr = image.getRaster();
if (tint) {
if (tintedTemp == null || tintedTemp.length != source.width) {
tintedTemp = new int[source.width];
if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
tintedTemp = new int[source.pixelHeight];
}
int a2 = (tintColor >> 24) & 0xff;
// System.out.println("tint color is " + a2);
@@ -1695,8 +1698,8 @@ public class PGraphicsJava2D extends PGraphics {
// The target image is opaque, meaning that the source image has no
// alpha (is not ARGB), and the tint has no alpha.
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int x = 0; x < source.width; x++) {
for (int y = 0; y < source.pixelHeight; y++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
@@ -1710,7 +1713,7 @@ public class PGraphicsJava2D extends PGraphics {
((g2 * g1) & 0xff00) |
(((b2 * b1) & 0xff00) >> 8);
}
wr.setDataElements(0, y, source.width, 1, tintedTemp);
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
}
// could this be any slower?
// float[] scales = { tintR, tintG, tintB };
@@ -1724,18 +1727,18 @@ public class PGraphicsJava2D extends PGraphics {
(tintColor & 0xffffff) == 0xffffff) {
int hi = tintColor & 0xff000000;
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int x = 0; x < source.width; x++) {
for (int y = 0; y < source.pixelHeight; y++) {
for (int x = 0; x < source.pixelWidth; x++) {
tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
}
wr.setDataElements(0, y, source.width, 1, tintedTemp);
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
}
} else {
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int y = 0; y < source.pixelHeight; y++) {
if (source.format == RGB) {
int alpha = tintColor & 0xFF000000;
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
@@ -1746,7 +1749,7 @@ public class PGraphicsJava2D extends PGraphics {
(((b2 * b1) & 0xff00) >> 8);
}
} else if (source.format == ARGB) {
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int a1 = (argb1 >> 24) & 0xff;
int r1 = (argb1 >> 16) & 0xff;
@@ -1760,13 +1763,13 @@ public class PGraphicsJava2D extends PGraphics {
}
} else if (source.format == ALPHA) {
int lower = tintColor & 0xFFFFFF;
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int a1 = source.pixels[index++];
tintedTemp[x] =
(((a2 * a1) & 0xff00) << 16) | lower;
}
}
wr.setDataElements(0, y, source.width, 1, tintedTemp);
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
}
}
// Not sure why ARGB images take the scales in this order...
@@ -1786,7 +1789,7 @@ public class PGraphicsJava2D extends PGraphics {
// in a PImage and how the high bits will be set.
}
// If no tint, just shove the pixels on in there verbatim
wr.setDataElements(0, 0, source.width, source.height, source.pixels);
wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels);
}
this.tinted = tint;
this.tintedColor = tintColor;
@@ -2232,6 +2235,7 @@ public class PGraphicsJava2D extends PGraphics {
@Override
public void resetMatrix() {
g2.setTransform(new AffineTransform());
g2.scale(pixelDensity, pixelDensity);
}
@@ -2793,7 +2797,7 @@ public class PGraphicsJava2D extends PGraphics {
if (pixels != null) {
getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
}
modified = true;
modified = false;
}
@@ -2836,12 +2840,6 @@ public class PGraphicsJava2D extends PGraphics {
//public PImage get(int x, int y, int w, int h)
@Override
public PImage get() {
return get(0, 0, width, height);
}
@Override
protected void getImpl(int sourceX, int sourceY,
int sourceWidth, int sourceHeight,
@@ -2852,7 +2850,7 @@ public class PGraphicsJava2D extends PGraphics {
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
WritableRaster raster = getRaster();
if (sourceWidth == target.width && sourceHeight == target.height) {
if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) {
raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
// https://github.com/processing/processing/issues/2030
if (raster.getNumBands() == 3) {
@@ -2866,7 +2864,7 @@ public class PGraphicsJava2D extends PGraphics {
// Copy the temporary output pixels over to the outgoing image
int sourceOffset = 0;
int targetOffset = targetY*target.width + targetX;
int targetOffset = targetY*target.pixelWidth + targetX;
for (int y = 0; y < sourceHeight; y++) {
if (raster.getNumBands() == 3) {
for (int i = 0; i < sourceWidth; i++) {
@@ -2878,7 +2876,7 @@ public class PGraphicsJava2D extends PGraphics {
System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth);
}
sourceOffset += sourceWidth;
targetOffset += target.width;
targetOffset += target.pixelWidth;
}
}
}
@@ -2886,7 +2884,7 @@ public class PGraphicsJava2D extends PGraphics {
@Override
public void set(int x, int y, int argb) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return;
if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) return;
// ((BufferedImage) image).setRGB(x, y, argb);
getset[0] = argb;
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
@@ -2907,18 +2905,18 @@ public class PGraphicsJava2D extends PGraphics {
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
if ((sourceX == 0) && (sourceY == 0) &&
(sourceWidth == sourceImage.width) &&
(sourceHeight == sourceImage.height)) {
(sourceWidth == sourceImage.pixelWidth) &&
(sourceHeight == sourceImage.pixelHeight)) {
// System.out.format("%d %d %dx%d %d%n", targetX, targetY,
// sourceImage.width, sourceImage.height,
// sourceImage.pixels.length);
raster.setDataElements(targetX, targetY,
sourceImage.width, sourceImage.height,
sourceImage.pixelWidth, sourceImage.pixelHeight,
sourceImage.pixels);
} else {
// TODO optimize, incredibly inefficient to reallocate this much memory
PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight);
raster.setDataElements(targetX, targetY, temp.width, temp.height, temp.pixels);
raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels);
}
}
+16 -9
View File
@@ -90,6 +90,8 @@ public class PSurfaceAWT extends PSurfaceNone {
int sketchWidth;
int sketchHeight;
int windowScaleFactor;
public PSurfaceAWT(PGraphics graphics) {
//this.graphics = graphics;
@@ -224,7 +226,7 @@ public class PSurfaceAWT extends PSurfaceNone {
if (!oldSize.equals(newSize)) {
// System.out.println("validate() render old=" + oldSize + " -> new=" + newSize);
oldSize = newSize;
sketch.setSize(newSize.width, newSize.height);
sketch.setSize(newSize.width / windowScaleFactor, newSize.height / windowScaleFactor);
// try {
render();
// } catch (IllegalStateException ise) {
@@ -423,8 +425,11 @@ public class PSurfaceAWT extends PSurfaceNone {
sketch.displayWidth = screenRect.width;
sketch.displayHeight = screenRect.height;
sketchWidth = sketch.sketchWidth();
sketchHeight = sketch.sketchHeight();
windowScaleFactor = PApplet.platform == PConstants.MACOSX ?
1 : sketch.pixelDensity;
sketchWidth = sketch.sketchWidth() * windowScaleFactor;
sketchHeight = sketch.sketchHeight() * windowScaleFactor;
boolean fullScreen = sketch.sketchFullScreen();
// Removing the section below because sometimes people want to do the
@@ -481,7 +486,7 @@ public class PSurfaceAWT extends PSurfaceNone {
// http://dev.processing.org/bugs/show_bug.cgi?id=908
frame.add(canvas);
setSize(sketchWidth, sketchHeight);
setSize(sketchWidth / windowScaleFactor, sketchHeight / windowScaleFactor);
/*
if (fullScreen) {
@@ -954,8 +959,8 @@ public class PSurfaceAWT extends PSurfaceNone {
return; // unchanged, don't rebuild everything
}
sketchWidth = wide;
sketchHeight = high;
sketchWidth = wide * windowScaleFactor;
sketchHeight = high * windowScaleFactor;
// canvas.setSize(wide, high);
// frame.setSize(wide, high);
@@ -1142,8 +1147,9 @@ public class PSurfaceAWT extends PSurfaceNone {
// overall size of the window. Perhaps JFrame sets its coord
// system so that (0, 0) is always the upper-left of the content
// area. Which seems nice, but breaks any f*ing AWT-based code.
setSize(windowSize.width - currentInsets.left - currentInsets.right,
windowSize.height - currentInsets.top - currentInsets.bottom);
int w = windowSize.width - currentInsets.left - currentInsets.right;
int h = windowSize.height - currentInsets.top - currentInsets.bottom;
setSize(w / windowScaleFactor, h / windowScaleFactor);
// correct the location when inset size changes
setLocation(x - currentInsets.left, y - currentInsets.top);
@@ -1312,7 +1318,8 @@ public class PSurfaceAWT extends PSurfaceNone {
sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(),
peAction, peModifiers,
nativeEvent.getX(), nativeEvent.getY(),
nativeEvent.getX() / windowScaleFactor,
nativeEvent.getY() / windowScaleFactor,
peButton,
peCount));
}
+45 -13
View File
@@ -790,6 +790,8 @@ public class PApplet implements PConstants {
*/
static public final String ARGS_SKETCH_FOLDER = "--sketch-path";
static public final String ARGS_DENSITY = "--density";
/**
* When run externally to a PdeEditor,
* this is sent by the sketch when it quits.
@@ -909,6 +911,9 @@ public class PApplet implements PConstants {
// Unlike the others above, needs to be public to support
// the pixelWidth and pixelHeight fields.
public int pixelDensity = 1;
int suggestedDensity = -1;
boolean present;
String outputPath;
OutputStream outputStream;
@@ -1128,23 +1133,23 @@ public class PApplet implements PConstants {
* @see PApplet#size(int,int)
*/
public int displayDensity() {
if (display == SPAN) {
// walk through all displays, use lowest common denominator
for (int i = 0; i < displayDevices.length; i++) {
if (displayDensity(i) != 2) {
return 1;
}
}
// If nobody's density is 1 (or != 2, to be exact) then everyone is 2
return 2;
if (display != SPAN && (fullScreen || present)) {
return displayDensity(display);
}
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;
}
/**
* @param display the display number to check
*/
static public int displayDensity(int display) {
public int displayDensity(int display) {
if (PApplet.platform == PConstants.MACOSX) {
// This should probably be reset each time there's a display change.
// A 5-minute search didn't turn up any such event in the Java 7 API.
@@ -1187,6 +1192,15 @@ public class PApplet implements PConstants {
}
} catch (Exception ignore) { }
}
} else if (PApplet.platform == PConstants.WINDOWS ||
PApplet.platform == PConstants.LINUX) {
if (suggestedDensity == -1) {
// TODO: detect and return DPI scaling using JNA; Windows has
// a system-wide value, not sure how it works on Linux
return 1;
} else if (suggestedDensity == 1 || suggestedDensity == 2) {
return suggestedDensity;
}
}
return 1;
}
@@ -1204,9 +1218,11 @@ public class PApplet implements PConstants {
if (density != 1 && density != 2) {
throw new RuntimeException("pixelDensity() can only be 1 or 2");
}
if (density == 2 && displayDensity() == 1) {
if (!FX2D.equals(renderer) && density == 2 && displayDensity() == 1) {
// FX has its own check in PSurfaceFX
// Don't throw exception because the sketch should still work
throw new RuntimeException("pixelDensity(2) is not available for this display");
System.err.println("pixelDensity(2) is not available for this display");
this.pixelDensity = 1;
} else {
this.pixelDensity = density;
}
@@ -10390,6 +10406,7 @@ public class PApplet implements PConstants {
// boolean fullScreen = false;
boolean present = false;
// boolean spanDisplays = false;
int density = -1;
String param = null, value = null;
String folder = calcSketchPath();
@@ -10432,6 +10449,15 @@ 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 {
@@ -10500,6 +10526,12 @@ 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
// used inside settings(). Sets a terrible precedent, but the alternative
// of not being able to size a sketch to an image is driving people loopy.
+6 -1
View File
@@ -3879,6 +3879,11 @@ public class PGraphics extends PImage implements PConstants {
// fillA = 1;
// }
u1 *= img.pixelDensity;
u2 *= img.pixelDensity;
v1 *= img.pixelDensity;
v2 *= img.pixelDensity;
beginShape(QUADS);
texture(img);
vertex(x1, y1, u1, v1);
@@ -7347,7 +7352,7 @@ public class PGraphics extends PImage implements PConstants {
* @param image PImage to set as background (must be same size as the sketch window)
*/
public void background(PImage image) {
if ((image.width != width) || (image.height != height)) {
if ((image.pixelWidth != pixelWidth) || (image.pixelHeight != pixelHeight)) {
throw new RuntimeException(ERROR_BACKGROUND_IMAGE_SIZE);
}
if ((image.format != RGB) && (image.format != ARGB)) {
+47 -23
View File
@@ -645,9 +645,27 @@ public class PGraphicsFX2D extends PGraphics {
int mw = mx2 - mx1;
int mh = my2 - my1;
PixelWriter pw = context.getPixelWriter();
pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels,
mx1 + my1 * pixelWidth, pixelWidth);
if (pixelDensity == 1) {
PixelWriter pw = context.getPixelWriter();
pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels,
mx1 + my1 * pixelWidth, pixelWidth);
} else {
// The only way to push all the pixels is to draw a scaled-down image
if (snapshotImage == null ||
snapshotImage.getWidth() != pixelWidth ||
snapshotImage.getHeight() != pixelHeight) {
snapshotImage = new WritableImage(pixelWidth, pixelHeight);
}
PixelWriter pw = snapshotImage.getPixelWriter();
pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels,
mx1 + my1 * pixelWidth, pixelWidth);
context.save();
resetMatrix();
context.scale(1d / pixelDensity, 1d / pixelDensity);
context.drawImage(snapshotImage, mx1, my1, mw, mh, mx1, my1, mw, mh);
context.restore();
}
}
modified = false;
@@ -1013,8 +1031,8 @@ public class PGraphicsFX2D extends PGraphics {
// Nuke the cache if the image was resized
if (cash != null) {
if (who.width != cash.image.getWidth() ||
who.height != cash.image.getHeight()) {
if (who.pixelWidth != cash.image.getWidth() ||
who.pixelHeight != cash.image.getHeight()) {
cash = null;
}
}
@@ -1041,12 +1059,17 @@ public class PGraphicsFX2D extends PGraphics {
// This might be a PGraphics that hasn't been drawn to yet.
// Can't just bail because the cache has been created above.
// https://github.com/processing/processing/issues/2208
who.pixels = new int[who.width * who.height];
who.pixels = new int[who.pixelWidth * who.pixelHeight];
}
cash.update(who, tint, tintColor);
who.setModified(false);
}
u1 *= who.pixelDensity;
v1 *= who.pixelDensity;
u2 *= who.pixelDensity;
v2 *= who.pixelDensity;
context.drawImage(((ImageCache) getCache(who)).image,
u1, v1, u2-u1, v2-v1,
x1, y1, x2-x1, y2-y1);
@@ -1087,14 +1110,14 @@ public class PGraphicsFX2D extends PGraphics {
// BufferedImage.TYPE_INT_ARGB);
// }
if (image == null) {
image = new WritableImage(source.width, source.height);
image = new WritableImage(source.pixelWidth, source.pixelHeight);
}
//WritableRaster wr = image.getRaster();
PixelWriter pw = image.getPixelWriter();
if (tint) {
if (tintedTemp == null || tintedTemp.length != source.width) {
tintedTemp = new int[source.width];
if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
tintedTemp = new int[source.pixelWidth];
}
int a2 = (tintColor >> 24) & 0xff;
// System.out.println("tint color is " + a2);
@@ -1108,8 +1131,8 @@ public class PGraphicsFX2D extends PGraphics {
// The target image is opaque, meaning that the source image has no
// alpha (is not ARGB), and the tint has no alpha.
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int x = 0; x < source.width; x++) {
for (int y = 0; y < source.pixelHeight; y++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
@@ -1124,7 +1147,7 @@ public class PGraphicsFX2D extends PGraphics {
(((b2 * b1) & 0xff00) >> 8);
}
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width);
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth);
}
// could this be any slower?
// float[] scales = { tintR, tintG, tintB };
@@ -1138,19 +1161,19 @@ public class PGraphicsFX2D extends PGraphics {
(tintColor & 0xffffff) == 0xffffff) {
int hi = tintColor & 0xff000000;
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int x = 0; x < source.width; x++) {
for (int y = 0; y < source.pixelHeight; y++) {
for (int x = 0; x < source.pixelWidth; x++) {
tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
}
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width);
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelHeight);
}
} else {
int index = 0;
for (int y = 0; y < source.height; y++) {
for (int y = 0; y < source.pixelHeight; y++) {
if (source.format == RGB) {
int alpha = tintColor & 0xFF000000;
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int r1 = (argb1 >> 16) & 0xff;
int g1 = (argb1 >> 8) & 0xff;
@@ -1161,7 +1184,7 @@ public class PGraphicsFX2D extends PGraphics {
(((b2 * b1) & 0xff00) >> 8);
}
} else if (source.format == ARGB) {
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int argb1 = source.pixels[index++];
int a1 = (argb1 >> 24) & 0xff;
int r1 = (argb1 >> 16) & 0xff;
@@ -1175,14 +1198,14 @@ public class PGraphicsFX2D extends PGraphics {
}
} else if (source.format == ALPHA) {
int lower = tintColor & 0xFFFFFF;
for (int x = 0; x < source.width; x++) {
for (int x = 0; x < source.pixelWidth; x++) {
int a1 = source.pixels[index++];
tintedTemp[x] =
(((a2 * a1) & 0xff00) << 16) | lower;
}
}
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width);
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth);
}
}
// Not sure why ARGB images take the scales in this order...
@@ -1204,8 +1227,8 @@ public class PGraphicsFX2D extends PGraphics {
// If no tint, just shove the pixels on in there verbatim
//wr.setDataElements(0, 0, source.width, source.height, source.pixels);
//System.out.println("moving the big one");
pw.setPixels(0, 0, source.width, source.height,
argbFormat, source.pixels, 0, source.width);
pw.setPixels(0, 0, source.pixelWidth, source.pixelHeight,
argbFormat, source.pixels, 0, source.pixelWidth);
}
this.tinted = tint;
this.tintedColor = tintColor;
@@ -2133,8 +2156,9 @@ public class PGraphicsFX2D extends PGraphics {
snapshotImage = new WritableImage(pixelWidth, pixelHeight);
}
SnapshotParameters sp = new SnapshotParameters();
SnapshotParameters sp = null;
if (pixelDensity != 1) {
sp = new SnapshotParameters();
sp.setTransform(Transform.scale(pixelDensity, pixelDensity));
}
snapshotImage = ((PSurfaceFX) surface).canvas.snapshot(sp, snapshotImage);
+26 -55
View File
@@ -22,6 +22,8 @@
package processing.javafx;
import com.sun.glass.ui.Screen;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
@@ -244,6 +246,19 @@ public class PSurfaceFX implements PSurface {
PApplet sketch = surface.sketch;
float renderScale = Screen.getMainScreen().getRenderScale();
if (PApplet.platform == PConstants.MACOSX) {
for (Screen s : Screen.getScreens()) {
renderScale = Math.max(renderScale, s.getRenderScale());
}
}
float uiScale = Screen.getMainScreen().getUIScale();
if (sketch.pixelDensity == 2 && renderScale < 2) {
sketch.pixelDensity = 1;
sketch.g.pixelDensity = 1;
System.err.println("pixelDensity(2) is not available for this display");
}
// Use AWT display code, because FX orders screens in different way
GraphicsDevice displayDevice = null;
@@ -286,17 +301,8 @@ public class PSurfaceFX implements PSurface {
maxY = Math.max(maxY, bounds.getMaxY());
}
}
if (minY < 0) {
// FX can't handle this
System.err.format("FX can't place window at negative Y coordinate " +
"[x=%d, y=%d]. Please make sure that your secondary " +
"display does not extend above the main display.",
(int) minX, (int) minY);
screenRect = primaryScreenRect;
} else {
screenRect = new Rectangle((int) minX, (int) minY,
(int) (maxX - minX), (int) (maxY - minY));
}
screenRect = new Rectangle((int) minX, (int) minY,
(int) (maxX - minX), (int) (maxY - minY));
}
// Set the displayWidth/Height variables inside PApplet, so that they're
@@ -308,14 +314,14 @@ public class PSurfaceFX implements PSurface {
int sketchHeight = sketch.sketchHeight();
if (fullScreen || spanDisplays) {
sketchWidth = (int) screenRect.getWidth();
sketchHeight = (int) screenRect.getHeight();
sketchWidth = (int) (screenRect.getWidth() / uiScale);
sketchHeight = (int) (screenRect.getHeight() / uiScale);
stage.initStyle(StageStyle.UNDECORATED);
stage.setX(screenRect.getMinX());
stage.setY(screenRect.getMinY());
stage.setWidth(screenRect.getWidth());
stage.setHeight(screenRect.getHeight());
stage.setX(screenRect.getMinX() / uiScale);
stage.setY(screenRect.getMinY() / uiScale);
stage.setWidth(screenRect.getWidth() / uiScale);
stage.setHeight(screenRect.getHeight() / uiScale);
}
Canvas canvas = surface.canvas;
@@ -540,12 +546,9 @@ public class PSurfaceFX implements PSurface {
public void placeWindow(int[] location, int[] editorLocation) {
if (sketch.sketchFullScreen()) {
PApplet.hideMenuBar();
return;
}
//Dimension window = setFrameSize();
// int contentW = Math.max(sketchWidth, MIN_WINDOW_WIDTH);
// int contentH = Math.max(sketchHeight, MIN_WINDOW_HEIGHT);
// System.out.println("stage size is " + stage.getWidth() + " " + stage.getHeight());
int wide = sketch.width; // stage.getWidth() is NaN here
int high = sketch.height; // stage.getHeight()
@@ -565,42 +568,10 @@ public class PSurfaceFX implements PSurface {
stage.setY(locationY);
} else { // doesn't fit
// // if it fits inside the editor window,
// // offset slightly from upper lefthand corner
// // so that it's plunked inside the text area
// locationX = editorLocation[0] + 66;
// locationY = editorLocation[1] + 66;
//
// if ((locationX + stage.getWidth() > sketch.displayWidth - 33) ||
// (locationY + stage.getHeight() > sketch.displayHeight - 33)) {
// // otherwise center on screen
// locationX = (int) ((sketch.displayWidth - wide) / 2);
// locationY = (int) ((sketch.displayHeight - high) / 2);
// }
locationX = (sketch.displayWidth - wide) / 2;
locationY = (sketch.displayHeight - high) / 2;
stage.setX(locationX);
stage.setY(locationY);
stage.centerOnScreen();
}
} else { // just center on screen
//setFrameCentered();
}
if (stage.getY() < 0) {
// Windows actually allows you to place frames where they can't be
// closed. Awesome. http://dev.processing.org/bugs/show_bug.cgi?id=1508
//frame.setLocation(frameLoc.x, 30);
stage.setY(30);
}
//canvas.setBounds((contentW - sketchWidth)/2,
// (contentH - sketchHeight)/2,
// sketchWidth, sketchHeight);
// handle frame resizing events
//setupFrameResizeListener();
if (sketch.getGraphics().displayable()) {
setVisible(true);
stage.centerOnScreen();
}
}
+30 -24
View File
@@ -637,6 +637,9 @@ public class PGraphicsOpenGL extends PGraphics {
height = iheight;
updatePixelSize();
texture = null;
ptexture = null;
// init perspective projection based on new dimensions
defCameraFOV = 60 * DEG_TO_RAD; // at least for now
defCameraX = width / 2.0f;
@@ -692,6 +695,10 @@ public class PGraphicsOpenGL extends PGraphics {
float f = pgl.getPixelScale();
pixelWidth = (int)(width * f);
pixelHeight = (int)(height * f);
if (primaryGraphics) {
parent.pixelWidth = pixelWidth;
parent.pixelHeight = pixelHeight;
}
}
@@ -2140,8 +2147,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
if (textured && textureMode == IMAGE) {
u /= textureImage.width;
v /= textureImage.height;
u /= textureImage.pixelWidth;
v /= textureImage.pixelHeight;
}
inGeo.addVertex(x, y, z,
@@ -5417,30 +5424,29 @@ public class PGraphicsOpenGL extends PGraphics {
protected void drawPixels(int x, int y, int w, int h) {
int f = (int)pgl.getPixelScale();
int len = f * w * f * h;
int len = w * h;
if (nativePixels == null || nativePixels.length < len) {
nativePixels = new int[len];
nativePixelBuffer = PGL.allocateIntBuffer(nativePixels);
}
try {
if (0 < x || 0 < y || w < width || h < height) {
if (0 < x || 0 < y || w < pixelWidth || h < pixelHeight) {
// The pixels to be copied to the texture need to be consecutive, and
// they are not in the pixels array, so putting each row one after
// another in nativePixels.
int offset0 = f * (y * width + x);
int offset0 = y * pixelWidth + x;
int offset1 = 0;
for (int yc = f * y; yc < f * (y + h); yc++) {
System.arraycopy(pixels, offset0, nativePixels, offset1, f * w);
offset0 += f * width;
offset1 += f * w;
for (int yc = y; yc < y + h; yc++) {
System.arraycopy(pixels, offset0, nativePixels, offset1, w);
offset0 += pixelWidth;
offset1 += w;
}
} else {
PApplet.arrayCopy(pixels, 0, nativePixels, 0, len);
}
PGL.javaToNativeARGB(nativePixels, f * w, f * h);
PGL.javaToNativeARGB(nativePixels, w, h);
} catch (ArrayIndexOutOfBoundsException e) {
}
PGL.putIntArray(nativePixelBuffer, nativePixels);
@@ -5464,10 +5470,10 @@ public class PGraphicsOpenGL extends PGraphics {
// (off)screen buffer.
// First, copy the pixels to the texture. We don't need to invert the
// pixel copy because the texture will be drawn inverted.
int tw = PApplet.min(texture.glWidth - f * x, f * w);
int th = PApplet.min(texture.glHeight - f * y, f * h);
int tw = PApplet.min(texture.glWidth - x, w);
int th = PApplet.min(texture.glHeight - y, h);
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName,
f * x, f * y, tw, th, nativePixelBuffer);
x, y, tw, th, nativePixelBuffer);
beginPixelsOp(OP_WRITE);
drawTexture(x, y, w, h);
endPixelsOp();
@@ -5476,7 +5482,7 @@ public class PGraphicsOpenGL extends PGraphics {
// currently drawing to. Because the texture is invertex along Y, we
// need to reflect that in the vertical arguments.
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName,
f * x, f * (height - (y + h)), f * w, f * h, nativePixelBuffer);
x, pixelHeight - (y + h), w, h, nativePixelBuffer);
}
}
@@ -5549,10 +5555,10 @@ public class PGraphicsOpenGL extends PGraphics {
@Override
protected void processImageBeforeAsyncSave(PImage image) {
if (image.format == AsyncPixelReader.OPENGL_NATIVE) {
PGL.nativeToJavaARGB(image.pixels, image.width, image.height);
PGL.nativeToJavaARGB(image.pixels, image.pixelWidth, image.pixelHeight);
image.format = ARGB;
} else if (image.format == AsyncPixelReader.OPENGL_NATIVE_OPAQUE) {
PGL.nativeToJavaRGB(image.pixels, image.width, image.height);
PGL.nativeToJavaRGB(image.pixels, image.pixelWidth, image.pixelHeight);
image.format = RGB;
}
}
@@ -5960,9 +5966,9 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.disable(PGL.BLEND);
pgl.drawTexture(texture.glTarget, texture.glName,
texture.glWidth, texture.glHeight,
0, 0, width, height,
0, 0, pixelWidth, pixelHeight, 1,
x, y, x + w, y + h,
x, height - (y + h), x + w, height - y);
x, pixelHeight - (y + h), x + w, pixelHeight - y);
pgl.enable(PGL.BLEND);
}
}
@@ -5997,7 +6003,7 @@ public class PGraphicsOpenGL extends PGraphics {
@Override
public void mask(PImage alpha) {
updatePixelSize();
if (alpha.width != pixelWidth || alpha.height != pixelHeight) {
if (alpha.pixelWidth != pixelWidth || alpha.pixelHeight != pixelHeight) {
throw new RuntimeException("The PImage used with mask() must be " +
"the same size as the applet.");
}
@@ -6358,8 +6364,8 @@ public class PGraphicsOpenGL extends PGraphics {
if (tex == null) return null;
if (img.isModified()) {
if (img.width != tex.width || img.height != tex.height) {
tex.init(img.width, img.height);
if (img.pixelWidth != tex.width || img.pixelHeight != tex.height) {
tex.init(img.pixelWidth, img.pixelHeight);
}
updateTexture(img, tex);
}
@@ -6485,8 +6491,8 @@ public class PGraphicsOpenGL extends PGraphics {
// avoid initializing the pixels array.
PImage img = new PImage();
img.parent = parent;
img.width = tex.width;
img.height = tex.height;
img.width = img.pixelWidth = tex.width;
img.height = img.pixelHeight = tex.height;
img.format = ARGB;
setCache(img, tex);
return img;
+85 -154
View File
@@ -94,8 +94,6 @@ public class PSurfaceJOGL implements PSurface {
protected PApplet sketch;
protected PGraphics graphics;
protected int sketchX;
protected int sketchY;
protected int sketchWidth0;
protected int sketchHeight0;
protected int sketchWidth;
@@ -103,13 +101,14 @@ public class PSurfaceJOGL implements PSurface {
protected Display display;
protected Screen screen;
protected List<MonitorDevice> monitors;
protected MonitorDevice displayDevice;
protected Rectangle displayRect;
protected Throwable drawException;
private final Object drawExceptionMutex = new Object();
protected NewtCanvasAWT canvas;
protected int windowScaleFactor;
protected float[] currentPixelScale = {0, 0};
protected boolean external = false;
@@ -151,103 +150,35 @@ public class PSurfaceJOGL implements PSurface {
protected void initDisplay() {
Display tmpDisplay = NewtFactory.createDisplay(null);
tmpDisplay.addReference();
Screen tmpScreen = NewtFactory.createScreen(tmpDisplay, 0);
tmpScreen.addReference();
display = NewtFactory.createDisplay(null);
display.addReference();
screen = NewtFactory.createScreen(display, 0);
screen.addReference();
monitors = new ArrayList<MonitorDevice>();
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] awtDevices = environment.getScreenDevices();
List<MonitorDevice> newtDevices = tmpScreen.getMonitorDevices();
// AWT and NEWT name devices in different ways, depending on the platform,
// and also appear to order them in different ways. The following code
// tries to address the differences.
if (PApplet.platform == PConstants.LINUX) {
for (GraphicsDevice device: awtDevices) {
String did = device.getIDstring();
String[] parts = did.split("\\.");
String id1 = "";
if (1 < parts.length) {
id1 = parts[1].trim();
}
MonitorDevice monitor = null;
int id0 = newtDevices.size() > 0 ? newtDevices.get(0).getId() : 0;
for (int i = 0; i < newtDevices.size(); i++) {
MonitorDevice mon = newtDevices.get(i);
String mid = String.valueOf(mon.getId() - id0);
if (id1.equals(mid)) {
monitor = mon;
break;
}
}
if (monitor != null) {
monitors.add(monitor);
}
}
} else if (PApplet.platform == PConstants.WINDOWS) {
// NEWT display id is == (adapterId << 8 | monitorId),
// should be in the same order as AWT
monitors.addAll(newtDevices);
} else { // MAC OSX and others
for (GraphicsDevice device: awtDevices) {
String did = device.getIDstring();
String[] parts = did.split("Display");
String id1 = "";
if (1 < parts.length) {
id1 = parts[1].trim();
}
MonitorDevice monitor = null;
for (int i = 0; i < newtDevices.size(); i++) {
MonitorDevice mon = newtDevices.get(i);
String mid = String.valueOf(mon.getId());
if (id1.equals(mid)) {
monitor = mon;
break;
}
}
if (monitor == null) {
// Didn't find a matching monitor, try using less stringent id check
for (int i = 0; i < newtDevices.size(); i++) {
MonitorDevice mon = newtDevices.get(i);
String mid = String.valueOf(mon.getId());
if (-1 < did.indexOf(mid)) {
monitor = mon;
break;
}
}
}
if (monitor != null) {
monitors.add(monitor);
}
}
}
displayDevice = null;
GraphicsDevice awtDisplayDevice = null;
int displayNum = sketch.sketchDisplay();
if (displayNum > 0) { // if -1, use the default device
if (displayNum <= monitors.size()) {
displayDevice = monitors.get(displayNum - 1);
if (displayNum <= awtDevices.length) {
awtDisplayDevice = awtDevices[displayNum-1];
} else {
System.err.format("Display %d does not exist, " +
"using the default display instead.%n", displayNum);
for (int i = 0; i < monitors.size(); i++) {
System.err.format("Display %d is %s%n", i+1, monitors.get(i));
for (int i = 0; i < awtDevices.length; i++) {
System.err.format("Display %d is %s%n", i+1, awtDevices[i]);
}
}
} else if (0 < monitors.size()) {
displayDevice = monitors.get(0);
} else if (0 < awtDevices.length) {
awtDisplayDevice = awtDevices[0];
}
if (displayDevice != null) {
screen = displayDevice.getScreen();
display = screen.getDisplay();
} else {
screen = tmpScreen;
display = tmpDisplay;
displayDevice = screen.getPrimaryMonitor();
if (awtDisplayDevice == null) {
awtDisplayDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
}
displayRect = awtDisplayDevice.getDefaultConfiguration().getBounds();
}
@@ -330,13 +261,15 @@ public class PSurfaceJOGL implements PSurface {
// window = GLWindow.create(displayDevice.getScreen(), pgl.getCaps());
// }
windowScaleFactor = PApplet.platform == PConstants.MACOSX ?
1 : sketch.pixelDensity;
boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN;
screenRect = spanDisplays ?
new Rectangle(0, 0, screen.getWidth(), screen.getHeight()) :
new Rectangle(0, 0,
displayDevice.getViewportInWindowUnits().getWidth(),
displayDevice.getViewportInWindowUnits().getHeight());
new Rectangle(screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight()) :
new Rectangle((int) displayRect.getX(), (int) displayRect.getY(),
(int) displayRect.getWidth(),
(int) displayRect.getHeight());
// Set the displayWidth/Height variables inside PApplet, so that they're
// usable and can even be returned by the sketchWidth()/Height() methods.
@@ -385,12 +318,14 @@ public class PSurfaceJOGL implements PSurface {
*/
if (fullScreen || spanDisplays) {
sketchWidth = screenRect.width;
sketchHeight = screenRect.height;
sketchWidth = screenRect.width / windowScaleFactor;
sketchHeight = screenRect.height / windowScaleFactor;
}
sketch.setSize(sketchWidth, sketchHeight);
float[] reqSurfacePixelScale;
if (graphics.is2X()) {
if (graphics.is2X() && PApplet.platform == PConstants.MACOSX) {
// Retina
reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE,
ScalableSurface.AUTOMAX_PIXELSCALE };
@@ -400,19 +335,17 @@ public class PSurfaceJOGL implements PSurface {
ScalableSurface.IDENTITY_PIXELSCALE };
}
window.setSurfaceScale(reqSurfacePixelScale);
window.setSize(sketchWidth, sketchHeight);
window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor);
window.setResizable(false);
setSize(sketchWidth, sketchHeight);
sketchX = displayDevice.getViewportInWindowUnits().getX();
sketchY = displayDevice.getViewportInWindowUnits().getY();
if (fullScreen) {
PApplet.hideMenuBar();
window.setTopLevelPosition(sketchX, sketchY);
if (spanDisplays) {
window.setFullscreen(monitors);
window.setFullscreen(screen.getMonitorDevices());
} else {
List<MonitorDevice> display = Collections.singletonList(displayDevice);
window.setFullscreen(display);
window.setUndecorated(true);
window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
}
}
}
@@ -688,6 +621,11 @@ public class PSurfaceJOGL implements PSurface {
@Override
public void placeWindow(int[] location, int[] editorLocation) {
if (sketch.sketchFullScreen()) {
return;
}
int x = window.getX() - window.getInsets().getLeftWidth();
int y = window.getY() - window.getInsets().getTopHeight();
int w = window.getWidth() + window.getInsets().getTotalWidth();
@@ -728,10 +666,8 @@ public class PSurfaceJOGL implements PSurface {
} else { // just center on screen
// Can't use frame.setLocationRelativeTo(null) because it sends the
// frame to the main display, which undermines the --display setting.
int sketchX = displayDevice.getViewportInWindowUnits().getX();
int sketchY = displayDevice.getViewportInWindowUnits().getY();
window.setTopLevelPosition(sketchX + screenRect.x + (screenRect.width - sketchWidth) / 2,
sketchY + screenRect.y + (screenRect.height - sketchHeight) / 2);
window.setTopLevelPosition(screenRect.x + (screenRect.width - sketchWidth) / 2,
screenRect.y + (screenRect.height - sketchHeight) / 2);
}
Point frameLoc = new Point(x, y);
@@ -744,13 +680,14 @@ public class PSurfaceJOGL implements PSurface {
public void placePresent(int stopColor) {
pgl.initPresentMode(0.5f * (screenRect.width - sketchWidth),
0.5f * (screenRect.height - sketchHeight), stopColor);
window.setSize(screenRect.width, screenRect.height);
float scale = getPixelScale();
pgl.initPresentMode(0.5f * (screenRect.width/scale - sketchWidth),
0.5f * (screenRect.height/scale - sketchHeight), stopColor);
PApplet.hideMenuBar();
window.setTopLevelPosition(sketchX + screenRect.x,
sketchY + screenRect.y);
window.setFullscreen(true);
window.setUndecorated(true);
window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY());
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
}
@@ -813,29 +750,39 @@ public class PSurfaceJOGL implements PSurface {
public void setSize(final int width, final int height) {
if (width == sketch.width && height == sketch.height) {
return;
}
if (pgl.presentMode()) return;
if (!pgl.presentMode()) {
sketch.setSize(width, height);
sketchWidth = width;
sketchHeight = height;
graphics.setSize(width, height);
window.setSize(width, height);
boolean changed = sketch.width != width || sketch.height != height;
sketchWidth = width;
sketchHeight = height;
sketch.setSize(width, height);
graphics.setSize(width, height);
if (changed) {
window.setSize(width * windowScaleFactor, height * windowScaleFactor);
}
}
public float getPixelScale() {
if (graphics.is2X()) {
// Even if the graphics are retina, the user might have moved the window
// into a non-retina monitor, so we need to check
window.getCurrentSurfaceScale(currentPixelScale);
return currentPixelScale[0];
} else {
if (graphics.pixelDensity == 1) {
return 1;
}
if (PApplet.platform == PConstants.MACOSX) {
return getCurrentPixelScale();
}
return 2;
}
private float getCurrentPixelScale() {
// Even if the graphics are retina, the user might have moved the window
// into a non-retina monitor, so we need to check
window.getCurrentSurfaceScale(currentPixelScale);
return currentPixelScale[0];
}
@@ -938,32 +885,11 @@ public class PSurfaceJOGL implements PSurface {
}
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
// int c = graphics.backgroundColor;
// pgl.clearColor(((c >> 16) & 0xff) / 255f,
// ((c >> 8) & 0xff) / 255f,
// ((c >> 0) & 0xff) / 255f,
// ((c >> 24) & 0xff) / 255f);
// pgl.clear(PGL.COLOR_BUFFER_BIT);
pgl.resetFBOLayer();
// final float[] valReqSurfacePixelScale = window.getRequestedSurfaceScale(new float[2]);
window.getCurrentSurfaceScale(currentPixelScale);
// final float[] nativeSurfacePixelScale = window.getMaximumSurfaceScale(new float[2]);
// System.err.println("[set PixelScale post]: "+
// valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
// hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+" (has), "+
// nativeSurfacePixelScale[0]+"x"+nativeSurfacePixelScale[1]+" (native)");
// System.out.println("reshape: " + w + ", " + h);
pgl.getGL(drawable);
// if (!graphics.is2X() && 1 < hasSurfacePixelScale[0]) {
// setSize(w/2, h/2);
// } else {
// setSize(w, h);
// }
setSize((int)(w/currentPixelScale[0]), (int)(h/currentPixelScale[1]));
float scale = PApplet.platform == PConstants.MACOSX ?
getCurrentPixelScale() : getPixelScale();
setSize((int) (w / scale), (int) (h / scale));
}
}
@@ -1111,9 +1037,14 @@ public class PSurfaceJOGL implements PSurface {
peCount = nativeEvent.getClickCount();
}
window.getCurrentSurfaceScale(currentPixelScale);
int sx = (int)(nativeEvent.getX()/currentPixelScale[0]);
int sy = (int)(nativeEvent.getY()/currentPixelScale[1]);
int scale;
if (PApplet.platform == PConstants.MACOSX) {
scale = (int) getCurrentPixelScale();
} else {
scale = (int) getPixelScale();
}
int sx = nativeEvent.getX() / scale;
int sy = nativeEvent.getY() / scale;
int mx = sx;
int my = sy;
@@ -1121,7 +1052,7 @@ public class PSurfaceJOGL implements PSurface {
mx -= (int)pgl.presentX;
my -= (int)pgl.presentY;
if (peAction == KeyEvent.RELEASE &&
pgl.insideStopButton(sx, sy - screenRect.height)) {
pgl.insideStopButton(sx, sy - screenRect.height / windowScaleFactor)) {
sketch.exit();
}
if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) {
@@ -24,6 +24,7 @@ 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;
@@ -466,6 +467,10 @@ 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");
}
params.append(build.getSketchClassName());
}
// Add command-line arguments to be given to the sketch itself