mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
further work on retina and improving performance
This commit is contained in:
@@ -228,6 +228,9 @@ public class PApplet extends Applet
|
||||
* This setting must be called before any AWT work happens, so that's why
|
||||
* it's such a terrible hack in how it's employed here. Calling setProperty()
|
||||
* inside setup() is a joke, since it's long since the AWT has been invoked.
|
||||
* <p/>
|
||||
* On OS X with a retina display, this option is ignored, because Apple's
|
||||
* Java implementation takes over and forces the Quartz renderer.
|
||||
*/
|
||||
// static public boolean useQuartz = true;
|
||||
static public boolean useQuartz = false;
|
||||
@@ -254,6 +257,13 @@ public class PApplet extends Applet
|
||||
/** The frame containing this applet (if any) */
|
||||
public Frame frame;
|
||||
|
||||
// disabled on retina inside init()
|
||||
boolean useActive = true;
|
||||
// boolean useActive = false;
|
||||
// boolean useStrategy = true;
|
||||
boolean useStrategy = false;
|
||||
Canvas canvas;
|
||||
|
||||
// /**
|
||||
// * Usually just 0, but with multiple displays, the X and Y coordinates of
|
||||
// * the screen will depend on the current screen's position relative to
|
||||
@@ -818,6 +828,11 @@ public class PApplet extends Applet
|
||||
/** true if this sketch is being run by the PDE */
|
||||
boolean external = false;
|
||||
|
||||
/**
|
||||
* Not official API, using internally because of the tweaks required.
|
||||
*/
|
||||
boolean retina;
|
||||
|
||||
|
||||
static final String ERROR_MIN_MAX =
|
||||
"Cannot use min() or max() on an empty array.";
|
||||
@@ -841,6 +856,20 @@ public class PApplet extends Applet
|
||||
// screenWidth = screen.width;
|
||||
// screenHeight = screen.height;
|
||||
|
||||
if (platform == MACOSX) {
|
||||
Float prop = (Float)
|
||||
getToolkit().getDesktopProperty("apple.awt.contentScaleFactor");
|
||||
if (prop != null) {
|
||||
retina = prop == 2;
|
||||
if (retina) {
|
||||
// The active-mode rendering seems to be 2x slower, so disable it
|
||||
// with retina. On a non-retina machine, however, useActive seems
|
||||
// the only (or best?) way to handle the rendering.
|
||||
useActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send tab keys through to the PApplet
|
||||
setFocusTraversalKeysEnabled(false);
|
||||
|
||||
@@ -1930,6 +1959,10 @@ public class PApplet extends Applet
|
||||
}
|
||||
*/
|
||||
|
||||
// if (useActive) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (insideDraw) {
|
||||
// new Exception().printStackTrace(System.out);
|
||||
// }
|
||||
@@ -1947,11 +1980,6 @@ public class PApplet extends Applet
|
||||
}
|
||||
|
||||
|
||||
boolean useActive = true;
|
||||
// boolean useStrategy = true;
|
||||
boolean useStrategy = false;
|
||||
Canvas canvas;
|
||||
|
||||
protected synchronized void render() {
|
||||
if (canvas == null) {
|
||||
removeListeners(this);
|
||||
|
||||
@@ -467,7 +467,10 @@ public interface PConstants {
|
||||
static final int ENABLE_STROKE_PURE = 9;
|
||||
static final int DISABLE_STROKE_PURE = -9;
|
||||
|
||||
static final int HINT_COUNT = 10;
|
||||
static final int ENABLE_RETINA_PIXELS = 10;
|
||||
static final int DISABLE_RETINA_PIXELS = -10;
|
||||
|
||||
static final int HINT_COUNT = 11;
|
||||
|
||||
// error messages
|
||||
|
||||
|
||||
@@ -2363,7 +2363,12 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
|
||||
|
||||
@Override
|
||||
// public PImage getImpl(int x, int y, int w, int h) {
|
||||
public PImage get() {
|
||||
return get(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void getImpl(int sourceX, int sourceY,
|
||||
int sourceWidth, int sourceHeight,
|
||||
PImage target, int targetX, int targetY) {
|
||||
@@ -2393,12 +2398,6 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PImage get() {
|
||||
return get(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, int argb) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return;
|
||||
@@ -2410,9 +2409,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
}
|
||||
|
||||
|
||||
//public void set(int x, int y, PImage img)
|
||||
|
||||
|
||||
// protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh,
|
||||
// PImage src) {
|
||||
@Override
|
||||
protected void setImpl(PImage sourceImage,
|
||||
int sourceX, int sourceY,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package processing.core;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
|
||||
public class PGraphicsRetina2D extends PGraphicsJava2D {
|
||||
PImage retina;
|
||||
// int retinaWidth;
|
||||
// int retinaHeight;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
@@ -12,7 +14,17 @@ public class PGraphicsRetina2D extends PGraphicsJava2D {
|
||||
// INTERNAL
|
||||
|
||||
|
||||
public PGraphicsRetina2D() { }
|
||||
public PGraphicsRetina2D() {
|
||||
retina = new PImage();
|
||||
retina.format = RGB;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setParent(PApplet parent) {
|
||||
super.setParent(parent);
|
||||
retina.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@@ -80,16 +92,18 @@ public class PGraphicsRetina2D extends PGraphicsJava2D {
|
||||
// g2 = (Graphics2D) parent.getGraphics();
|
||||
|
||||
GraphicsConfiguration gc = parent.getGraphicsConfiguration();
|
||||
if (false) {
|
||||
if (image == null || ((VolatileImage) image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
image = gc.createCompatibleVolatileImage(width*2, height*2);
|
||||
}
|
||||
} else {
|
||||
if (image == null) {
|
||||
image = gc.createCompatibleImage(width*2, height*2);
|
||||
// if (false) {
|
||||
// if (image == null || ((VolatileImage) image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
// image = gc.createCompatibleVolatileImage(width*2, height*2);
|
||||
// }
|
||||
// } else {
|
||||
if (image == null) {
|
||||
retina.width = width * 2;
|
||||
retina.height = height * 2;
|
||||
image = gc.createCompatibleImage(retina.width, retina.height);
|
||||
// System.out.println("image type is " + image);
|
||||
}
|
||||
}
|
||||
// }
|
||||
g2 = (Graphics2D) image.getGraphics();
|
||||
// g2.scale(2, 2);
|
||||
|
||||
@@ -190,129 +204,430 @@ public class PGraphicsRetina2D extends PGraphicsJava2D {
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
// int[] retinaPixels;
|
||||
|
||||
@Override
|
||||
public void loadPixels() {
|
||||
nope("loadPixels");
|
||||
if ((retina.pixels == null) || (retina.pixels.length != retina.width * retina.height)) {
|
||||
retina.pixels = new int[retina.width * retina.height];
|
||||
}
|
||||
getRaster().getDataElements(0, 0, retina.width, retina.height, retina.pixels);
|
||||
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
pixels = retina.pixels;
|
||||
|
||||
} else {
|
||||
if ((pixels == null) || (pixels.length != width * height)) {
|
||||
pixels = new int[width * height];
|
||||
}
|
||||
int offset = 0;
|
||||
int roffset = 0;
|
||||
// int offset01 = 1;
|
||||
// int offset10 = retinaWidth;
|
||||
// int offset11 = retinaWidth + 1;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int px00 = retina.pixels[roffset];
|
||||
int px01 = retina.pixels[roffset + 1];
|
||||
int px10 = retina.pixels[roffset + retina.width];
|
||||
int px11 = retina.pixels[roffset + retina.width + 1];
|
||||
|
||||
int red = ((((px00 >> 16) & 0xff) +
|
||||
((px01 >> 16) & 0xff) +
|
||||
((px10 >> 16) & 0xff) +
|
||||
((px11 >> 16) & 0xff)) << 14) & 0xFF0000;
|
||||
|
||||
int green = ((((px00 >> 8) & 0xff) +
|
||||
((px01 >> 8) & 0xff) +
|
||||
((px10 >> 8) & 0xff) +
|
||||
((px11 >> 8) & 0xff)) << 6) & 0xFF00;
|
||||
|
||||
int blue = (((px00 & 0xff) +
|
||||
(px01 & 0xff) +
|
||||
(px10 & 0xff) +
|
||||
(px11 & 0xff)) >> 2) & 0xFF;
|
||||
|
||||
pixels[offset++] = 0xff000000 | red | green | blue;
|
||||
roffset += 2;
|
||||
// offset01 += 2;
|
||||
// offset10 += 2;
|
||||
// offset11 += 2;
|
||||
}
|
||||
roffset += retina.width;
|
||||
// offset01 += retinaWidth;
|
||||
// offset10 += retinaWidth;
|
||||
// offset11 += retinaWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the pixels[] buffer to the PGraphics image.
|
||||
* <P>
|
||||
* Unlike in PImage, where updatePixels() only requests that the
|
||||
* update happens, in PGraphicsJava2D, this will happen immediately.
|
||||
*/
|
||||
@Override
|
||||
public void updatePixels() {
|
||||
nope("updatePixels");
|
||||
if (!hints[ENABLE_RETINA_PIXELS]) {
|
||||
int offset = 0;
|
||||
int roffset = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int orig = pixels[offset++];
|
||||
retina.pixels[roffset] = orig;
|
||||
retina.pixels[roffset + 1] = orig;
|
||||
retina.pixels[roffset + retina.width] = orig;
|
||||
retina.pixels[roffset + retina.width + 1] = orig;
|
||||
}
|
||||
roffset += retina.width;
|
||||
}
|
||||
}
|
||||
getRaster().setDataElements(0, 0, retina.width, retina.height, retina.pixels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePixels(int x, int y, int c, int d) {
|
||||
nope("updatePixels");
|
||||
}
|
||||
|
||||
//
|
||||
// No override necessary, just prints a warning and calls updatePixels()
|
||||
//public void updatePixels(int x, int y, int c, int d);
|
||||
|
||||
|
||||
static int rgetset[] = new int[4];
|
||||
|
||||
@Override
|
||||
public int get(int x, int y) {
|
||||
nope("get");
|
||||
return 0; // not reached
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
if ((x < 0) || (y < 0) || (x >= retina.width) || (y >= retina.height)) {
|
||||
return 0;
|
||||
}
|
||||
getRaster().getDataElements(x, y, getset);
|
||||
return getset[0];
|
||||
|
||||
} else {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
return 0;
|
||||
}
|
||||
getRaster().getDataElements(x, y, 2, 2, getset);
|
||||
|
||||
int red = ((((rgetset[0] >> 16) & 0xff) +
|
||||
((rgetset[1] >> 16) & 0xff) +
|
||||
((rgetset[2] >> 16) & 0xff) +
|
||||
((rgetset[3] >> 16) & 0xff)) << 14) & 0xFF0000;
|
||||
|
||||
int green = ((((rgetset[0] >> 8) & 0xff) +
|
||||
((rgetset[1] >> 8) & 0xff) +
|
||||
((rgetset[2] >> 8) & 0xff) +
|
||||
((rgetset[3] >> 8) & 0xff)) << 6) & 0xFF00;
|
||||
|
||||
int blue = (((rgetset[0] & 0xff) +
|
||||
(rgetset[1] & 0xff) +
|
||||
(rgetset[2] & 0xff) +
|
||||
(rgetset[3] & 0xff)) >> 2) & 0xFF;
|
||||
|
||||
return 0xff000000 | red | green | blue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PImage get(int x, int y, int c, int d) {
|
||||
nope("get");
|
||||
return null; // not reached
|
||||
public PImage get(int x, int y, int w, int h) {
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
int targetWidth = w;
|
||||
int targetHeight = h;
|
||||
boolean cropped = false;
|
||||
|
||||
if (x < 0) {
|
||||
w += x; // x is negative, removes the left edge from the width
|
||||
targetX = -x;
|
||||
cropped = true;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
h += y; // y is negative, clip the number of rows
|
||||
targetY = -y;
|
||||
cropped = true;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
if (x + w > retina.width) {
|
||||
w = retina.width - x;
|
||||
cropped = true;
|
||||
}
|
||||
if (y + h > retina.height) {
|
||||
h = retina.height - y;
|
||||
cropped = true;
|
||||
}
|
||||
} else {
|
||||
if (x + w > width) {
|
||||
w = width - x;
|
||||
cropped = true;
|
||||
}
|
||||
if (y + h > height) {
|
||||
h = height - y;
|
||||
cropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (w < 0) {
|
||||
w = 0;
|
||||
}
|
||||
if (h < 0) {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
int targetFormat = format;
|
||||
if (cropped && format == RGB) {
|
||||
targetFormat = ARGB;
|
||||
}
|
||||
|
||||
PImage target = new PImage(targetWidth, targetHeight, targetFormat);
|
||||
target.parent = parent; // parent may be null so can't use createImage()
|
||||
if (w > 0 && h > 0) {
|
||||
getImpl(x, y, w, h, target, targetX, targetY);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
// Replaces version found in PImage
|
||||
@Override
|
||||
public PImage get() {
|
||||
nope("get");
|
||||
return null; // not reached
|
||||
loadPixels();
|
||||
PImage outgoing;
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
// outgoing = new PImage(retinaWidth, retinaHeight, RGB);
|
||||
// outgoing.pixels = new int[retinaWidth * retinaHeight];
|
||||
// System.arraycopy(retinaPixels, 0, outgoing.pixels, 0, outgoing.pixels.length);
|
||||
// outgoing.parent = parent;
|
||||
outgoing = retina.get();
|
||||
outgoing.parent = parent;
|
||||
|
||||
} else {
|
||||
outgoing = new PImage(width, height, RGB);
|
||||
outgoing.pixels = new int[width * height];
|
||||
System.arraycopy(pixels, 0, outgoing.pixels, 0, outgoing.pixels.length);
|
||||
outgoing.parent = parent;
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
|
||||
// Found in PGraphicsJava2D
|
||||
//protected void getImpl(int sourceX, int sourceY,
|
||||
// int sourceWidth, int sourceHeight,
|
||||
// PImage target, int targetX, int targetY)
|
||||
|
||||
|
||||
@Override
|
||||
public void set(int x, int y, int argb) {
|
||||
nope("set");
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
if (x >= 0 && y >= 0 && x < retina.width && y < retina.height) {
|
||||
getset[0] = argb;
|
||||
getRaster().setDataElements(x, y, getset);
|
||||
}
|
||||
} else {
|
||||
if (x >= 0 && y >= 0 && x < width && y < height) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rgetset[i] = argb;
|
||||
}
|
||||
getRaster().setDataElements(x, y, 2, 2, rgetset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Replaces version found in PImage
|
||||
@Override
|
||||
public void set(int x, int y, PImage image) {
|
||||
nope("set");
|
||||
public void set(int x, int y, PImage img) {
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int sw = img.width;
|
||||
int sh = img.height;
|
||||
|
||||
if (x < 0) { // off left edge
|
||||
sx -= x;
|
||||
sw += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) { // off top edge
|
||||
sy -= y;
|
||||
sh += y;
|
||||
y = 0;
|
||||
}
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
if (x + sw > retina.width) { // off right edge
|
||||
sw = retina.width - x;
|
||||
}
|
||||
if (y + sh > retina.height) { // off bottom edge
|
||||
sh = retina.height - y;
|
||||
}
|
||||
} else {
|
||||
if (x + sw > width) { // off right edge
|
||||
sw = width - x;
|
||||
}
|
||||
if (y + sh > height) { // off bottom edge
|
||||
sh = height - y;
|
||||
}
|
||||
}
|
||||
|
||||
// this could be nonexistent
|
||||
if ((sw <= 0) || (sh <= 0)) return;
|
||||
|
||||
setImpl(img, sx, sy, sw, sh, x, y);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public void mask(int alpha[]) {
|
||||
nope("mask");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mask(PImage alpha) {
|
||||
nope("mask");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public void filter(int kind) {
|
||||
nope("filter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(int kind, float param) {
|
||||
nope("filter");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public void copy(int sx1, int sy1, int sx2, int sy2,
|
||||
int dx1, int dy1, int dx2, int dy2) {
|
||||
nope("copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(PImage src,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
int dx1, int dy1, int dx2, int dy2) {
|
||||
nope("copy");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void blend(int sx, int sy, int dx, int dy, int mode) {
|
||||
nope("blend");
|
||||
}
|
||||
|
||||
public void blend(PImage src,
|
||||
int sx, int sy, int dx, int dy, int mode) {
|
||||
nope("blend");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blend(int sx1, int sy1, int sx2, int sy2,
|
||||
int dx1, int dy1, int dx2, int dy2, int mode) {
|
||||
nope("blend");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blend(PImage src,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
int dx1, int dy1, int dx2, int dy2, int mode) {
|
||||
nope("blend");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public boolean save(String filename) {
|
||||
nope("save");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
// Handled by PGraphicsJava2D
|
||||
//protected void setImpl(PImage sourceImage,
|
||||
// int sourceX, int sourceY,
|
||||
// int sourceWidth, int sourceHeight,
|
||||
// int targetX, int targetY)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// MASK
|
||||
|
||||
protected void nope(String function) {
|
||||
throw new RuntimeException("No " + function + "() for PGraphicsRetina2D");
|
||||
|
||||
@Override
|
||||
public void mask(int alpha[]) {
|
||||
showMethodWarning("mask");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mask(PImage alpha) {
|
||||
showMethodWarning("mask");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// FILTER
|
||||
|
||||
|
||||
@Override
|
||||
public void filter(int kind) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
loadPixels();
|
||||
// Wrap the pixels as a fake image so that width/height
|
||||
// in the filter() commands work properly.
|
||||
// PImage temp = new PImage();
|
||||
// temp.width = retinaWidth;
|
||||
// temp.height = retinaHeight;
|
||||
// temp.format = RGB;
|
||||
// temp.pixels = retinaPixels;
|
||||
// temp.filter(kind);
|
||||
retina.filter(kind);
|
||||
updatePixels();
|
||||
|
||||
} else {
|
||||
super.filter(kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void filter(int kind, float param) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
loadPixels();
|
||||
retina.filter(kind, param);
|
||||
updatePixels();
|
||||
|
||||
} else {
|
||||
super.filter(kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// COPY
|
||||
|
||||
|
||||
@Override
|
||||
public void copy(int sx, int sy, int sw, int sh,
|
||||
int dx, int dy, int dw, int dh) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
super.copy(sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
|
||||
} else {
|
||||
// Since copying into itself, double pixels for both src and dest
|
||||
if ((sw != dw) || (sh != dh)) {
|
||||
g2.drawImage(image,
|
||||
dx*2, dy*2, (dx + dw)*2, (dy + dh)*2,
|
||||
sx*2, sy*2, (sx + sw)*2, (sy + sh)*2, null);
|
||||
} else {
|
||||
dx = dx - sx; // java2d's "dx" is the delta, not dest
|
||||
dy = dy - sy;
|
||||
g2.copyArea(sx*2, sy*2, sw*2, sh*2, dx*2, dy*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void copy(PImage src,
|
||||
int sx, int sy, int sw, int sh,
|
||||
int dx, int dy, int dw, int dh) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
super.copy(src, sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
|
||||
} else {
|
||||
// Double the pixels from the source image when drawing into dest
|
||||
g2.drawImage((Image) src.getNative(),
|
||||
dx*2, dy*2, (dx + dw)*2, (dy + dh)*2,
|
||||
sx, sy, sx + sw, sy + sh, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// BLEND
|
||||
|
||||
|
||||
@Override
|
||||
public void blend(int sx, int sy, int sw, int sh,
|
||||
int dx, int dy, int dw, int dh, int mode) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
retina.blend(sx, sy, sw, sh, dx, dy, dw, dh, mode);
|
||||
} else {
|
||||
super.blend(sx, sy, sw, sh, dx, dy, dw, dh, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void blend(PImage src,
|
||||
int sx, int sy, int sw, int sh,
|
||||
int dx, int dy, int dw, int dh, int mode) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
retina.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, mode);
|
||||
} else {
|
||||
super.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SAVE
|
||||
|
||||
|
||||
@Override
|
||||
public boolean save(String filename) {
|
||||
if (hints[ENABLE_RETINA_PIXELS]) {
|
||||
return retina.save(filename);
|
||||
} else {
|
||||
return super.save(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -832,6 +832,16 @@ public class PImage implements PConstants, Cloneable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a copy of this PImage. Equivalent to get(0, 0, width, height).
|
||||
*/
|
||||
public PImage get() {
|
||||
// Formerly this used clone(), which caused memory problems.
|
||||
// http://code.google.com/p/processing/issues/detail?id=42
|
||||
return get(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal function to actually handle getting a block of pixels that
|
||||
* has already been properly cropped to a valid region. That is, x/y/w/h
|
||||
@@ -851,16 +861,6 @@ public class PImage implements PConstants, Cloneable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a copy of this PImage. Equivalent to get(0, 0, width, height).
|
||||
*/
|
||||
public PImage get() {
|
||||
// Formerly this used clone(), which caused memory problems.
|
||||
// http://code.google.com/p/processing/issues/detail?id=42
|
||||
return get(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ( begin auto-generated from PImage_set.xml )
|
||||
*
|
||||
|
||||
+6
-2
@@ -120,11 +120,11 @@ _ and how it should be handled with hash/dict
|
||||
_ right now using hasKey().. in JSONObject
|
||||
|
||||
_ add mouse wheel support to 2.0 event system
|
||||
_ http://code.google.com/p/processing/issues/detail?id=1423
|
||||
X this is fairly messy since desktop and JS behave a little differently
|
||||
o wheel event should subclass mouse (since position still relevant)
|
||||
X just another sub-event as part of mouse
|
||||
o might be more effort than it's worth?
|
||||
_ http://code.google.com/p/processing/issues/detail?id=1423
|
||||
X peasycam uses e.getWheelRotation()
|
||||
X js has a couple versions
|
||||
X http://www.javascriptkit.com/javatutors/onmousewheel.shtml
|
||||
@@ -132,9 +132,12 @@ X e.detail is 1 for 1 click up, -2 for 2 clicks down
|
||||
X e.wheelDelta is 120 for 1 click up, -240 for two clicks down
|
||||
X using float value (/120.0f)
|
||||
X high-precision method grabbed if 1.7 is in use
|
||||
_ test with actual
|
||||
_ test with actual wheel mouse
|
||||
_ test on Windows
|
||||
_ add to the API docs
|
||||
_ decide on getAmount() and weirdness w/ clickCount
|
||||
_ get mouseWheel() added to api ref
|
||||
_ also added to keywords.txt
|
||||
|
||||
andres
|
||||
_ P2D/P3D sketches don't get focus until click
|
||||
@@ -144,6 +147,7 @@ _ OpenGL/P3D sketches show graphical corruption
|
||||
_ http://code.google.com/p/processing/issues/detail?id=1452
|
||||
_ noCursor() seems quite/somewhat broken
|
||||
X started some work, ignores 'invisible' already being set
|
||||
_ several key/mouse event issues in the db
|
||||
|
||||
_ add 'gz' as one of the loadXxx() options
|
||||
_ helps .svgz case from being weird, also generally dealing w/ compressed data
|
||||
|
||||
Reference in New Issue
Block a user