mirror of
https://github.com/processing/processing4.git
synced 2026-05-31 04:28:06 +02:00
Merge pull request #5011 from JakubValtar/blow-up
Window placement and pixel density cleanup
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user