propane 3.3.1-java → 3.4.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mvn/wrapper/MavenWrapperDownloader.java +117 -0
- data/.mvn/wrapper/maven-wrapper.properties +2 -3
- data/.travis.yml +9 -0
- data/CHANGELOG.md +7 -5
- data/README.md +1 -1
- data/Rakefile +8 -21
- data/lib/propane/native_folder.rb +16 -11
- data/lib/propane/version.rb +1 -1
- data/mvnw +127 -51
- data/mvnw.cmd +182 -145
- data/pom.rb +50 -48
- data/pom.xml +15 -6
- data/propane.gemspec +3 -3
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
- data/src/main/java/monkstone/vecmath/vec3/Vec3.java +2 -2
- data/src/main/java/processing/awt/PGraphicsJava2D.java +1616 -1609
- data/src/main/java/processing/awt/PShapeJava2D.java +273 -265
- data/src/main/java/processing/awt/PSurfaceAWT.java +830 -817
- data/src/main/java/processing/core/PApplet.java +3990 -3990
- data/src/main/java/processing/core/PGraphics.java +37 -37
- data/src/main/java/processing/core/PImage.java +9 -9
- data/src/main/java/processing/core/PMatrix2D.java +6 -0
- data/src/main/java/processing/core/PShape.java +2 -2
- data/src/main/java/processing/core/PShapeOBJ.java +425 -409
- data/src/main/java/processing/core/PShapeSVG.java +167 -159
- data/src/main/java/processing/core/PSurfaceNone.java +10 -0
- data/src/main/java/processing/core/ThinkDifferent.java +7 -14
- data/src/main/java/processing/event/Event.java +7 -6
- metadata +9 -7
data/propane.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.summary = %q{ruby implementation of processing-4.0 on MacOS, linux and windows (64bit only)}
|
16
16
|
gem.homepage = 'https://ruby-processing.github.io/propane/'
|
17
17
|
gem.files = `git ls-files`.split($/)
|
18
|
-
gem.files << 'lib/propane-3.
|
18
|
+
gem.files << 'lib/propane-3.4.0.jar'
|
19
19
|
gem.files << 'lib/gluegen-rt.jar'
|
20
20
|
gem.files << 'lib/jogl-all.jar'
|
21
21
|
gem.files << 'lib/gluegen-rt-natives-linux-amd64.jar'
|
@@ -27,9 +27,9 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
28
28
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
29
29
|
gem.add_development_dependency 'rake', '~> 12.3'
|
30
|
-
gem.add_development_dependency 'minitest', '~> 5.
|
30
|
+
gem.add_development_dependency 'minitest', '~> 5.11'
|
31
31
|
gem.add_runtime_dependency 'arcball', '~> 1.0', '>= 1.0.0'
|
32
32
|
gem.require_paths = ['lib']
|
33
33
|
gem.platform = 'java'
|
34
|
-
gem.requirements << 'java runtime >= 11.0.
|
34
|
+
gem.requirements << 'java runtime >= 11.0.2+'
|
35
35
|
end
|
@@ -399,7 +399,7 @@ public class Vec2 extends RubyObject {
|
|
399
399
|
@JRubyMethod(name = "set_mag")
|
400
400
|
|
401
401
|
public IRubyObject set_mag(ThreadContext context, IRubyObject scalar, Block block) {
|
402
|
-
double new_mag =
|
402
|
+
double new_mag = scalar.toJava(Double.class);
|
403
403
|
if (block.isGiven()) {
|
404
404
|
if (!(boolean) block.yield(context, scalar).toJava(Boolean.class)) {
|
405
405
|
return this;
|
@@ -385,7 +385,7 @@ public final class Vec3 extends RubyObject {
|
|
385
385
|
@JRubyMethod(name = "/", required = 1)
|
386
386
|
public IRubyObject op_div(ThreadContext context, IRubyObject scalar) {
|
387
387
|
Ruby runtime = context.runtime;
|
388
|
-
|
388
|
+
var divisor = (scalar instanceof RubyFloat)
|
389
389
|
? ((RubyFloat) scalar).getValue() : ((RubyFixnum) scalar).getDoubleValue();
|
390
390
|
if (Math.abs(divisor) < Vec3.EPSILON) {
|
391
391
|
return this;
|
@@ -432,7 +432,7 @@ public final class Vec3 extends RubyObject {
|
|
432
432
|
return this;
|
433
433
|
}
|
434
434
|
}
|
435
|
-
|
435
|
+
var new_mag = (scalar instanceof RubyFloat)
|
436
436
|
? ((RubyFloat) scalar).getValue() : ((RubyFixnum) scalar).getDoubleValue();
|
437
437
|
double current = Math.sqrt(jx * jx + jy * jy + jz * jz);
|
438
438
|
if (current > EPSILON) {
|
@@ -57,58 +57,58 @@ public class PGraphicsJava2D extends PGraphics {
|
|
57
57
|
//// boolean useOffscreen = true; // ~40fps
|
58
58
|
// boolean useOffscreen = false;
|
59
59
|
|
60
|
-
|
60
|
+
public Graphics2D g2;
|
61
61
|
// protected BufferedImage offscreen;
|
62
62
|
|
63
|
-
|
63
|
+
Composite defaultComposite;
|
64
64
|
|
65
|
-
|
65
|
+
GeneralPath gpath;
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
// path for contours so gpath can be closed
|
68
|
+
GeneralPath auxPath;
|
69
69
|
|
70
|
-
|
70
|
+
boolean openContour;
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
/// break the shape at the next vertex (next vertex() call is a moveto())
|
73
|
+
boolean breakShape;
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
/// coordinates for internal curve calculation
|
76
|
+
float[] curveCoordX;
|
77
|
+
float[] curveCoordY;
|
78
|
+
float[] curveDrawX;
|
79
|
+
float[] curveDrawY;
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
int transformCount;
|
82
|
+
AffineTransform transformStack[]
|
83
|
+
= new AffineTransform[MATRIX_STACK_DEPTH];
|
84
|
+
double[] transform = new double[6];
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
Line2D.Float line = new Line2D.Float();
|
87
|
+
Ellipse2D.Float ellipse = new Ellipse2D.Float();
|
88
|
+
Rectangle2D.Float rect = new Rectangle2D.Float();
|
89
|
+
Arc2D.Float arc = new Arc2D.Float();
|
90
90
|
|
91
|
-
|
91
|
+
protected Color tintColorObject;
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
protected Color fillColorObject;
|
94
|
+
public boolean fillGradient;
|
95
|
+
public Paint fillGradientObject;
|
96
96
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
97
|
+
protected Stroke strokeObject;
|
98
|
+
protected Color strokeColorObject;
|
99
|
+
public boolean strokeGradient;
|
100
|
+
public Paint strokeGradientObject;
|
101
101
|
|
102
|
-
|
102
|
+
Font fontObject;
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
//////////////////////////////////////////////////////////////
|
105
|
+
// INTERNAL
|
106
|
+
public PGraphicsJava2D() {
|
107
|
+
}
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
//public void setParent(PApplet parent)
|
110
|
+
//public void setPrimary(boolean primary)
|
111
|
+
//public void setPath(String path)
|
112
112
|
// /**
|
113
113
|
// * Called in response to a resize event, handles setting the
|
114
114
|
// * new width and height internally, as well as re-allocating
|
@@ -129,7 +129,7 @@ public class PGraphicsJava2D extends PGraphics {
|
|
129
129
|
// //surface.initImage(this, width, height);
|
130
130
|
// surface.initImage(this);
|
131
131
|
// }
|
132
|
-
|
132
|
+
/*
|
133
133
|
@Override
|
134
134
|
protected void allocate() {
|
135
135
|
// Tried this with RGB instead of ARGB for the primarySurface version,
|
@@ -201,7 +201,7 @@ public class PGraphicsJava2D extends PGraphics {
|
|
201
201
|
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
202
202
|
g2 = (Graphics2D) image.getGraphics();
|
203
203
|
}
|
204
|
-
|
204
|
+
*/
|
205
205
|
|
206
206
|
/*
|
207
207
|
if (primarySurface) {
|
@@ -223,32 +223,36 @@ public class PGraphicsJava2D extends PGraphics {
|
|
223
223
|
}
|
224
224
|
g2 = (Graphics2D) image.getGraphics();
|
225
225
|
}
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
226
|
+
*/
|
227
|
+
//public void dispose()
|
228
|
+
@Override
|
229
|
+
public PSurface createSurface() {
|
230
|
+
return surface = new PSurfaceAWT(this);
|
231
|
+
}
|
232
232
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
233
|
+
/**
|
234
|
+
* Still need a means to get the java.awt.Image object, since getNative() is
|
235
|
+
* going to return the {@link Graphics2D} object.
|
236
|
+
*
|
237
|
+
* @return
|
238
|
+
*/
|
239
|
+
@Override
|
240
|
+
public Image getImage() {
|
241
|
+
return image;
|
242
|
+
}
|
241
243
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
244
|
+
/**
|
245
|
+
* Returns the java.awt.Graphics2D object used by this renderer.
|
246
|
+
*
|
247
|
+
* @return
|
248
|
+
*/
|
249
|
+
@Override
|
250
|
+
public Object getNative() {
|
251
|
+
return g2;
|
252
|
+
}
|
249
253
|
|
250
|
-
|
251
|
-
|
254
|
+
//////////////////////////////////////////////////////////////
|
255
|
+
// FRAME
|
252
256
|
// @Override
|
253
257
|
// public boolean canDraw() {
|
254
258
|
// return true;
|
@@ -262,10 +266,10 @@ public class PGraphicsJava2D extends PGraphics {
|
|
262
266
|
//// });
|
263
267
|
// }
|
264
268
|
// Graphics2D g2old;
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
+
public Graphics2D checkImage() {
|
270
|
+
if (image == null
|
271
|
+
|| ((BufferedImage) image).getWidth() != width * pixelDensity
|
272
|
+
|| ((BufferedImage) image).getHeight() != height * pixelDensity) {
|
269
273
|
// ((VolatileImage) image).getWidth() != width ||
|
270
274
|
// ((VolatileImage) image).getHeight() != height) {
|
271
275
|
// image = new BufferedImage(width * pixelFactor, height * pixelFactor
|
@@ -290,46 +294,46 @@ public class PGraphicsJava2D extends PGraphics {
|
|
290
294
|
// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
291
295
|
// gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
|
292
296
|
// }
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
297
|
+
// Formerly this was broken into separate versions based on offscreen or
|
298
|
+
// not, but we may as well create a compatible image; it won't hurt, right?
|
299
|
+
// P.S.: Three years later, I'm happy to report it did in fact hurt [jv 2018-06-01]
|
300
|
+
int wide = width * pixelDensity;
|
301
|
+
int high = height * pixelDensity;
|
298
302
|
// System.out.println("re-creating image");
|
299
303
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
}
|
309
|
-
return (Graphics2D) image.getGraphics();
|
304
|
+
// For now we expect non-premultiplied INT ARGB and the compatible image
|
305
|
+
// might not be it... create the image directly. It's important that the
|
306
|
+
// image has all four bands, otherwise we get garbage alpha during blending
|
307
|
+
// (see https://github.com/processing/processing/pull/2645,
|
308
|
+
// https://github.com/processing/processing/pull/3523)
|
309
|
+
//
|
310
|
+
// image = gc.createCompatibleImage(wide, high, Transparency.TRANSLUCENT);
|
311
|
+
image = new BufferedImage(wide, high, BufferedImage.TYPE_INT_ARGB);
|
310
312
|
}
|
313
|
+
return (Graphics2D) image.getGraphics();
|
314
|
+
}
|
311
315
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
316
|
+
@Override
|
317
|
+
public void beginDraw() {
|
318
|
+
g2 = checkImage();
|
319
|
+
|
320
|
+
// Calling getGraphics() seems to nuke several settings.
|
321
|
+
// It seems to be re-creating a new Graphics2D object each time.
|
322
|
+
// https://github.com/processing/processing/issues/3331
|
323
|
+
if (strokeObject != null) {
|
324
|
+
g2.setStroke(strokeObject);
|
325
|
+
}
|
326
|
+
// https://github.com/processing/processing/issues/2617
|
327
|
+
if (fontObject != null) {
|
328
|
+
g2.setFont(fontObject);
|
329
|
+
}
|
330
|
+
// https://github.com/processing/processing/issues/4019
|
331
|
+
if (blendMode != 0) {
|
332
|
+
blendMode(blendMode);
|
333
|
+
}
|
334
|
+
handleSmooth();
|
331
335
|
|
332
|
-
|
336
|
+
/*
|
333
337
|
// NOTE: Calling image.getGraphics() will create a new Graphics context,
|
334
338
|
// even if it's for the same image that's already had a context created.
|
335
339
|
// Seems like a speed/memory issue, and also requires that all smoothing,
|
@@ -380,46 +384,46 @@ public class PGraphicsJava2D extends PGraphics {
|
|
380
384
|
reapplySettings = true;
|
381
385
|
}
|
382
386
|
}
|
383
|
-
*/
|
384
|
-
checkSettings();
|
385
|
-
resetMatrix(); // reset model matrix
|
386
|
-
vertexCount = 0;
|
387
|
-
}
|
388
|
-
|
389
|
-
/**
|
390
|
-
* Smoothing for Java2D is 2 for bilinear, and 3 for bicubic (the default).
|
391
|
-
* Internally, smooth(1) is the default, smooth(0) is noSmooth().
|
392
387
|
*/
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
398
|
-
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
399
|
-
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
400
|
-
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
388
|
+
checkSettings();
|
389
|
+
resetMatrix(); // reset model matrix
|
390
|
+
vertexCount = 0;
|
391
|
+
}
|
401
392
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
393
|
+
/**
|
394
|
+
* Smoothing for Java2D is 2 for bilinear, and 3 for bicubic (the default).
|
395
|
+
* Internally, smooth(1) is the default, smooth(0) is noSmooth().
|
396
|
+
*/
|
397
|
+
protected void handleSmooth() {
|
398
|
+
if (smooth == 0) {
|
399
|
+
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
400
|
+
RenderingHints.VALUE_ANTIALIAS_OFF);
|
401
|
+
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
402
|
+
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
403
|
+
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
404
|
+
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
413
405
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
406
|
+
} else {
|
407
|
+
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
408
|
+
RenderingHints.VALUE_ANTIALIAS_ON);
|
409
|
+
|
410
|
+
if (smooth == 1 || smooth == 3) { // default is bicubic
|
411
|
+
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
412
|
+
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
413
|
+
} else if (smooth == 2) {
|
414
|
+
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
415
|
+
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
416
|
+
}
|
417
|
+
|
418
|
+
// http://docs.oracle.com/javase/tutorial/2d/text/renderinghints.html
|
419
|
+
// Oracle Java text anti-aliasing on OS X looks like s*t compared to the
|
420
|
+
// text rendering with Apple's old Java 6. Below, several attempts to fix:
|
421
|
+
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
422
|
+
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
423
|
+
// Turns out this is the one that actually makes things work.
|
424
|
+
// Kerning is still screwed up, however.
|
425
|
+
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
|
426
|
+
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
423
427
|
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
424
428
|
// RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
|
425
429
|
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
@@ -427,17 +431,17 @@ public class PGraphicsJava2D extends PGraphics {
|
|
427
431
|
|
428
432
|
// g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
429
433
|
// RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
430
|
-
}
|
431
434
|
}
|
435
|
+
}
|
432
436
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
437
|
+
@Override
|
438
|
+
public void endDraw() {
|
439
|
+
// hm, mark pixels as changed, because this will instantly do a full
|
440
|
+
// copy of all the pixels to the surface.. so that's kind of a mess.
|
441
|
+
//updatePixels();
|
438
442
|
|
439
|
-
|
440
|
-
|
443
|
+
if (primaryGraphics) {
|
444
|
+
/*
|
441
445
|
//if (canvas != null) {
|
442
446
|
if (useCanvas) {
|
443
447
|
//System.out.println(canvas);
|
@@ -465,11 +469,11 @@ public class PGraphicsJava2D extends PGraphics {
|
|
465
469
|
// g2.dispose();
|
466
470
|
// System.out.println("not doing anything special in endDraw()");
|
467
471
|
}
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
472
|
+
*/
|
473
|
+
} else {
|
474
|
+
// TODO this is probably overkill for most tasks...
|
475
|
+
loadPixels();
|
476
|
+
}
|
473
477
|
|
474
478
|
// // Marking as modified, and then calling updatePixels() in
|
475
479
|
// // the super class, which just sets the mx1, my1, mx2, my2
|
@@ -477,15 +481,15 @@ public class PGraphicsJava2D extends PGraphics {
|
|
477
481
|
// // full copy of the pixels to the surface in this.updatePixels().
|
478
482
|
// setModified();
|
479
483
|
// super.updatePixels();
|
480
|
-
|
481
|
-
|
482
|
-
|
484
|
+
// Marks pixels as modified so that the pixels will be updated.
|
485
|
+
// Also sets mx1/y1/x2/y2 so that OpenGL will pick it up.
|
486
|
+
setModified();
|
483
487
|
|
484
|
-
|
485
|
-
|
488
|
+
g2.dispose();
|
489
|
+
}
|
486
490
|
|
487
491
|
|
488
|
-
|
492
|
+
/*
|
489
493
|
private void redraw() {
|
490
494
|
// only need this check if the validate() call will use redraw()
|
491
495
|
// if (strategy == null) return;
|
@@ -528,12 +532,12 @@ public class PGraphicsJava2D extends PGraphics {
|
|
528
532
|
} while (strategy.contentsLost());
|
529
533
|
PApplet.debug("PGraphicsJava2D.redraw() out of do { } block");
|
530
534
|
}
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
535
|
+
*/
|
536
|
+
//////////////////////////////////////////////////////////////
|
537
|
+
// SETTINGS
|
538
|
+
//protected void checkSettings()
|
539
|
+
@Override
|
540
|
+
protected void defaultSettings() {
|
537
541
|
// if (!useCanvas) {
|
538
542
|
// // Papered over another threading issue...
|
539
543
|
// // See if this comes back now that the other issue is fixed.
|
@@ -543,49 +547,49 @@ public class PGraphicsJava2D extends PGraphics {
|
|
543
547
|
//// Thread.sleep(5);
|
544
548
|
//// } catch (InterruptedException e) { }
|
545
549
|
//// }
|
546
|
-
|
550
|
+
defaultComposite = g2.getComposite();
|
547
551
|
// }
|
548
|
-
|
549
|
-
|
552
|
+
super.defaultSettings();
|
553
|
+
}
|
550
554
|
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
}
|
555
|
+
//protected void reapplySettings()
|
556
|
+
//////////////////////////////////////////////////////////////
|
557
|
+
// HINT
|
558
|
+
@Override
|
559
|
+
public void hint(int which) {
|
560
|
+
// take care of setting the hint
|
561
|
+
super.hint(which);
|
562
|
+
|
563
|
+
// Avoid badness when drawing shorter strokes.
|
564
|
+
// http://code.google.com/p/processing/issues/detail?id=1068
|
565
|
+
// Unfortunately cannot always be enabled, because it makes the
|
566
|
+
// stroke in many standard Processing examples really gross.
|
567
|
+
if (which == ENABLE_STROKE_PURE) {
|
568
|
+
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
569
|
+
RenderingHints.VALUE_STROKE_PURE);
|
570
|
+
} else if (which == DISABLE_STROKE_PURE) {
|
571
|
+
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
572
|
+
RenderingHints.VALUE_STROKE_DEFAULT);
|
570
573
|
}
|
574
|
+
}
|
571
575
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
576
|
+
//////////////////////////////////////////////////////////////
|
577
|
+
// SHAPE CREATION
|
578
|
+
@Override
|
579
|
+
protected PShape createShapeFamily(int type) {
|
580
|
+
return new PShape(this, type);
|
581
|
+
}
|
578
582
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
+
@Override
|
584
|
+
protected PShape createShapePrimitive(int kind, float... p) {
|
585
|
+
return new PShape(this, kind, p);
|
586
|
+
}
|
583
587
|
|
584
588
|
// @Override
|
585
589
|
// public PShape createShape(PShape source) {
|
586
590
|
// return PShapeOpenGL.createShape2D(this, source);
|
587
591
|
// }
|
588
|
-
|
592
|
+
/*
|
589
593
|
protected PShape createShapeImpl(PGraphicsJava2D pg, int type) {
|
590
594
|
PShape shape = null;
|
591
595
|
if (type == PConstants.GROUP) {
|
@@ -599,7 +603,7 @@ public class PGraphicsJava2D extends PGraphics {
|
|
599
603
|
//shape.set3D(false);
|
600
604
|
return shape;
|
601
605
|
}
|
602
|
-
|
606
|
+
*/
|
603
607
|
/*
|
604
608
|
static protected PShape createShapeImpl(PGraphicsJava2D pg,
|
605
609
|
int kind, float... p) {
|
@@ -672,474 +676,465 @@ public class PGraphicsJava2D extends PGraphics {
|
|
672
676
|
|
673
677
|
return shape;
|
674
678
|
}
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
//public boolean edge(boolean e)
|
695
|
-
//public void normal(float nx, float ny, float nz) {
|
696
|
-
//public void textureMode(int mode)
|
697
|
-
@Override
|
698
|
-
public void texture(PImage image) {
|
699
|
-
showMethodWarning("texture");
|
700
|
-
}
|
679
|
+
*/
|
680
|
+
//////////////////////////////////////////////////////////////
|
681
|
+
// SHAPES
|
682
|
+
@Override
|
683
|
+
public void beginShape(int kind) {
|
684
|
+
//super.beginShape(kind);
|
685
|
+
shape = kind;
|
686
|
+
vertexCount = 0;
|
687
|
+
curveVertexCount = 0;
|
688
|
+
|
689
|
+
// set gpath to null, because when mixing curves and straight
|
690
|
+
// lines, vertexCount will be set back to zero, so vertexCount == 1
|
691
|
+
// is no longer a good indicator of whether the shape is new.
|
692
|
+
// this way, just check to see if gpath is null, and if it isn't
|
693
|
+
// then just use it to continue the shape.
|
694
|
+
gpath = null;
|
695
|
+
auxPath = null;
|
696
|
+
}
|
701
697
|
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
698
|
+
//public boolean edge(boolean e)
|
699
|
+
//public void normal(float nx, float ny, float nz) {
|
700
|
+
//public void textureMode(int mode)
|
701
|
+
@Override
|
702
|
+
public void texture(PImage image) {
|
703
|
+
showMethodWarning("texture");
|
704
|
+
}
|
705
|
+
|
706
|
+
@Override
|
707
|
+
public void vertex(float x, float y) {
|
708
|
+
curveVertexCount = 0;
|
709
|
+
//float vertex[];
|
710
|
+
|
711
|
+
if (vertexCount == vertices.length) {
|
712
|
+
float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT];
|
713
|
+
System.arraycopy(vertices, 0, temp, 0, vertexCount);
|
714
|
+
vertices = temp;
|
715
|
+
//message(CHATTER, "allocating more vertices " + vertices.length);
|
716
|
+
}
|
717
|
+
// not everyone needs this, but just easier to store rather
|
718
|
+
// than adding another moving part to the code...
|
719
|
+
vertices[vertexCount][X] = x;
|
720
|
+
vertices[vertexCount][Y] = y;
|
721
|
+
vertexCount++;
|
722
|
+
|
723
|
+
switch (shape) {
|
724
|
+
|
725
|
+
case POINTS:
|
726
|
+
point(x, y);
|
727
|
+
break;
|
728
|
+
|
729
|
+
case LINES:
|
730
|
+
if ((vertexCount % 2) == 0) {
|
731
|
+
line(vertices[vertexCount - 2][X],
|
732
|
+
vertices[vertexCount - 2][Y], x, y);
|
733
|
+
}
|
734
|
+
break;
|
735
|
+
|
736
|
+
case TRIANGLES:
|
737
|
+
if ((vertexCount % 3) == 0) {
|
738
|
+
triangle(vertices[vertexCount - 3][X],
|
739
|
+
vertices[vertexCount - 3][Y],
|
740
|
+
vertices[vertexCount - 2][X],
|
741
|
+
vertices[vertexCount - 2][Y],
|
742
|
+
x, y);
|
743
|
+
}
|
744
|
+
break;
|
745
|
+
|
746
|
+
case TRIANGLE_STRIP:
|
747
|
+
if (vertexCount >= 3) {
|
748
|
+
triangle(vertices[vertexCount - 2][X],
|
749
|
+
vertices[vertexCount - 2][Y],
|
750
|
+
vertices[vertexCount - 1][X],
|
751
|
+
vertices[vertexCount - 1][Y],
|
752
|
+
vertices[vertexCount - 3][X],
|
753
|
+
vertices[vertexCount - 3][Y]);
|
754
|
+
}
|
755
|
+
break;
|
756
|
+
|
757
|
+
case TRIANGLE_FAN:
|
758
|
+
if (vertexCount >= 3) {
|
759
|
+
// This is an unfortunate implementation because the stroke for an
|
760
|
+
// adjacent triangle will be repeated. However, if the stroke is not
|
761
|
+
// redrawn, it will replace the adjacent line (when it lines up
|
762
|
+
// perfectly) or show a faint line (when off by a small amount).
|
763
|
+
// The alternative would be to wait, then draw the shape as a
|
764
|
+
// polygon fill, followed by a series of vertices. But that's a
|
765
|
+
// poor method when used with PDF, DXF, or other recording objects,
|
766
|
+
// since discrete triangles would likely be preferred.
|
767
|
+
triangle(vertices[0][X],
|
768
|
+
vertices[0][Y],
|
769
|
+
vertices[vertexCount - 2][X],
|
770
|
+
vertices[vertexCount - 2][Y],
|
771
|
+
x, y);
|
772
|
+
}
|
773
|
+
break;
|
774
|
+
|
775
|
+
case QUAD:
|
776
|
+
case QUADS:
|
777
|
+
if ((vertexCount % 4) == 0) {
|
778
|
+
quad(vertices[vertexCount - 4][X],
|
779
|
+
vertices[vertexCount - 4][Y],
|
780
|
+
vertices[vertexCount - 3][X],
|
781
|
+
vertices[vertexCount - 3][Y],
|
782
|
+
vertices[vertexCount - 2][X],
|
783
|
+
vertices[vertexCount - 2][Y],
|
784
|
+
x, y);
|
785
|
+
}
|
786
|
+
break;
|
787
|
+
|
788
|
+
case QUAD_STRIP:
|
789
|
+
// 0---2---4
|
790
|
+
// | | |
|
791
|
+
// 1---3---5
|
792
|
+
if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) {
|
793
|
+
quad(vertices[vertexCount - 4][X],
|
794
|
+
vertices[vertexCount - 4][Y],
|
795
|
+
vertices[vertexCount - 2][X],
|
796
|
+
vertices[vertexCount - 2][Y],
|
797
|
+
x, y,
|
798
|
+
vertices[vertexCount - 3][X],
|
799
|
+
vertices[vertexCount - 3][Y]);
|
800
|
+
}
|
801
|
+
break;
|
802
|
+
|
803
|
+
case POLYGON:
|
804
|
+
if (gpath == null) {
|
805
|
+
gpath = new GeneralPath();
|
806
|
+
gpath.moveTo(x, y);
|
807
|
+
} else if (breakShape) {
|
808
|
+
gpath.moveTo(x, y);
|
809
|
+
breakShape = false;
|
810
|
+
} else {
|
811
|
+
gpath.lineTo(x, y);
|
810
812
|
}
|
813
|
+
break;
|
811
814
|
}
|
815
|
+
}
|
812
816
|
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
+
@Override
|
818
|
+
public void vertex(float x, float y, float z) {
|
819
|
+
showDepthWarningXYZ("vertex");
|
820
|
+
}
|
817
821
|
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
+
@Override
|
823
|
+
public void vertex(float[] v) {
|
824
|
+
vertex(v[X], v[Y]);
|
825
|
+
}
|
822
826
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
+
@Override
|
828
|
+
public void vertex(float x, float y, float u, float v) {
|
829
|
+
showVariationWarning("vertex(x, y, u, v)");
|
830
|
+
}
|
827
831
|
|
828
|
-
|
829
|
-
|
830
|
-
|
832
|
+
@Override
|
833
|
+
public void vertex(float x, float y, float z, float u, float v) {
|
834
|
+
showDepthWarningXYZ("vertex");
|
835
|
+
}
|
836
|
+
|
837
|
+
@Override
|
838
|
+
public void beginContour() {
|
839
|
+
if (openContour) {
|
840
|
+
PGraphics.showWarning("Already called beginContour()");
|
841
|
+
return;
|
831
842
|
}
|
832
843
|
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
return;
|
838
|
-
}
|
844
|
+
// draw contours to auxiliary path so main path can be closed later
|
845
|
+
GeneralPath contourPath = auxPath;
|
846
|
+
auxPath = gpath;
|
847
|
+
gpath = contourPath;
|
839
848
|
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
gpath = contourPath;
|
849
|
+
if (contourPath != null) { // first contour does not break
|
850
|
+
breakShape = true;
|
851
|
+
}
|
844
852
|
|
845
|
-
|
846
|
-
|
847
|
-
}
|
853
|
+
openContour = true;
|
854
|
+
}
|
848
855
|
|
849
|
-
|
856
|
+
@Override
|
857
|
+
public void endContour() {
|
858
|
+
if (!openContour) {
|
859
|
+
PGraphics.showWarning("Need to call beginContour() first");
|
860
|
+
return;
|
850
861
|
}
|
851
862
|
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
return;
|
857
|
-
}
|
863
|
+
// close this contour
|
864
|
+
if (gpath != null) {
|
865
|
+
gpath.closePath();
|
866
|
+
}
|
858
867
|
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
868
|
+
// switch back to main path
|
869
|
+
GeneralPath contourPath = gpath;
|
870
|
+
gpath = auxPath;
|
871
|
+
auxPath = contourPath;
|
863
872
|
|
864
|
-
|
865
|
-
|
866
|
-
gpath = auxPath;
|
867
|
-
auxPath = contourPath;
|
873
|
+
openContour = false;
|
874
|
+
}
|
868
875
|
|
869
|
-
|
876
|
+
@Override
|
877
|
+
public void endShape(int mode) {
|
878
|
+
if (openContour) { // correct automagically, notify user
|
879
|
+
endContour();
|
880
|
+
PGraphics.showWarning("Missing endContour() before endShape()");
|
870
881
|
}
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
endContour();
|
876
|
-
PGraphics.showWarning("Missing endContour() before endShape()");
|
882
|
+
if (gpath != null) { // make sure something has been drawn
|
883
|
+
if (shape == POLYGON) {
|
884
|
+
if (mode == CLOSE) {
|
885
|
+
gpath.closePath();
|
877
886
|
}
|
878
|
-
if (
|
879
|
-
|
880
|
-
if (mode == CLOSE) {
|
881
|
-
gpath.closePath();
|
882
|
-
}
|
883
|
-
if (auxPath != null) {
|
884
|
-
gpath.append(auxPath, false);
|
885
|
-
}
|
886
|
-
drawShape(gpath);
|
887
|
-
}
|
887
|
+
if (auxPath != null) {
|
888
|
+
gpath.append(auxPath, false);
|
888
889
|
}
|
889
|
-
|
890
|
+
drawShape(gpath);
|
891
|
+
}
|
890
892
|
}
|
893
|
+
shape = 0;
|
894
|
+
}
|
891
895
|
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
896
|
+
//////////////////////////////////////////////////////////////
|
897
|
+
// CLIPPING
|
898
|
+
@Override
|
899
|
+
protected void clipImpl(float x1, float y1, float x2, float y2) {
|
900
|
+
g2.setClip(new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
|
901
|
+
}
|
898
902
|
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
+
@Override
|
904
|
+
public void noClip() {
|
905
|
+
g2.setClip(null);
|
906
|
+
}
|
903
907
|
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
protected void blendModeImpl() {
|
919
|
-
if (blendMode == BLEND) {
|
920
|
-
g2.setComposite(defaultComposite);
|
908
|
+
//////////////////////////////////////////////////////////////
|
909
|
+
// BLEND
|
910
|
+
/**
|
911
|
+
* ( begin auto-generated from blendMode.xml )
|
912
|
+
*
|
913
|
+
* This is a new reference entry for Processing 2.0.It will be updated
|
914
|
+
* shortly. ( end auto-generated )
|
915
|
+
*
|
916
|
+
* @webref Rendering
|
917
|
+
*/
|
918
|
+
@Override
|
919
|
+
protected void blendModeImpl() {
|
920
|
+
if (blendMode == BLEND) {
|
921
|
+
g2.setComposite(defaultComposite);
|
921
922
|
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
@Override
|
926
|
-
public CompositeContext createContext(ColorModel srcColorModel,
|
927
|
-
ColorModel dstColorModel,
|
928
|
-
RenderingHints hints) {
|
929
|
-
return new BlendingContext(blendMode);
|
930
|
-
}
|
931
|
-
});
|
932
|
-
}
|
923
|
+
} else {
|
924
|
+
g2.setComposite((ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints1) -> new BlendingContext(blendMode));
|
933
925
|
}
|
926
|
+
}
|
934
927
|
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
928
|
+
// Blending implementation cribbed from portions of Romain Guy's
|
929
|
+
// demo and terrific writeup on blending modes in Java 2D.
|
930
|
+
// http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
|
931
|
+
private static final class BlendingContext implements CompositeContext {
|
939
932
|
|
940
|
-
|
933
|
+
private final int mode;
|
941
934
|
|
942
|
-
|
943
|
-
|
944
|
-
|
935
|
+
private BlendingContext(int mode) {
|
936
|
+
this.mode = mode;
|
937
|
+
}
|
945
938
|
|
946
|
-
|
947
|
-
|
939
|
+
@Override
|
940
|
+
public void dispose() {
|
941
|
+
}
|
948
942
|
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
943
|
+
@Override
|
944
|
+
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
|
945
|
+
// not sure if this is really necessary, since we control our buffers
|
946
|
+
if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT
|
947
|
+
|| dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT
|
948
|
+
|| dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
|
949
|
+
throw new IllegalStateException("Source and destination must store pixels as INT.");
|
950
|
+
}
|
956
951
|
|
957
|
-
|
958
|
-
|
952
|
+
int width = Math.min(src.getWidth(), dstIn.getWidth());
|
953
|
+
int height = Math.min(src.getHeight(), dstIn.getHeight());
|
959
954
|
|
960
|
-
|
961
|
-
|
955
|
+
int[] srcPixels = new int[width];
|
956
|
+
int[] dstPixels = new int[width];
|
962
957
|
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
}
|
969
|
-
dstOut.setDataElements(0, y, width, 1, dstPixels);
|
970
|
-
}
|
958
|
+
for (int y = 0; y < height; y++) {
|
959
|
+
src.getDataElements(0, y, width, 1, srcPixels);
|
960
|
+
dstIn.getDataElements(0, y, width, 1, dstPixels);
|
961
|
+
for (int x = 0; x < width; x++) {
|
962
|
+
dstPixels[x] = blendColor(dstPixels[x], srcPixels[x], mode);
|
971
963
|
}
|
964
|
+
dstOut.setDataElements(0, y, width, 1, dstPixels);
|
965
|
+
}
|
972
966
|
}
|
967
|
+
}
|
973
968
|
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
969
|
+
//////////////////////////////////////////////////////////////
|
970
|
+
// BEZIER VERTICES
|
971
|
+
@Override
|
972
|
+
public void bezierVertex(float x1, float y1,
|
973
|
+
float x2, float y2,
|
974
|
+
float x3, float y3) {
|
975
|
+
bezierVertexCheck();
|
976
|
+
gpath.curveTo(x1, y1, x2, y2, x3, y3);
|
977
|
+
}
|
983
978
|
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
979
|
+
@Override
|
980
|
+
public void bezierVertex(float x2, float y2, float z2,
|
981
|
+
float x3, float y3, float z3,
|
982
|
+
float x4, float y4, float z4) {
|
983
|
+
showDepthWarningXYZ("bezierVertex");
|
984
|
+
}
|
990
985
|
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
986
|
+
//////////////////////////////////////////////////////////////
|
987
|
+
// QUADRATIC BEZIER VERTICES
|
988
|
+
@Override
|
989
|
+
public void quadraticVertex(float ctrlX, float ctrlY,
|
990
|
+
float endX, float endY) {
|
991
|
+
bezierVertexCheck();
|
992
|
+
Point2D cur = gpath.getCurrentPoint();
|
998
993
|
|
999
|
-
|
1000
|
-
|
994
|
+
float x1 = (float) cur.getX();
|
995
|
+
float y1 = (float) cur.getY();
|
1001
996
|
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
997
|
+
bezierVertex(x1 + ((ctrlX - x1) * 2 / 3.0f), y1 + ((ctrlY - y1) * 2 / 3.0f),
|
998
|
+
endX + ((ctrlX - endX) * 2 / 3.0f), endY + ((ctrlY - endY) * 2 / 3.0f),
|
999
|
+
endX, endY);
|
1000
|
+
}
|
1006
1001
|
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1002
|
+
@Override
|
1003
|
+
public void quadraticVertex(float x2, float y2, float z2,
|
1004
|
+
float x4, float y4, float z4) {
|
1005
|
+
showDepthWarningXYZ("quadVertex");
|
1006
|
+
}
|
1012
1007
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
if (curveCoordX == null) {
|
1020
|
-
curveCoordX = new float[4];
|
1021
|
-
curveCoordY = new float[4];
|
1022
|
-
curveDrawX = new float[4];
|
1023
|
-
curveDrawY = new float[4];
|
1024
|
-
}
|
1025
|
-
}
|
1008
|
+
//////////////////////////////////////////////////////////////
|
1009
|
+
// CURVE VERTICES
|
1010
|
+
@Override
|
1011
|
+
protected void curveVertexCheck() {
|
1012
|
+
super.curveVertexCheck();
|
1026
1013
|
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1014
|
+
if (curveCoordX == null) {
|
1015
|
+
curveCoordX = new float[4];
|
1016
|
+
curveCoordY = new float[4];
|
1017
|
+
curveDrawX = new float[4];
|
1018
|
+
curveDrawY = new float[4];
|
1019
|
+
}
|
1020
|
+
}
|
1034
1021
|
|
1035
|
-
|
1036
|
-
|
1022
|
+
@Override
|
1023
|
+
protected void curveVertexSegment(float x1, float y1,
|
1024
|
+
float x2, float y2,
|
1025
|
+
float x3, float y3,
|
1026
|
+
float x4, float y4) {
|
1027
|
+
curveCoordX[0] = x1;
|
1028
|
+
curveCoordY[0] = y1;
|
1037
1029
|
|
1038
|
-
|
1039
|
-
|
1030
|
+
curveCoordX[1] = x2;
|
1031
|
+
curveCoordY[1] = y2;
|
1040
1032
|
|
1041
|
-
|
1042
|
-
|
1033
|
+
curveCoordX[2] = x3;
|
1034
|
+
curveCoordY[2] = y3;
|
1043
1035
|
|
1044
|
-
|
1045
|
-
|
1036
|
+
curveCoordX[3] = x4;
|
1037
|
+
curveCoordY[3] = y4;
|
1046
1038
|
|
1047
|
-
|
1048
|
-
|
1049
|
-
if (gpath == null) {
|
1050
|
-
gpath = new GeneralPath();
|
1051
|
-
gpath.moveTo(curveDrawX[0], curveDrawY[0]);
|
1052
|
-
}
|
1039
|
+
curveToBezierMatrix.mult(curveCoordX, curveDrawX);
|
1040
|
+
curveToBezierMatrix.mult(curveCoordY, curveDrawY);
|
1053
1041
|
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1042
|
+
// since the paths are continuous,
|
1043
|
+
// only the first point needs the actual moveto
|
1044
|
+
if (gpath == null) {
|
1045
|
+
gpath = new GeneralPath();
|
1046
|
+
gpath.moveTo(curveDrawX[0], curveDrawY[0]);
|
1057
1047
|
}
|
1058
1048
|
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1049
|
+
gpath.curveTo(curveDrawX[1], curveDrawY[1],
|
1050
|
+
curveDrawX[2], curveDrawY[2],
|
1051
|
+
curveDrawX[3], curveDrawY[3]);
|
1052
|
+
}
|
1063
1053
|
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1054
|
+
@Override
|
1055
|
+
public void curveVertex(float x, float y, float z) {
|
1056
|
+
showDepthWarningXYZ("curveVertex");
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
//////////////////////////////////////////////////////////////
|
1060
|
+
// RENDERER
|
1061
|
+
//public void flush()
|
1062
|
+
//////////////////////////////////////////////////////////////
|
1063
|
+
// POINT, LINE, TRIANGLE, QUAD
|
1064
|
+
@Override
|
1065
|
+
public void point(float x, float y) {
|
1066
|
+
if (stroke) {
|
1072
1067
|
// if (strokeWeight > 1) {
|
1073
|
-
|
1068
|
+
line(x, y, x + EPSILON, y + EPSILON);
|
1074
1069
|
// } else {
|
1075
1070
|
// set((int) screenX(x, y), (int) screenY(x, y), strokeColor);
|
1076
1071
|
// }
|
1077
|
-
}
|
1078
1072
|
}
|
1073
|
+
}
|
1079
1074
|
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1075
|
+
@Override
|
1076
|
+
public void line(float x1, float y1, float x2, float y2) {
|
1077
|
+
line.setLine(x1, y1, x2, y2);
|
1078
|
+
strokeShape(line);
|
1079
|
+
}
|
1085
1080
|
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1081
|
+
@Override
|
1082
|
+
public void triangle(float x1, float y1, float x2, float y2,
|
1083
|
+
float x3, float y3) {
|
1084
|
+
gpath = new GeneralPath();
|
1085
|
+
gpath.moveTo(x1, y1);
|
1086
|
+
gpath.lineTo(x2, y2);
|
1087
|
+
gpath.lineTo(x3, y3);
|
1088
|
+
gpath.closePath();
|
1089
|
+
drawShape(gpath);
|
1090
|
+
}
|
1096
1091
|
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
//////////////////////////////////////////////////////////////
|
1110
|
-
// RECT
|
1111
|
-
//public void rectMode(int mode)
|
1112
|
-
//public void rect(float a, float b, float c, float d)
|
1113
|
-
@Override
|
1114
|
-
protected void rectImpl(float x1, float y1, float x2, float y2) {
|
1115
|
-
rect.setFrame(x1, y1, x2 - x1, y2 - y1);
|
1116
|
-
drawShape(rect);
|
1117
|
-
}
|
1092
|
+
@Override
|
1093
|
+
public void quad(float x1, float y1, float x2, float y2,
|
1094
|
+
float x3, float y3, float x4, float y4) {
|
1095
|
+
GeneralPath gp = new GeneralPath();
|
1096
|
+
gp.moveTo(x1, y1);
|
1097
|
+
gp.lineTo(x2, y2);
|
1098
|
+
gp.lineTo(x3, y3);
|
1099
|
+
gp.lineTo(x4, y4);
|
1100
|
+
gp.closePath();
|
1101
|
+
drawShape(gp);
|
1102
|
+
}
|
1118
1103
|
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1104
|
+
//////////////////////////////////////////////////////////////
|
1105
|
+
// RECT
|
1106
|
+
//public void rectMode(int mode)
|
1107
|
+
//public void rect(float a, float b, float c, float d)
|
1108
|
+
@Override
|
1109
|
+
protected void rectImpl(float x1, float y1, float x2, float y2) {
|
1110
|
+
rect.setFrame(x1, y1, x2 - x1, y2 - y1);
|
1111
|
+
drawShape(rect);
|
1112
|
+
}
|
1128
1113
|
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1114
|
+
//////////////////////////////////////////////////////////////
|
1115
|
+
// ELLIPSE
|
1116
|
+
//public void ellipseMode(int mode)
|
1117
|
+
//public void ellipse(float a, float b, float c, float d)
|
1118
|
+
@Override
|
1119
|
+
protected void ellipseImpl(float x, float y, float w, float h) {
|
1120
|
+
ellipse.setFrame(x, y, w, h);
|
1121
|
+
drawShape(ellipse);
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
//////////////////////////////////////////////////////////////
|
1125
|
+
// ARC
|
1126
|
+
//public void arc(float a, float b, float c, float d,
|
1127
|
+
// float start, float stop)
|
1128
|
+
@Override
|
1129
|
+
protected void arcImpl(float x, float y, float w, float h,
|
1130
|
+
float start, float stop, int mode) {
|
1131
|
+
// 0 to 90 in java would be 0 to -90 for p5 renderer
|
1132
|
+
// but that won't work, so -90 to 0?
|
1138
1133
|
|
1139
|
-
|
1140
|
-
|
1134
|
+
start = -start * RAD_TO_DEG;
|
1135
|
+
stop = -stop * RAD_TO_DEG;
|
1141
1136
|
|
1142
|
-
|
1137
|
+
// ok to do this because already checked for NaN
|
1143
1138
|
// while (start < 0) {
|
1144
1139
|
// start += 360;
|
1145
1140
|
// stop += 360;
|
@@ -1149,137 +1144,141 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1149
1144
|
// start = stop;
|
1150
1145
|
// stop = temp;
|
1151
1146
|
// }
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1147
|
+
float sweep = stop - start;
|
1148
|
+
|
1149
|
+
// The defaults, before 2.0b7, were to stroke as Arc2D.OPEN, and then fill
|
1150
|
+
// using Arc2D.PIE. That's a little wonky, but it's here for compatability.
|
1151
|
+
int fillMode = Arc2D.PIE;
|
1152
|
+
int strokeMode = Arc2D.OPEN;
|
1153
|
+
|
1154
|
+
switch (mode) {
|
1155
|
+
case OPEN:
|
1156
|
+
fillMode = Arc2D.OPEN;
|
1157
|
+
//strokeMode = Arc2D.OPEN;
|
1158
|
+
break;
|
1159
|
+
case PIE:
|
1160
|
+
//fillMode = Arc2D.PIE;
|
1161
|
+
strokeMode = Arc2D.PIE;
|
1162
|
+
break;
|
1163
|
+
case CHORD:
|
1164
|
+
fillMode = Arc2D.CHORD;
|
1165
|
+
strokeMode = Arc2D.CHORD;
|
1166
|
+
break;
|
1167
|
+
default:
|
1168
|
+
break;
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
if (fill) {
|
1172
|
+
//System.out.println("filla");
|
1173
|
+
arc.setArc(x, y, w, h, start, sweep, fillMode);
|
1174
|
+
fillShape(arc);
|
1175
|
+
}
|
1176
|
+
if (stroke) {
|
1177
|
+
//System.out.println("strokey");
|
1178
|
+
arc.setArc(x, y, w, h, start, sweep, strokeMode);
|
1179
|
+
strokeShape(arc);
|
1182
1180
|
}
|
1181
|
+
}
|
1183
1182
|
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
}
|
1183
|
+
//////////////////////////////////////////////////////////////
|
1184
|
+
// JAVA2D SHAPE/PATH HANDLING
|
1185
|
+
protected void fillShape(Shape s) {
|
1186
|
+
if (fillGradient) {
|
1187
|
+
g2.setPaint(fillGradientObject);
|
1188
|
+
g2.fill(s);
|
1189
|
+
} else if (fill) {
|
1190
|
+
g2.setColor(fillColorObject);
|
1191
|
+
g2.fill(s);
|
1194
1192
|
}
|
1193
|
+
}
|
1195
1194
|
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
}
|
1195
|
+
protected void strokeShape(Shape s) {
|
1196
|
+
if (strokeGradient) {
|
1197
|
+
g2.setPaint(strokeGradientObject);
|
1198
|
+
g2.draw(s);
|
1199
|
+
} else if (stroke) {
|
1200
|
+
g2.setColor(strokeColorObject);
|
1201
|
+
g2.draw(s);
|
1204
1202
|
}
|
1203
|
+
}
|
1205
1204
|
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
}
|
1205
|
+
protected void drawShape(Shape s) {
|
1206
|
+
if (fillGradient) {
|
1207
|
+
g2.setPaint(fillGradientObject);
|
1208
|
+
g2.fill(s);
|
1209
|
+
} else if (fill) {
|
1210
|
+
g2.setColor(fillColorObject);
|
1211
|
+
g2.fill(s);
|
1212
|
+
}
|
1213
|
+
if (strokeGradient) {
|
1214
|
+
g2.setPaint(strokeGradientObject);
|
1215
|
+
g2.draw(s);
|
1216
|
+
} else if (stroke) {
|
1217
|
+
g2.setColor(strokeColorObject);
|
1218
|
+
g2.draw(s);
|
1221
1219
|
}
|
1220
|
+
}
|
1222
1221
|
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1222
|
+
//////////////////////////////////////////////////////////////
|
1223
|
+
// BOX
|
1224
|
+
//public void box(float size)
|
1225
|
+
@Override
|
1226
|
+
public void box(float w, float h, float d) {
|
1227
|
+
showMethodWarning("box");
|
1228
|
+
}
|
1230
1229
|
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1230
|
+
//////////////////////////////////////////////////////////////
|
1231
|
+
// SPHERE
|
1232
|
+
//public void sphereDetail(int res)
|
1233
|
+
//public void sphereDetail(int ures, int vres)
|
1234
|
+
@Override
|
1235
|
+
public void sphere(float r) {
|
1236
|
+
showMethodWarning("sphere");
|
1237
|
+
}
|
1239
1238
|
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1239
|
+
//////////////////////////////////////////////////////////////
|
1240
|
+
// BEZIER
|
1241
|
+
//public float bezierPoint(float a, float b, float c, float d, float t)
|
1242
|
+
//public float bezierTangent(float a, float b, float c, float d, float t)
|
1243
|
+
//protected void bezierInitCheck()
|
1244
|
+
//protected void bezierInit()
|
1245
|
+
/**
|
1246
|
+
* Ignored (not needed) in Java 2D.
|
1247
|
+
*/
|
1248
|
+
@Override
|
1249
|
+
public void bezierDetail(int detail) {
|
1250
|
+
}
|
1251
|
+
|
1252
|
+
//public void bezier(float x1, float y1,
|
1253
|
+
// float x2, float y2,
|
1254
|
+
// float x3, float y3,
|
1255
|
+
// float x4, float y4)
|
1256
|
+
//public void bezier(float x1, float y1, float z1,
|
1257
|
+
// float x2, float y2, float z2,
|
1258
|
+
// float x3, float y3, float z3,
|
1259
|
+
// float x4, float y4, float z4)
|
1260
|
+
//////////////////////////////////////////////////////////////
|
1261
|
+
// CURVE
|
1262
|
+
//public float curvePoint(float a, float b, float c, float d, float t)
|
1263
|
+
//public float curveTangent(float a, float b, float c, float d, float t)
|
1264
|
+
/**
|
1265
|
+
* Ignored (not needed) in Java 2D.
|
1266
|
+
*/
|
1267
|
+
@Override
|
1268
|
+
public void curveDetail(int detail) {
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
//public void curveTightness(float tightness)
|
1272
|
+
//protected void curveInitCheck()
|
1273
|
+
//protected void curveInit()
|
1274
|
+
//public void curve(float x1, float y1,
|
1275
|
+
// float x2, float y2,
|
1276
|
+
// float x3, float y3,
|
1277
|
+
// float x4, float y4)
|
1278
|
+
//public void curve(float x1, float y1, float z1,
|
1279
|
+
// float x2, float y2, float z2,
|
1280
|
+
// float x3, float y3, float z3,
|
1281
|
+
// float x4, float y4, float z4)
|
1283
1282
|
// //////////////////////////////////////////////////////////////
|
1284
1283
|
//
|
1285
1284
|
// // SMOOTH
|
@@ -1343,75 +1342,77 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1343
1342
|
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
1344
1343
|
// RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
1345
1344
|
// }
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1345
|
+
//////////////////////////////////////////////////////////////
|
1346
|
+
// IMAGE
|
1347
|
+
//public void imageMode(int mode)
|
1348
|
+
//public void image(PImage image, float x, float y)
|
1349
|
+
//public void image(PImage image, float x, float y, float c, float d)
|
1350
|
+
//public void image(PImage image,
|
1351
|
+
// float a, float b, float c, float d,
|
1352
|
+
// int u1, int v1, int u2, int v2)
|
1353
|
+
/**
|
1354
|
+
* Handle renderer-specific image drawing.
|
1355
|
+
*
|
1356
|
+
* @param who
|
1357
|
+
*/
|
1358
|
+
@Override
|
1359
|
+
protected void imageImpl(PImage who,
|
1360
|
+
float x1, float y1, float x2, float y2,
|
1361
|
+
int u1, int v1, int u2, int v2) {
|
1362
|
+
// Image not ready yet, or an error
|
1363
|
+
if (who.width <= 0 || who.height <= 0) {
|
1364
|
+
return;
|
1365
|
+
}
|
1367
1366
|
|
1368
|
-
|
1369
|
-
if (cash != null) {
|
1370
|
-
if (who.pixelWidth != cash.image.getWidth()
|
1371
|
-
|| who.pixelHeight != cash.image.getHeight()) {
|
1372
|
-
cash = null;
|
1373
|
-
}
|
1374
|
-
}
|
1367
|
+
ImageCache cash = (ImageCache) getCache(who);
|
1375
1368
|
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1369
|
+
// Nuke the cache if the image was resized
|
1370
|
+
if (cash != null) {
|
1371
|
+
if (who.pixelWidth != cash.image.getWidth()
|
1372
|
+
|| who.pixelHeight != cash.image.getHeight()) {
|
1373
|
+
cash = null;
|
1374
|
+
}
|
1375
|
+
}
|
1383
1376
|
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
}
|
1377
|
+
if (cash == null) {
|
1378
|
+
//System.out.println("making new image cache");
|
1379
|
+
cash = new ImageCache(); //who);
|
1380
|
+
setCache(who, cash);
|
1381
|
+
who.updatePixels(); // mark the whole thing for update
|
1382
|
+
who.setModified();
|
1383
|
+
}
|
1392
1384
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1385
|
+
// If image previously was tinted, or the color changed
|
1386
|
+
// or the image was tinted, and tint is now disabled
|
1387
|
+
if ((tint && !cash.tinted)
|
1388
|
+
|| (tint && (cash.tintedColor != tintColor))
|
1389
|
+
|| (!tint && cash.tinted)) {
|
1390
|
+
// For tint change, mark all pixels as needing update.
|
1391
|
+
who.updatePixels();
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
if (who.isModified()) {
|
1395
|
+
if (who.pixels == null) {
|
1396
|
+
// This might be a PGraphics that hasn't been drawn to yet.
|
1397
|
+
// Can't just bail because the cache has been created above.
|
1398
|
+
// https://github.com/processing/processing/issues/2208
|
1399
|
+
who.pixels = new int[who.pixelWidth * who.pixelHeight];
|
1400
|
+
}
|
1401
|
+
cash.update(who, tint, tintColor);
|
1402
|
+
who.setModified(false);
|
1403
|
+
}
|
1403
1404
|
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1405
|
+
u1 *= who.pixelDensity;
|
1406
|
+
v1 *= who.pixelDensity;
|
1407
|
+
u2 *= who.pixelDensity;
|
1408
|
+
v2 *= who.pixelDensity;
|
1408
1409
|
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1410
|
+
g2.drawImage(((ImageCache) getCache(who)).image,
|
1411
|
+
(int) x1, (int) y1, (int) x2, (int) y2,
|
1412
|
+
u1, v1, u2, v2, null);
|
1412
1413
|
|
1413
|
-
|
1414
|
-
|
1414
|
+
// Every few years I think "nah, Java2D couldn't possibly be that f*king
|
1415
|
+
// slow, why are we doing this by hand?" then comes the affirmation:
|
1415
1416
|
// Composite oldComp = null;
|
1416
1417
|
// if (false && tint) {
|
1417
1418
|
// oldComp = g2.getComposite();
|
@@ -1431,14 +1432,14 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1431
1432
|
// if (oldComp != null) {
|
1432
1433
|
// g2.setComposite(oldComp);
|
1433
1434
|
// }
|
1434
|
-
|
1435
|
+
}
|
1435
1436
|
|
1436
|
-
|
1437
|
+
static class ImageCache {
|
1437
1438
|
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1439
|
+
boolean tinted;
|
1440
|
+
int tintedColor;
|
1441
|
+
int[] tintedTemp; // one row of tinted pixels
|
1442
|
+
BufferedImage image;
|
1442
1443
|
// BufferedImage compat;
|
1443
1444
|
|
1444
1445
|
// public ImageCache(PImage source) {
|
@@ -1449,145 +1450,151 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1449
1450
|
// //System.out.println("making new buffered image");
|
1450
1451
|
//// image = new BufferedImage(source.width, source.height, type);
|
1451
1452
|
// }
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1453
|
+
/**
|
1454
|
+
* Update the pixels of the cache image. Already determined that the tint
|
1455
|
+
* has changed, or the pixels have changed, so should just go through with
|
1456
|
+
* the update without further checks.
|
1457
|
+
*/
|
1458
|
+
public void update(PImage source, boolean tint, int tintColor) {
|
1459
|
+
//int bufferType = BufferedImage.TYPE_INT_ARGB;
|
1460
|
+
int targetType = ARGB;
|
1461
|
+
boolean opaque = (tintColor & 0xFF000000) == 0xFF000000;
|
1462
|
+
if (source.format == RGB) {
|
1463
|
+
if (!tint || (tint && opaque)) {
|
1464
|
+
//bufferType = BufferedImage.TYPE_INT_RGB;
|
1465
|
+
targetType = RGB;
|
1466
|
+
}
|
1467
|
+
}
|
1467
1468
|
// boolean wrongType = (image != null) && (image.getType() != bufferType);
|
1468
1469
|
// if ((image == null) || wrongType) {
|
1469
1470
|
// image = new BufferedImage(source.width, source.height, bufferType);
|
1470
1471
|
// }
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1472
|
+
// Must always use an ARGB image, otherwise will write zeros
|
1473
|
+
// in the alpha channel when drawn to the screen.
|
1474
|
+
// https://github.com/processing/processing/issues/2030
|
1475
|
+
if (image == null) {
|
1476
|
+
image = new BufferedImage(source.pixelWidth, source.pixelHeight,
|
1477
|
+
BufferedImage.TYPE_INT_ARGB);
|
1478
|
+
}
|
1478
1479
|
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1480
|
+
WritableRaster wr = image.getRaster();
|
1481
|
+
if (tint) {
|
1482
|
+
if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
|
1483
|
+
tintedTemp = new int[source.pixelWidth];
|
1484
|
+
}
|
1485
|
+
int a2 = (tintColor >> 24) & 0xff;
|
1485
1486
|
// System.out.println("tint color is " + a2);
|
1486
1487
|
// System.out.println("source.pixels[0] alpha is " + (source.pixels[0] >>> 24));
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1488
|
+
int r2 = (tintColor >> 16) & 0xff;
|
1489
|
+
int g2 = (tintColor >> 8) & 0xff;
|
1490
|
+
int b2 = (tintColor) & 0xff;
|
1491
|
+
|
1492
|
+
//if (bufferType == BufferedImage.TYPE_INT_RGB) {
|
1493
|
+
if (targetType == RGB) {
|
1494
|
+
// The target image is opaque, meaning that the source image has no
|
1495
|
+
// alpha (is not ARGB), and the tint has no alpha.
|
1496
|
+
int index = 0;
|
1497
|
+
for (int y = 0; y < source.pixelHeight; y++) {
|
1498
|
+
for (int x = 0; x < source.pixelWidth; x++) {
|
1499
|
+
int argb1 = source.pixels[index++];
|
1500
|
+
int r1 = (argb1 >> 16) & 0xff;
|
1501
|
+
int g1 = (argb1 >> 8) & 0xff;
|
1502
|
+
int b1 = (argb1) & 0xff;
|
1503
|
+
|
1504
|
+
// Prior to 2.1, the alpha channel was commented out here,
|
1505
|
+
// but can't remember why (just thought unnecessary b/c of RGB?)
|
1506
|
+
// https://github.com/processing/processing/issues/2030
|
1507
|
+
tintedTemp[x] = 0xFF000000
|
1508
|
+
| (((r2 * r1) & 0xff00) << 8)
|
1509
|
+
| ((g2 * g1) & 0xff00)
|
1510
|
+
| (((b2 * b1) & 0xff00) >> 8);
|
1511
|
+
}
|
1512
|
+
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
|
1513
|
+
}
|
1514
|
+
// could this be any slower?
|
1514
1515
|
// float[] scales = { tintR, tintG, tintB };
|
1515
1516
|
// float[] offsets = new float[3];
|
1516
1517
|
// RescaleOp op = new RescaleOp(scales, offsets, null);
|
1517
1518
|
// op.filter(image, image);
|
1518
1519
|
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1520
|
+
//} else if (bufferType == BufferedImage.TYPE_INT_ARGB) {
|
1521
|
+
} else if (targetType == ARGB) {
|
1522
|
+
if (source.format == RGB
|
1523
|
+
&& (tintColor & 0xffffff) == 0xffffff) {
|
1524
|
+
int hi = tintColor & 0xff000000;
|
1525
|
+
int index = 0;
|
1526
|
+
for (int y = 0; y < source.pixelHeight; y++) {
|
1527
|
+
for (int x = 0; x < source.pixelWidth; x++) {
|
1528
|
+
tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
|
1529
|
+
}
|
1530
|
+
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
|
1531
|
+
}
|
1532
|
+
} else {
|
1533
|
+
int index = 0;
|
1534
|
+
for (int y = 0; y < source.pixelHeight; y++) {
|
1535
|
+
switch (source.format) {
|
1536
|
+
case RGB:
|
1537
|
+
int alpha = tintColor & 0xFF000000;
|
1538
|
+
for (int x = 0; x < source.pixelWidth; x++) {
|
1539
|
+
int argb1 = source.pixels[index++];
|
1540
|
+
int r1 = (argb1 >> 16) & 0xff;
|
1541
|
+
int g1 = (argb1 >> 8) & 0xff;
|
1542
|
+
int b1 = (argb1) & 0xff;
|
1543
|
+
tintedTemp[x] = alpha
|
1544
|
+
| (((r2 * r1) & 0xff00) << 8)
|
1545
|
+
| ((g2 * g1) & 0xff00)
|
1546
|
+
| (((b2 * b1) & 0xff00) >> 8);
|
1547
|
+
}
|
1548
|
+
break;
|
1549
|
+
case ARGB:
|
1550
|
+
for (int x = 0; x < source.pixelWidth; x++) {
|
1551
|
+
int argb1 = source.pixels[index++];
|
1552
|
+
int a1 = (argb1 >> 24) & 0xff;
|
1553
|
+
int r1 = (argb1 >> 16) & 0xff;
|
1554
|
+
int g1 = (argb1 >> 8) & 0xff;
|
1555
|
+
int b1 = (argb1) & 0xff;
|
1556
|
+
tintedTemp[x]
|
1557
|
+
= (((a2 * a1) & 0xff00) << 16)
|
1558
|
+
| (((r2 * r1) & 0xff00) << 8)
|
1559
|
+
| ((g2 * g1) & 0xff00)
|
1560
|
+
| (((b2 * b1) & 0xff00) >> 8);
|
1561
|
+
}
|
1562
|
+
break;
|
1563
|
+
case ALPHA:
|
1564
|
+
int lower = tintColor & 0xFFFFFF;
|
1565
|
+
for (int x = 0; x < source.pixelWidth; x++) {
|
1566
|
+
int a1 = source.pixels[index++];
|
1567
|
+
tintedTemp[x]
|
1568
|
+
= (((a2 * a1) & 0xff00) << 16) | lower;
|
1569
|
+
}
|
1570
|
+
break;
|
1571
|
+
default:
|
1572
|
+
break;
|
1573
|
+
}
|
1574
|
+
wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
|
1575
|
+
}
|
1576
|
+
}
|
1577
|
+
// Not sure why ARGB images take the scales in this order...
|
1571
1578
|
// float[] scales = { tintR, tintG, tintB, tintA };
|
1572
1579
|
// float[] offsets = new float[4];
|
1573
1580
|
// RescaleOp op = new RescaleOp(scales, offsets, null);
|
1574
1581
|
// op.filter(image, image);
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1582
|
+
}
|
1583
|
+
} else { // !tint
|
1584
|
+
if (targetType == RGB && (source.pixels[0] >> 24 == 0)) {
|
1585
|
+
// If it's an RGB image and the high bits aren't set, need to set
|
1586
|
+
// the high bits to opaque because we're drawing ARGB images.
|
1587
|
+
source.filter(OPAQUE);
|
1588
|
+
// Opting to just manipulate the image here, since it shouldn't
|
1589
|
+
// affect anything else (and alpha(get(x, y)) should return 0xff).
|
1590
|
+
// Wel also make no guarantees about the values of the pixels array
|
1591
|
+
// in a PImage and how the high bits will be set.
|
1592
|
+
}
|
1593
|
+
// If no tint, just shove the pixels on in there verbatim
|
1594
|
+
wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels);
|
1595
|
+
}
|
1596
|
+
this.tinted = tint;
|
1597
|
+
this.tintedColor = tintColor;
|
1591
1598
|
|
1592
1599
|
// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
|
1593
1600
|
// compat = gc.createCompatibleImage(image.getWidth(),
|
@@ -1597,132 +1604,132 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1597
1604
|
// Graphics2D g = compat.createGraphics();
|
1598
1605
|
// g.drawImage(image, 0, 0, null);
|
1599
1606
|
// g.dispose();
|
1600
|
-
}
|
1601
1607
|
}
|
1608
|
+
}
|
1602
1609
|
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
}
|
1618
|
-
PGraphics.showWarning("Unsupported format: " + filename);
|
1619
|
-
return null;
|
1610
|
+
//////////////////////////////////////////////////////////////
|
1611
|
+
// SHAPE
|
1612
|
+
//public void shapeMode(int mode)
|
1613
|
+
//public void shape(PShape shape)
|
1614
|
+
//public void shape(PShape shape, float x, float y)
|
1615
|
+
//public void shape(PShape shape, float x, float y, float c, float d)
|
1616
|
+
//////////////////////////////////////////////////////////////
|
1617
|
+
// SHAPE I/O
|
1618
|
+
//public PShape loadShape(String filename)
|
1619
|
+
@Override
|
1620
|
+
public PShape loadShape(String filename, String options) {
|
1621
|
+
String extension = PApplet.getExtension(filename);
|
1622
|
+
if (extension.equals("svg") || extension.equals("svgz")) {
|
1623
|
+
return new PShapeJava2D(parent.loadXML(filename));
|
1620
1624
|
}
|
1625
|
+
PGraphics.showWarning("Unsupported format: " + filename);
|
1626
|
+
return null;
|
1627
|
+
}
|
1621
1628
|
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
}
|
1631
|
-
|
1632
|
-
Font font = (Font) textFont.getNative();
|
1633
|
-
if (font != null) {
|
1634
|
-
//return getFontMetrics(font).getAscent();
|
1635
|
-
return g2.getFontMetrics(font).getAscent();
|
1636
|
-
}
|
1637
|
-
return super.textAscent();
|
1629
|
+
//////////////////////////////////////////////////////////////
|
1630
|
+
// TEXT ATTRIBTUES
|
1631
|
+
//public void textAlign(int align)
|
1632
|
+
//public void textAlign(int alignX, int alignY)
|
1633
|
+
@Override
|
1634
|
+
public float textAscent() {
|
1635
|
+
if (textFont == null) {
|
1636
|
+
defaultFontOrDeath("textAscent");
|
1638
1637
|
}
|
1639
1638
|
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
}
|
1645
|
-
Font font = (Font) textFont.getNative();
|
1646
|
-
if (font != null) {
|
1647
|
-
//return getFontMetrics(font).getDescent();
|
1648
|
-
return g2.getFontMetrics(font).getDescent();
|
1649
|
-
}
|
1650
|
-
return super.textDescent();
|
1639
|
+
Font font = (Font) textFont.getNative();
|
1640
|
+
if (font != null) {
|
1641
|
+
//return getFontMetrics(font).getAscent();
|
1642
|
+
return g2.getFontMetrics(font).getAscent();
|
1651
1643
|
}
|
1644
|
+
return super.textAscent();
|
1645
|
+
}
|
1652
1646
|
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1647
|
+
@Override
|
1648
|
+
public float textDescent() {
|
1649
|
+
if (textFont == null) {
|
1650
|
+
defaultFontOrDeath("textDescent");
|
1651
|
+
}
|
1652
|
+
Font font = (Font) textFont.getNative();
|
1653
|
+
if (font != null) {
|
1654
|
+
//return getFontMetrics(font).getDescent();
|
1655
|
+
return g2.getFontMetrics(font).getDescent();
|
1660
1656
|
}
|
1657
|
+
return super.textDescent();
|
1658
|
+
}
|
1661
1659
|
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1660
|
+
//public void textFont(PFont which)
|
1661
|
+
//public void textFont(PFont which, float size)
|
1662
|
+
//public void textLeading(float leading)
|
1663
|
+
//public void textMode(int mode)
|
1664
|
+
@Override
|
1665
|
+
protected boolean textModeCheck(int mode) {
|
1666
|
+
return mode == MODEL;
|
1667
|
+
}
|
1668
|
+
|
1669
|
+
/**
|
1670
|
+
* Same as parent, but override for native version of the font.
|
1671
|
+
*
|
1672
|
+
* Called from textFontImpl and textSizeImpl, so the metrics will get recorded
|
1673
|
+
* properly.
|
1674
|
+
*/
|
1675
|
+
@Override
|
1676
|
+
protected void handleTextSize(float size) {
|
1677
|
+
// if a native version available, derive this font
|
1678
|
+
Font font = (Font) textFont.getNative();
|
1679
|
+
// don't derive again if the font size has not changed
|
1680
|
+
if (font != null) {
|
1681
|
+
if (font.getSize2D() != size) {
|
1682
|
+
Map<TextAttribute, Object> map
|
1683
|
+
= new HashMap<>();
|
1684
|
+
map.put(TextAttribute.SIZE, size);
|
1685
|
+
map.put(TextAttribute.KERNING,
|
1686
|
+
TextAttribute.KERNING_ON);
|
1680
1687
|
// map.put(TextAttribute.TRACKING,
|
1681
1688
|
// TextAttribute.TRACKING_TIGHT);
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1689
|
+
font = font.deriveFont(map);
|
1690
|
+
}
|
1691
|
+
g2.setFont(font);
|
1692
|
+
textFont.setNative(font);
|
1693
|
+
fontObject = font;
|
1687
1694
|
|
1688
|
-
|
1695
|
+
/*
|
1689
1696
|
Map<TextAttribute, ?> attrs = font.getAttributes();
|
1690
1697
|
for (TextAttribute ta : attrs.keySet()) {
|
1691
1698
|
System.out.println(ta + " -> " + attrs.get(ta));
|
1692
1699
|
}
|
1693
|
-
|
1694
|
-
}
|
1695
|
-
|
1696
|
-
// take care of setting the textSize and textLeading vars
|
1697
|
-
// this has to happen second, because it calls textAscent()
|
1698
|
-
// (which requires the native font metrics to be set)
|
1699
|
-
super.handleTextSize(size);
|
1700
|
+
*/
|
1700
1701
|
}
|
1701
1702
|
|
1702
|
-
//
|
1703
|
-
//
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1703
|
+
// take care of setting the textSize and textLeading vars
|
1704
|
+
// this has to happen second, because it calls textAscent()
|
1705
|
+
// (which requires the native font metrics to be set)
|
1706
|
+
super.handleTextSize(size);
|
1707
|
+
}
|
1708
|
+
|
1709
|
+
//public float textWidth(char c)
|
1710
|
+
//public float textWidth(String str)
|
1711
|
+
@Override
|
1712
|
+
protected float textWidthImpl(char buffer[], int start, int stop) {
|
1713
|
+
if (textFont == null) {
|
1714
|
+
defaultFontOrDeath("textWidth");
|
1715
|
+
}
|
1716
|
+
// Avoid "Zero length string passed to TextLayout constructor" error
|
1717
|
+
if (start == stop) {
|
1718
|
+
return 0;
|
1719
|
+
}
|
1713
1720
|
|
1714
|
-
|
1721
|
+
Font font = (Font) textFont.getNative();
|
1715
1722
|
// System.out.println(font);
|
1716
|
-
|
1717
|
-
|
1723
|
+
//if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
|
1724
|
+
if (font != null) {
|
1718
1725
|
// System.out.println("using charswidth for " + new String(buffer, start, stop-start));
|
1719
|
-
|
1726
|
+
// maybe should use one of the newer/fancier functions for this?
|
1720
1727
|
// int length = stop - start;
|
1721
1728
|
// FontMetrics metrics = getFontMetrics(font);
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1729
|
+
FontMetrics metrics = g2.getFontMetrics(font);
|
1730
|
+
// Using fractional metrics makes the measurement worse, not better,
|
1731
|
+
// at least on OS X 10.6 (November, 2010).
|
1732
|
+
// TextLayout returns the same value as charsWidth().
|
1726
1733
|
// System.err.println("using native");
|
1727
1734
|
// g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
|
1728
1735
|
// RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
@@ -1735,11 +1742,11 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1735
1742
|
//// return m2;
|
1736
1743
|
//// return metrics.charsWidth(buffer, start, length);
|
1737
1744
|
// return m2;
|
1738
|
-
|
1739
|
-
}
|
1740
|
-
// System.err.println("not native");
|
1741
|
-
return super.textWidthImpl(buffer, start, stop);
|
1745
|
+
return (float) metrics.getStringBounds(buffer, start, stop, g2).getWidth();
|
1742
1746
|
}
|
1747
|
+
// System.err.println("not native");
|
1748
|
+
return super.textWidthImpl(buffer, start, stop);
|
1749
|
+
}
|
1743
1750
|
|
1744
1751
|
// protected void beginTextScreenMode() {
|
1745
1752
|
// loadPixels();
|
@@ -1747,20 +1754,20 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1747
1754
|
// protected void endTextScreenMode() {
|
1748
1755
|
// updatePixels();
|
1749
1756
|
// }
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1757
|
+
//////////////////////////////////////////////////////////////
|
1758
|
+
// TEXT
|
1759
|
+
// None of the variations of text() are overridden from PGraphics.
|
1760
|
+
//////////////////////////////////////////////////////////////
|
1761
|
+
// TEXT IMPL
|
1762
|
+
//protected void textLineAlignImpl(char buffer[], int start, int stop,
|
1763
|
+
// float x, float y)
|
1764
|
+
@Override
|
1765
|
+
protected void textLineImpl(char buffer[], int start, int stop,
|
1766
|
+
float x, float y) {
|
1767
|
+
Font font = (Font) textFont.getNative();
|
1761
1768
|
// if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
|
1762
|
-
|
1763
|
-
|
1769
|
+
if (font != null) {
|
1770
|
+
/*
|
1764
1771
|
// save the current setting for text smoothing. note that this is
|
1765
1772
|
// different from the smooth() function, because the font smoothing
|
1766
1773
|
// is controlled when the font is created, not now as it's drawn.
|
@@ -1774,47 +1781,47 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1774
1781
|
textFont.smooth ?
|
1775
1782
|
RenderingHints.VALUE_ANTIALIAS_ON :
|
1776
1783
|
RenderingHints.VALUE_ANTIALIAS_OFF);
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
+
*/
|
1785
|
+
Object antialias
|
1786
|
+
= g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
|
1787
|
+
if (antialias == null) {
|
1788
|
+
// if smooth() and noSmooth() not called, this will be null (0120)
|
1789
|
+
antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT;
|
1790
|
+
}
|
1784
1791
|
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
+
// override the current smoothing setting based on the font
|
1793
|
+
// also changes global setting for antialiasing, but this is because it's
|
1794
|
+
// not possible to enable/disable them independently in some situations.
|
1795
|
+
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
1796
|
+
textFont.isSmooth()
|
1797
|
+
? RenderingHints.VALUE_ANTIALIAS_ON
|
1798
|
+
: RenderingHints.VALUE_ANTIALIAS_OFF);
|
1792
1799
|
|
1793
|
-
|
1800
|
+
g2.setColor(fillColorObject);
|
1794
1801
|
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1802
|
+
int length = stop - start;
|
1803
|
+
if (length != 0) {
|
1804
|
+
g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f));
|
1805
|
+
// better to use round here? also, drawChars now just calls drawString
|
1799
1806
|
// g2.drawString(new String(buffer, start, stop - start), Math.round(x), Math.round(y));
|
1800
1807
|
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1808
|
+
// better to use drawString() with floats? (nope, draws the same)
|
1809
|
+
//g2.drawString(new String(buffer, start, length), x, y);
|
1810
|
+
// this didn't seem to help the scaling issue, and creates garbage
|
1811
|
+
// because of a fairly heavyweight new temporary object
|
1805
1812
|
// java.awt.font.GlyphVector gv =
|
1806
1813
|
// font.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop - start));
|
1807
1814
|
// g2.drawGlyphVector(gv, x, y);
|
1808
|
-
|
1815
|
+
}
|
1809
1816
|
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1817
|
+
// return to previous smoothing state if it was changed
|
1818
|
+
//g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias);
|
1819
|
+
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias);
|
1813
1820
|
|
1814
|
-
|
1815
|
-
|
1816
|
-
}
|
1821
|
+
} else { // otherwise just do the default
|
1822
|
+
super.textLineImpl(buffer, start, stop, x, y);
|
1817
1823
|
}
|
1824
|
+
}
|
1818
1825
|
|
1819
1826
|
// /**
|
1820
1827
|
// * Convenience method to get a legit FontMetrics object. Where possible,
|
@@ -1838,7 +1845,7 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1838
1845
|
// return getFontMetrics(font).getFontRenderContext();
|
1839
1846
|
// }
|
1840
1847
|
|
1841
|
-
|
1848
|
+
/*
|
1842
1849
|
Toolkit toolkit;
|
1843
1850
|
|
1844
1851
|
@SuppressWarnings("deprecation")
|
@@ -1855,471 +1862,471 @@ public class PGraphicsJava2D extends PGraphics {
|
|
1855
1862
|
return toolkit.getFontMetrics(font);
|
1856
1863
|
//return (g2 != null) ? g2.getFontMetrics(font) : super.getFontMetrics(font);
|
1857
1864
|
}
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
}
|
1867
|
-
transformStack[transformCount] = g2.getTransform();
|
1868
|
-
transformCount++;
|
1865
|
+
*/
|
1866
|
+
//////////////////////////////////////////////////////////////
|
1867
|
+
// MATRIX STACK
|
1868
|
+
@Override
|
1869
|
+
public void pushMatrix() {
|
1870
|
+
if (transformCount == transformStack.length) {
|
1871
|
+
throw new RuntimeException("pushMatrix() cannot use push more than "
|
1872
|
+
+ transformStack.length + " times");
|
1869
1873
|
}
|
1874
|
+
transformStack[transformCount] = g2.getTransform();
|
1875
|
+
transformCount++;
|
1876
|
+
}
|
1870
1877
|
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
}
|
1877
|
-
transformCount--;
|
1878
|
-
g2.setTransform(transformStack[transformCount]);
|
1878
|
+
@Override
|
1879
|
+
public void popMatrix() {
|
1880
|
+
if (transformCount == 0) {
|
1881
|
+
throw new RuntimeException("missing a pushMatrix() "
|
1882
|
+
+ "to go with that popMatrix()");
|
1879
1883
|
}
|
1884
|
+
transformCount--;
|
1885
|
+
g2.setTransform(transformStack[transformCount]);
|
1886
|
+
}
|
1880
1887
|
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1888
|
+
//////////////////////////////////////////////////////////////
|
1889
|
+
// MATRIX TRANSFORMS
|
1890
|
+
@Override
|
1891
|
+
public void translate(float tx, float ty) {
|
1892
|
+
g2.translate(tx, ty);
|
1893
|
+
}
|
1887
1894
|
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1895
|
+
//public void translate(float tx, float ty, float tz)
|
1896
|
+
@Override
|
1897
|
+
public void rotate(float angle) {
|
1898
|
+
g2.rotate(angle);
|
1899
|
+
}
|
1893
1900
|
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1901
|
+
@Override
|
1902
|
+
public void rotateX(float angle) {
|
1903
|
+
showDepthWarning("rotateX");
|
1904
|
+
}
|
1898
1905
|
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1906
|
+
@Override
|
1907
|
+
public void rotateY(float angle) {
|
1908
|
+
showDepthWarning("rotateY");
|
1909
|
+
}
|
1903
1910
|
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1911
|
+
@Override
|
1912
|
+
public void rotateZ(float angle) {
|
1913
|
+
showDepthWarning("rotateZ");
|
1914
|
+
}
|
1908
1915
|
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1916
|
+
@Override
|
1917
|
+
public void rotate(float angle, float vx, float vy, float vz) {
|
1918
|
+
showVariationWarning("rotate");
|
1919
|
+
}
|
1913
1920
|
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1921
|
+
@Override
|
1922
|
+
public void scale(float s) {
|
1923
|
+
g2.scale(s, s);
|
1924
|
+
}
|
1918
1925
|
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1926
|
+
@Override
|
1927
|
+
public void scale(float sx, float sy) {
|
1928
|
+
g2.scale(sx, sy);
|
1929
|
+
}
|
1923
1930
|
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1931
|
+
@Override
|
1932
|
+
public void scale(float sx, float sy, float sz) {
|
1933
|
+
showDepthWarningXYZ("scale");
|
1934
|
+
}
|
1928
1935
|
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1936
|
+
@Override
|
1937
|
+
public void shearX(float angle) {
|
1938
|
+
g2.shear(Math.tan(angle), 0);
|
1939
|
+
}
|
1933
1940
|
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1941
|
+
@Override
|
1942
|
+
public void shearY(float angle) {
|
1943
|
+
g2.shear(0, Math.tan(angle));
|
1944
|
+
}
|
1938
1945
|
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
+
//////////////////////////////////////////////////////////////
|
1947
|
+
// MATRIX MORE
|
1948
|
+
@Override
|
1949
|
+
public void resetMatrix() {
|
1950
|
+
g2.setTransform(new AffineTransform());
|
1951
|
+
g2.scale(pixelDensity, pixelDensity);
|
1952
|
+
}
|
1946
1953
|
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1954
|
+
//public void applyMatrix(PMatrix2D source)
|
1955
|
+
@Override
|
1956
|
+
public void applyMatrix(float n00, float n01, float n02,
|
1957
|
+
float n10, float n11, float n12) {
|
1958
|
+
//System.out.println("PGraphicsJava2D.applyMatrix()");
|
1959
|
+
//System.out.println(new AffineTransform(n00, n10, n01, n11, n02, n12));
|
1960
|
+
g2.transform(new AffineTransform(n00, n10, n01, n11, n02, n12));
|
1961
|
+
//g2.transform(new AffineTransform(n00, n01, n02, n10, n11, n12));
|
1962
|
+
}
|
1956
1963
|
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1964
|
+
//public void applyMatrix(PMatrix3D source)
|
1965
|
+
@Override
|
1966
|
+
public void applyMatrix(float n00, float n01, float n02, float n03,
|
1967
|
+
float n10, float n11, float n12, float n13,
|
1968
|
+
float n20, float n21, float n22, float n23,
|
1969
|
+
float n30, float n31, float n32, float n33) {
|
1970
|
+
showVariationWarning("applyMatrix");
|
1971
|
+
}
|
1965
1972
|
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1973
|
+
//////////////////////////////////////////////////////////////
|
1974
|
+
// MATRIX GET/SET
|
1975
|
+
@Override
|
1976
|
+
public PMatrix getMatrix() {
|
1977
|
+
return getMatrix((PMatrix2D) null);
|
1978
|
+
}
|
1972
1979
|
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1980
|
+
@Override
|
1981
|
+
public PMatrix2D getMatrix(PMatrix2D target) {
|
1982
|
+
if (target == null) {
|
1983
|
+
target = new PMatrix2D();
|
1984
|
+
}
|
1985
|
+
g2.getTransform().getMatrix(transform);
|
1986
|
+
target.set((float) transform[0], (float) transform[2], (float) transform[4],
|
1987
|
+
(float) transform[1], (float) transform[3], (float) transform[5]);
|
1988
|
+
return target;
|
1989
|
+
}
|
1983
1990
|
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1991
|
+
@Override
|
1992
|
+
public PMatrix3D getMatrix(PMatrix3D target) {
|
1993
|
+
showVariationWarning("getMatrix");
|
1994
|
+
return target;
|
1995
|
+
}
|
1989
1996
|
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
+
//public void setMatrix(PMatrix source)
|
1998
|
+
@Override
|
1999
|
+
public void setMatrix(PMatrix2D source) {
|
2000
|
+
g2.setTransform(new AffineTransform(source.m00, source.m10,
|
2001
|
+
source.m01, source.m11,
|
2002
|
+
source.m02, source.m12));
|
2003
|
+
}
|
1997
2004
|
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2005
|
+
@Override
|
2006
|
+
public void setMatrix(PMatrix3D source) {
|
2007
|
+
showVariationWarning("setMatrix");
|
2008
|
+
}
|
2002
2009
|
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
//////////////////////////////////////////////////////////////
|
2009
|
-
// CAMERA and PROJECTION
|
2010
|
-
// Inherit the plaintive warnings from PGraphics
|
2011
|
-
//public void beginCamera()
|
2012
|
-
//public void endCamera()
|
2013
|
-
//public void camera()
|
2014
|
-
//public void camera(float eyeX, float eyeY, float eyeZ,
|
2015
|
-
// float centerX, float centerY, float centerZ,
|
2016
|
-
// float upX, float upY, float upZ)
|
2017
|
-
//public void printCamera()
|
2018
|
-
//public void ortho()
|
2019
|
-
//public void ortho(float left, float right,
|
2020
|
-
// float bottom, float top,
|
2021
|
-
// float near, float far)
|
2022
|
-
//public void perspective()
|
2023
|
-
//public void perspective(float fov, float aspect, float near, float far)
|
2024
|
-
//public void frustum(float left, float right,
|
2025
|
-
// float bottom, float top,
|
2026
|
-
// float near, float far)
|
2027
|
-
//public void printProjection()
|
2028
|
-
//////////////////////////////////////////////////////////////
|
2029
|
-
// SCREEN and MODEL transforms
|
2030
|
-
@Override
|
2031
|
-
public float screenX(float x, float y) {
|
2032
|
-
g2.getTransform().getMatrix(transform);
|
2033
|
-
return (float) transform[0] * x + (float) transform[2] * y + (float) transform[4];
|
2034
|
-
}
|
2010
|
+
@Override
|
2011
|
+
public void printMatrix() {
|
2012
|
+
getMatrix((PMatrix2D) null).print();
|
2013
|
+
}
|
2035
2014
|
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2015
|
+
//////////////////////////////////////////////////////////////
|
2016
|
+
// CAMERA and PROJECTION
|
2017
|
+
// Inherit the plaintive warnings from PGraphics
|
2018
|
+
//public void beginCamera()
|
2019
|
+
//public void endCamera()
|
2020
|
+
//public void camera()
|
2021
|
+
//public void camera(float eyeX, float eyeY, float eyeZ,
|
2022
|
+
// float centerX, float centerY, float centerZ,
|
2023
|
+
// float upX, float upY, float upZ)
|
2024
|
+
//public void printCamera()
|
2025
|
+
//public void ortho()
|
2026
|
+
//public void ortho(float left, float right,
|
2027
|
+
// float bottom, float top,
|
2028
|
+
// float near, float far)
|
2029
|
+
//public void perspective()
|
2030
|
+
//public void perspective(float fov, float aspect, float near, float far)
|
2031
|
+
//public void frustum(float left, float right,
|
2032
|
+
// float bottom, float top,
|
2033
|
+
// float near, float far)
|
2034
|
+
//public void printProjection()
|
2035
|
+
//////////////////////////////////////////////////////////////
|
2036
|
+
// SCREEN and MODEL transforms
|
2037
|
+
@Override
|
2038
|
+
public float screenX(float x, float y) {
|
2039
|
+
g2.getTransform().getMatrix(transform);
|
2040
|
+
return (float) transform[0] * x + (float) transform[2] * y + (float) transform[4];
|
2041
|
+
}
|
2041
2042
|
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2043
|
+
@Override
|
2044
|
+
public float screenY(float x, float y) {
|
2045
|
+
g2.getTransform().getMatrix(transform);
|
2046
|
+
return (float) transform[1] * x + (float) transform[3] * y + (float) transform[5];
|
2047
|
+
}
|
2047
2048
|
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2049
|
+
@Override
|
2050
|
+
public float screenX(float x, float y, float z) {
|
2051
|
+
showDepthWarningXYZ("screenX");
|
2052
|
+
return 0;
|
2053
|
+
}
|
2053
2054
|
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
//public float modelX(float x, float y, float z)
|
2061
|
-
//public float modelY(float x, float y, float z)
|
2062
|
-
//public float modelZ(float x, float y, float z)
|
2063
|
-
//////////////////////////////////////////////////////////////
|
2064
|
-
// STYLE
|
2065
|
-
// pushStyle(), popStyle(), style() and getStyle() inherited.
|
2066
|
-
//////////////////////////////////////////////////////////////
|
2067
|
-
// STROKE CAP/JOIN/WEIGHT
|
2068
|
-
@Override
|
2069
|
-
public void strokeCap(int cap) {
|
2070
|
-
super.strokeCap(cap);
|
2071
|
-
strokeImpl();
|
2072
|
-
}
|
2055
|
+
@Override
|
2056
|
+
public float screenY(float x, float y, float z) {
|
2057
|
+
showDepthWarningXYZ("screenY");
|
2058
|
+
return 0;
|
2059
|
+
}
|
2073
2060
|
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2061
|
+
@Override
|
2062
|
+
public float screenZ(float x, float y, float z) {
|
2063
|
+
showDepthWarningXYZ("screenZ");
|
2064
|
+
return 0;
|
2065
|
+
}
|
2079
2066
|
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2067
|
+
//public float modelX(float x, float y, float z)
|
2068
|
+
//public float modelY(float x, float y, float z)
|
2069
|
+
//public float modelZ(float x, float y, float z)
|
2070
|
+
//////////////////////////////////////////////////////////////
|
2071
|
+
// STYLE
|
2072
|
+
// pushStyle(), popStyle(), style() and getStyle() inherited.
|
2073
|
+
//////////////////////////////////////////////////////////////
|
2074
|
+
// STROKE CAP/JOIN/WEIGHT
|
2075
|
+
@Override
|
2076
|
+
public void strokeCap(int cap) {
|
2077
|
+
super.strokeCap(cap);
|
2078
|
+
strokeImpl();
|
2079
|
+
}
|
2085
2080
|
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
cap = BasicStroke.CAP_SQUARE;
|
2092
|
-
}
|
2081
|
+
@Override
|
2082
|
+
public void strokeJoin(int join) {
|
2083
|
+
super.strokeJoin(join);
|
2084
|
+
strokeImpl();
|
2085
|
+
}
|
2093
2086
|
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
}
|
2087
|
+
@Override
|
2088
|
+
public void strokeWeight(float weight) {
|
2089
|
+
super.strokeWeight(weight);
|
2090
|
+
strokeImpl();
|
2091
|
+
}
|
2100
2092
|
|
2101
|
-
|
2102
|
-
|
2093
|
+
protected void strokeImpl() {
|
2094
|
+
int cap = BasicStroke.CAP_BUTT;
|
2095
|
+
if (strokeCap == ROUND) {
|
2096
|
+
cap = BasicStroke.CAP_ROUND;
|
2097
|
+
} else if (strokeCap == PROJECT) {
|
2098
|
+
cap = BasicStroke.CAP_SQUARE;
|
2103
2099
|
}
|
2104
2100
|
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
super.strokeFromCalc();
|
2111
|
-
strokeColorObject = new Color(strokeColor, true);
|
2112
|
-
strokeGradient = false;
|
2101
|
+
int join = BasicStroke.JOIN_BEVEL;
|
2102
|
+
if (strokeJoin == MITER) {
|
2103
|
+
join = BasicStroke.JOIN_MITER;
|
2104
|
+
} else if (strokeJoin == ROUND) {
|
2105
|
+
join = BasicStroke.JOIN_ROUND;
|
2113
2106
|
}
|
2114
2107
|
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
@Override
|
2119
|
-
protected void tintFromCalc() {
|
2120
|
-
super.tintFromCalc();
|
2121
|
-
// TODO actually implement tinted images
|
2122
|
-
tintColorObject = new Color(tintColor, true);
|
2123
|
-
}
|
2108
|
+
strokeObject = new BasicStroke(strokeWeight, cap, join);
|
2109
|
+
g2.setStroke(strokeObject);
|
2110
|
+
}
|
2124
2111
|
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
//
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2112
|
+
//////////////////////////////////////////////////////////////
|
2113
|
+
// STROKE
|
2114
|
+
// noStroke() and stroke() inherited from PGraphics.
|
2115
|
+
@Override
|
2116
|
+
protected void strokeFromCalc() {
|
2117
|
+
super.strokeFromCalc();
|
2118
|
+
strokeColorObject = new Color(strokeColor, true);
|
2119
|
+
strokeGradient = false;
|
2120
|
+
}
|
2121
|
+
|
2122
|
+
//////////////////////////////////////////////////////////////
|
2123
|
+
// TINT
|
2124
|
+
// noTint() and tint() inherited from PGraphics.
|
2125
|
+
@Override
|
2126
|
+
protected void tintFromCalc() {
|
2127
|
+
super.tintFromCalc();
|
2128
|
+
// TODO actually implement tinted images
|
2129
|
+
tintColorObject = new Color(tintColor, true);
|
2130
|
+
}
|
2131
|
+
|
2132
|
+
//////////////////////////////////////////////////////////////
|
2133
|
+
// FILL
|
2134
|
+
// noFill() and fill() inherited from PGraphics.
|
2135
|
+
@Override
|
2136
|
+
protected void fillFromCalc() {
|
2137
|
+
super.fillFromCalc();
|
2138
|
+
fillColorObject = new Color(fillColor, true);
|
2139
|
+
fillGradient = false;
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
//////////////////////////////////////////////////////////////
|
2143
|
+
// MATERIAL PROPERTIES
|
2144
|
+
//public void ambient(int rgb)
|
2145
|
+
//public void ambient(float gray)
|
2146
|
+
//public void ambient(float x, float y, float z)
|
2147
|
+
//protected void ambientFromCalc()
|
2148
|
+
//public void specular(int rgb)
|
2149
|
+
//public void specular(float gray)
|
2150
|
+
//public void specular(float x, float y, float z)
|
2151
|
+
//protected void specularFromCalc()
|
2152
|
+
//public void shininess(float shine)
|
2153
|
+
//public void emissive(int rgb)
|
2154
|
+
//public void emissive(float gray)
|
2155
|
+
//public void emissive(float x, float y, float z )
|
2156
|
+
//protected void emissiveFromCalc()
|
2157
|
+
//////////////////////////////////////////////////////////////
|
2158
|
+
// LIGHTS
|
2159
|
+
//public void lights()
|
2160
|
+
//public void noLights()
|
2161
|
+
//public void ambientLight(float red, float green, float blue)
|
2162
|
+
//public void ambientLight(float red, float green, float blue,
|
2163
|
+
// float x, float y, float z)
|
2164
|
+
//public void directionalLight(float red, float green, float blue,
|
2165
|
+
// float nx, float ny, float nz)
|
2166
|
+
//public void pointLight(float red, float green, float blue,
|
2167
|
+
// float x, float y, float z)
|
2168
|
+
//public void spotLight(float red, float green, float blue,
|
2169
|
+
// float x, float y, float z,
|
2170
|
+
// float nx, float ny, float nz,
|
2171
|
+
// float angle, float concentration)
|
2172
|
+
//public void lightFalloff(float constant, float linear, float quadratic)
|
2173
|
+
//public void lightSpecular(float x, float y, float z)
|
2174
|
+
//protected void lightPosition(int num, float x, float y, float z)
|
2175
|
+
//protected void lightDirection(int num, float x, float y, float z)
|
2176
|
+
//////////////////////////////////////////////////////////////
|
2177
|
+
// BACKGROUND
|
2178
|
+
int[] clearPixels;
|
2179
|
+
|
2180
|
+
protected void clearPixels(int color) {
|
2181
|
+
// On a hi-res display, image may be larger than width/height
|
2182
|
+
int imageWidth = image.getWidth(null);
|
2183
|
+
int imageHeight = image.getHeight(null);
|
2184
|
+
|
2185
|
+
// Create a small array that can be used to set the pixels several times.
|
2186
|
+
// Using a single-pixel line of length 'width' is a tradeoff between
|
2187
|
+
// speed (setting each pixel individually is too slow) and memory
|
2188
|
+
// (an array for width*height would waste lots of memory if it stayed
|
2189
|
+
// resident, and would terrify the gc if it were re-created on each trip
|
2190
|
+
// to background().
|
2184
2191
|
// WritableRaster raster = ((BufferedImage) image).getRaster();
|
2185
2192
|
// WritableRaster raster = image.getRaster();
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2192
|
-
|
2193
|
-
}
|
2193
|
+
WritableRaster raster = getRaster();
|
2194
|
+
if ((clearPixels == null) || (clearPixels.length < imageWidth)) {
|
2195
|
+
clearPixels = new int[imageWidth];
|
2196
|
+
}
|
2197
|
+
Arrays.fill(clearPixels, 0, imageWidth, backgroundColor);
|
2198
|
+
for (int i = 0; i < imageHeight; i++) {
|
2199
|
+
raster.setDataElements(0, i, imageWidth, 1, clearPixels);
|
2194
2200
|
}
|
2201
|
+
}
|
2195
2202
|
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
+
// background() methods inherited from PGraphics, along with the
|
2204
|
+
// PImage version of backgroundImpl(), since it just calls set().
|
2205
|
+
//public void backgroundImpl(PImage image)
|
2206
|
+
@Override
|
2207
|
+
public void backgroundImpl() {
|
2208
|
+
if (backgroundAlpha) {
|
2209
|
+
clearPixels(backgroundColor);
|
2203
2210
|
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2211
|
+
} else {
|
2212
|
+
Color bgColor = new Color(backgroundColor);
|
2213
|
+
// seems to fire an additional event that causes flickering,
|
2214
|
+
// like an extra background erase on OS X
|
2208
2215
|
// if (canvas != null) {
|
2209
2216
|
// canvas.setBackground(bgColor);
|
2210
2217
|
// }
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2218
|
+
//new Exception().printStackTrace(System.out);
|
2219
|
+
// in case people do transformations before background(),
|
2220
|
+
// need to handle this with a push/reset/pop
|
2221
|
+
Composite oldComposite = g2.getComposite();
|
2222
|
+
g2.setComposite(defaultComposite);
|
2223
|
+
|
2224
|
+
pushMatrix();
|
2225
|
+
resetMatrix();
|
2226
|
+
g2.setColor(bgColor); //, backgroundAlpha));
|
2220
2227
|
// g2.fillRect(0, 0, width, height);
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2228
|
+
// On a hi-res display, image may be larger than width/height
|
2229
|
+
if (image != null) {
|
2230
|
+
// image will be null in subclasses (i.e. PDF)
|
2231
|
+
g2.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
|
2232
|
+
} else {
|
2233
|
+
// hope for the best if image is null
|
2234
|
+
g2.fillRect(0, 0, width, height);
|
2235
|
+
}
|
2236
|
+
popMatrix();
|
2230
2237
|
|
2231
|
-
|
2232
|
-
}
|
2238
|
+
g2.setComposite(oldComposite);
|
2233
2239
|
}
|
2240
|
+
}
|
2234
2241
|
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2242
|
+
//////////////////////////////////////////////////////////////
|
2243
|
+
// COLOR MODE
|
2244
|
+
// All colorMode() variations are inherited from PGraphics.
|
2245
|
+
//////////////////////////////////////////////////////////////
|
2246
|
+
// COLOR CALC
|
2247
|
+
// colorCalc() and colorCalcARGB() inherited from PGraphics.
|
2248
|
+
//////////////////////////////////////////////////////////////
|
2249
|
+
// COLOR DATATYPE STUFFING
|
2250
|
+
// final color() variations inherited.
|
2251
|
+
//////////////////////////////////////////////////////////////
|
2252
|
+
// COLOR DATATYPE EXTRACTION
|
2253
|
+
// final methods alpha, red, green, blue,
|
2254
|
+
// hue, saturation, and brightness all inherited.
|
2255
|
+
//////////////////////////////////////////////////////////////
|
2256
|
+
// COLOR DATATYPE INTERPOLATION
|
2257
|
+
// both lerpColor variants inherited.
|
2258
|
+
//////////////////////////////////////////////////////////////
|
2259
|
+
// BEGIN/END RAW
|
2260
|
+
@Override
|
2261
|
+
public void beginRaw(PGraphics recorderRaw) {
|
2262
|
+
showMethodWarning("beginRaw");
|
2263
|
+
}
|
2257
2264
|
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2265
|
+
@Override
|
2266
|
+
public void endRaw() {
|
2267
|
+
showMethodWarning("endRaw");
|
2268
|
+
}
|
2269
|
+
|
2270
|
+
//////////////////////////////////////////////////////////////
|
2271
|
+
// WARNINGS and EXCEPTIONS
|
2272
|
+
// showWarning and showException inherited.
|
2273
|
+
//////////////////////////////////////////////////////////////
|
2274
|
+
// RENDERER SUPPORT QUERIES
|
2275
|
+
//public boolean displayable() // true
|
2276
|
+
//public boolean is2D() // true
|
2277
|
+
//public boolean is3D() // false
|
2278
|
+
//////////////////////////////////////////////////////////////
|
2279
|
+
// PIMAGE METHODS
|
2280
|
+
// getImage, setCache, getCache, removeCache, isModified, setModified
|
2281
|
+
protected WritableRaster getRaster() {
|
2282
|
+
WritableRaster raster = null;
|
2283
|
+
if (primaryGraphics) {
|
2284
|
+
/*
|
2278
2285
|
// 'offscreen' will probably be removed in the next release
|
2279
2286
|
if (useOffscreen) {
|
2280
2287
|
raster = offscreen.getRaster();
|
2281
2288
|
} else*/ if (image instanceof VolatileImage) {
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
|
2288
|
-
}
|
2289
|
-
|
2290
|
-
// On Raspberry Pi (and perhaps other platforms, the color buffer won't
|
2291
|
-
// necessarily be the int array that we'd like. Need to convert it here.
|
2292
|
-
// Not that this would probably mean getRaster() would need to work more
|
2293
|
-
// like loadRaster/updateRaster because the pixels will need to be
|
2294
|
-
// temporarily moved to (and later from) a buffer that's understood by
|
2295
|
-
// the rest of the Processing source.
|
2296
|
-
// https://github.com/processing/processing/issues/2010
|
2297
|
-
if (raster.getTransferType() != DataBuffer.TYPE_INT) {
|
2298
|
-
System.err.println("See https://github.com/processing/processing/issues/2010");
|
2299
|
-
throw new RuntimeException("Pixel operations are not supported on this device.");
|
2300
|
-
}
|
2301
|
-
return raster;
|
2289
|
+
// when possible, we'll try VolatileImage
|
2290
|
+
raster = ((VolatileImage) image).getSnapshot().getRaster();
|
2291
|
+
}
|
2292
|
+
}
|
2293
|
+
if (raster == null) {
|
2294
|
+
raster = ((BufferedImage) image).getRaster();
|
2302
2295
|
}
|
2303
2296
|
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2297
|
+
// On Raspberry Pi (and perhaps other platforms, the color buffer won't
|
2298
|
+
// necessarily be the int array that we'd like. Need to convert it here.
|
2299
|
+
// Not that this would probably mean getRaster() would need to work more
|
2300
|
+
// like loadRaster/updateRaster because the pixels will need to be
|
2301
|
+
// temporarily moved to (and later from) a buffer that's understood by
|
2302
|
+
// the rest of the Processing source.
|
2303
|
+
// https://github.com/processing/processing/issues/2010
|
2304
|
+
if (raster.getTransferType() != DataBuffer.TYPE_INT) {
|
2305
|
+
System.err.println("See https://github.com/processing/processing/issues/2010");
|
2306
|
+
throw new RuntimeException("Pixel operations are not supported on this device.");
|
2307
|
+
}
|
2308
|
+
return raster;
|
2309
|
+
}
|
2309
2310
|
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2311
|
+
@Override
|
2312
|
+
public void loadPixels() {
|
2313
|
+
if (pixels == null || (pixels.length != pixelWidth * pixelHeight)) {
|
2314
|
+
pixels = new int[pixelWidth * pixelHeight];
|
2315
|
+
}
|
2316
|
+
|
2317
|
+
WritableRaster raster = getRaster();
|
2318
|
+
raster.getDataElements(0, 0, pixelWidth, pixelHeight, pixels);
|
2319
|
+
if (raster.getNumBands() == 3) {
|
2320
|
+
// Java won't set the high bits when RGB, returns 0 for alpha
|
2321
|
+
// https://github.com/processing/processing/issues/2030
|
2322
|
+
for (int i = 0; i < pixels.length; i++) {
|
2323
|
+
pixels[i] = 0xff000000 | pixels[i];
|
2324
|
+
}
|
2325
|
+
}
|
2326
|
+
//((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width);
|
2320
2327
|
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
|
2321
2328
|
// WritableRaster raster = image.getRaster();
|
2322
|
-
|
2329
|
+
}
|
2323
2330
|
|
2324
2331
|
// /**
|
2325
2332
|
// * Update the pixels[] buffer to the PGraphics image.
|
@@ -2334,27 +2341,27 @@ public class PGraphicsJava2D extends PGraphics {
|
|
2334
2341
|
//// WritableRaster raster = image.getRaster();
|
2335
2342
|
// updatePixels(0, 0, width, height);
|
2336
2343
|
// }
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2344
|
+
/**
|
2345
|
+
* Update the pixels[] buffer to the PGraphics image.
|
2346
|
+
* <P>
|
2347
|
+
* Unlike in PImage, where updatePixels() only requests that the update
|
2348
|
+
* happens, in PGraphicsJava2D, this will happen immediately.
|
2349
|
+
*/
|
2350
|
+
@Override
|
2351
|
+
public void updatePixels(int x, int y, int c, int d) {
|
2352
|
+
//if ((x == 0) && (y == 0) && (c == width) && (d == height)) {
|
2346
2353
|
// System.err.format("%d %d %d %d .. w/h = %d %d .. pw/ph = %d %d %n", x, y, c, d, width, height, pixelWidth, pixelHeight);
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2354
|
+
if ((x != 0) || (y != 0) || (c != pixelWidth) || (d != pixelHeight)) {
|
2355
|
+
// Show a warning message, but continue anyway.
|
2356
|
+
showVariationWarning("updatePixels(x, y, w, h)");
|
2350
2357
|
// new Exception().printStackTrace(System.out);
|
2351
|
-
|
2358
|
+
}
|
2352
2359
|
// updatePixels();
|
2353
|
-
|
2354
|
-
|
2355
|
-
}
|
2356
|
-
modified = true;
|
2360
|
+
if (pixels != null) {
|
2361
|
+
getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
|
2357
2362
|
}
|
2363
|
+
modified = true;
|
2364
|
+
}
|
2358
2365
|
|
2359
2366
|
// @Override
|
2360
2367
|
// protected void updatePixelsImpl(int x, int y, int w, int h) {
|
@@ -2366,170 +2373,170 @@ public class PGraphicsJava2D extends PGraphics {
|
|
2366
2373
|
// }
|
2367
2374
|
// getRaster().setDataElements(0, 0, width, height, pixels);
|
2368
2375
|
// }
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2376
|
+
//////////////////////////////////////////////////////////////
|
2377
|
+
// GET/SET
|
2378
|
+
static int getset[] = new int[1];
|
2372
2379
|
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2380
|
+
@Override
|
2381
|
+
public int get(int x, int y) {
|
2382
|
+
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
2383
|
+
return 0;
|
2384
|
+
}
|
2385
|
+
//return ((BufferedImage) image).getRGB(x, y);
|
2379
2386
|
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
}
|
2386
|
-
return getset[0];
|
2387
|
+
WritableRaster raster = getRaster();
|
2388
|
+
raster.getDataElements(x, y, getset);
|
2389
|
+
if (raster.getNumBands() == 3) {
|
2390
|
+
// https://github.com/processing/processing/issues/2030
|
2391
|
+
return getset[0] | 0xff000000;
|
2387
2392
|
}
|
2393
|
+
return getset[0];
|
2394
|
+
}
|
2388
2395
|
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2396
|
+
//public PImage get(int x, int y, int w, int h)
|
2397
|
+
@Override
|
2398
|
+
protected void getImpl(int sourceX, int sourceY,
|
2399
|
+
int sourceWidth, int sourceHeight,
|
2400
|
+
PImage target, int targetX, int targetY) {
|
2401
|
+
// last parameter to getRGB() is the scan size of the *target* buffer
|
2402
|
+
//((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w);
|
2396
2403
|
// WritableRaster raster =
|
2397
2404
|
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
|
2398
|
-
|
2405
|
+
WritableRaster raster = getRaster();
|
2399
2406
|
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2407
|
+
if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) {
|
2408
|
+
raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
|
2409
|
+
// https://github.com/processing/processing/issues/2030
|
2410
|
+
if (raster.getNumBands() == 3) {
|
2411
|
+
target.filter(OPAQUE);
|
2412
|
+
}
|
2406
2413
|
|
2414
|
+
} else {
|
2415
|
+
// TODO optimize, incredibly inefficient to reallocate this much memory
|
2416
|
+
int[] temp = new int[sourceWidth * sourceHeight];
|
2417
|
+
raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, temp);
|
2418
|
+
|
2419
|
+
// Copy the temporary output pixels over to the outgoing image
|
2420
|
+
int sourceOffset = 0;
|
2421
|
+
int targetOffset = targetY * target.pixelWidth + targetX;
|
2422
|
+
for (int y = 0; y < sourceHeight; y++) {
|
2423
|
+
if (raster.getNumBands() == 3) {
|
2424
|
+
for (int i = 0; i < sourceWidth; i++) {
|
2425
|
+
// Need to set the high bits for this feller
|
2426
|
+
// https://github.com/processing/processing/issues/2030
|
2427
|
+
target.pixels[targetOffset + i] = 0xFF000000 | temp[sourceOffset + i];
|
2428
|
+
}
|
2407
2429
|
} else {
|
2408
|
-
|
2409
|
-
int[] temp = new int[sourceWidth * sourceHeight];
|
2410
|
-
raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, temp);
|
2411
|
-
|
2412
|
-
// Copy the temporary output pixels over to the outgoing image
|
2413
|
-
int sourceOffset = 0;
|
2414
|
-
int targetOffset = targetY * target.pixelWidth + targetX;
|
2415
|
-
for (int y = 0; y < sourceHeight; y++) {
|
2416
|
-
if (raster.getNumBands() == 3) {
|
2417
|
-
for (int i = 0; i < sourceWidth; i++) {
|
2418
|
-
// Need to set the high bits for this feller
|
2419
|
-
// https://github.com/processing/processing/issues/2030
|
2420
|
-
target.pixels[targetOffset + i] = 0xFF000000 | temp[sourceOffset + i];
|
2421
|
-
}
|
2422
|
-
} else {
|
2423
|
-
System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth);
|
2424
|
-
}
|
2425
|
-
sourceOffset += sourceWidth;
|
2426
|
-
targetOffset += target.pixelWidth;
|
2427
|
-
}
|
2430
|
+
System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth);
|
2428
2431
|
}
|
2432
|
+
sourceOffset += sourceWidth;
|
2433
|
+
targetOffset += target.pixelWidth;
|
2434
|
+
}
|
2429
2435
|
}
|
2436
|
+
}
|
2430
2437
|
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2438
|
+
@Override
|
2439
|
+
public void set(int x, int y, int argb) {
|
2440
|
+
if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) {
|
2441
|
+
return;
|
2442
|
+
}
|
2436
2443
|
// ((BufferedImage) image).setRGB(x, y, argb);
|
2437
|
-
|
2444
|
+
getset[0] = argb;
|
2438
2445
|
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
|
2439
2446
|
// WritableRaster raster = image.getRaster();
|
2440
|
-
|
2441
|
-
|
2447
|
+
getRaster().setDataElements(x, y, getset);
|
2448
|
+
}
|
2442
2449
|
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
+
//public void set(int x, int y, PImage img)
|
2451
|
+
@Override
|
2452
|
+
protected void setImpl(PImage sourceImage,
|
2453
|
+
int sourceX, int sourceY,
|
2454
|
+
int sourceWidth, int sourceHeight,
|
2455
|
+
int targetX, int targetY) {
|
2456
|
+
WritableRaster raster = getRaster();
|
2450
2457
|
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
|
2451
2458
|
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2459
|
+
if ((sourceX == 0) && (sourceY == 0)
|
2460
|
+
&& (sourceWidth == sourceImage.pixelWidth)
|
2461
|
+
&& (sourceHeight == sourceImage.pixelHeight)) {
|
2455
2462
|
// System.out.format("%d %d %dx%d %d%n", targetX, targetY,
|
2456
2463
|
// sourceImage.width, sourceImage.height,
|
2457
2464
|
// sourceImage.pixels.length);
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
}
|
2465
|
+
raster.setDataElements(targetX, targetY,
|
2466
|
+
sourceImage.pixelWidth, sourceImage.pixelHeight,
|
2467
|
+
sourceImage.pixels);
|
2468
|
+
} else {
|
2469
|
+
// TODO optimize, incredibly inefficient to reallocate this much memory
|
2470
|
+
PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight);
|
2471
|
+
raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels);
|
2466
2472
|
}
|
2473
|
+
}
|
2467
2474
|
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2475
|
+
//////////////////////////////////////////////////////////////
|
2476
|
+
// MASK
|
2477
|
+
static final String MASK_WARNING
|
2478
|
+
= "mask() cannot be used on the main drawing surface";
|
2472
2479
|
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2480
|
+
@Override
|
2481
|
+
public void mask(int[] alpha) {
|
2482
|
+
if (primaryGraphics) {
|
2483
|
+
showWarning(MASK_WARNING);
|
2477
2484
|
|
2478
|
-
|
2479
|
-
|
2480
|
-
}
|
2485
|
+
} else {
|
2486
|
+
super.mask(alpha);
|
2481
2487
|
}
|
2488
|
+
}
|
2482
2489
|
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
2490
|
+
@Override
|
2491
|
+
public void mask(PImage alpha) {
|
2492
|
+
if (primaryGraphics) {
|
2493
|
+
showWarning(MASK_WARNING);
|
2487
2494
|
|
2488
|
-
|
2489
|
-
|
2490
|
-
}
|
2495
|
+
} else {
|
2496
|
+
super.mask(alpha);
|
2491
2497
|
}
|
2498
|
+
}
|
2492
2499
|
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2500
|
+
//////////////////////////////////////////////////////////////
|
2501
|
+
// FILTER
|
2502
|
+
// Because the PImage versions call loadPixels() and
|
2503
|
+
// updatePixels(), no need to override anything here.
|
2504
|
+
//public void filter(int kind)
|
2505
|
+
//public void filter(int kind, float param)
|
2506
|
+
//////////////////////////////////////////////////////////////
|
2507
|
+
// COPY
|
2508
|
+
@Override
|
2509
|
+
public void copy(int sx, int sy, int sw, int sh,
|
2510
|
+
int dx, int dy, int dw, int dh) {
|
2511
|
+
if ((sw != dw) || (sh != dh)) {
|
2512
|
+
g2.drawImage(image, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
|
2506
2513
|
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
}
|
2514
|
+
} else {
|
2515
|
+
dx = dx - sx; // java2d's "dx" is the delta, not dest
|
2516
|
+
dy = dy - sy;
|
2517
|
+
g2.copyArea(sx, sy, sw, sh, dx, dy);
|
2512
2518
|
}
|
2519
|
+
}
|
2513
2520
|
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
|
2521
|
+
@Override
|
2522
|
+
public void copy(PImage src,
|
2523
|
+
int sx, int sy, int sw, int sh,
|
2524
|
+
int dx, int dy, int dw, int dh) {
|
2525
|
+
g2.drawImage((Image) src.getNative(),
|
2526
|
+
dx, dy, dx + dw, dy + dh,
|
2527
|
+
sx, sy, sx + sw, sy + sh, null);
|
2528
|
+
}
|
2522
2529
|
|
2523
|
-
|
2524
|
-
|
2530
|
+
//////////////////////////////////////////////////////////////
|
2531
|
+
// BLEND
|
2525
2532
|
// static public int blendColor(int c1, int c2, int mode)
|
2526
2533
|
// public void blend(int sx, int sy, int sw, int sh,
|
2527
2534
|
// int dx, int dy, int dw, int dh, int mode)
|
2528
2535
|
// public void blend(PImage src,
|
2529
2536
|
// int sx, int sy, int sw, int sh,
|
2530
2537
|
// int dx, int dy, int dw, int dh, int mode)
|
2531
|
-
|
2532
|
-
|
2538
|
+
//////////////////////////////////////////////////////////////
|
2539
|
+
// SAVE
|
2533
2540
|
// public void save(String filename) {
|
2534
2541
|
// loadPixels();
|
2535
2542
|
// super.save(filename);
|