propane 3.3.1-java → 3.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.3.0.jar'
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.10'
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.1+'
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 = (Double) scalar.toJava(Double.class);
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
- double divisor = (scalar instanceof RubyFloat)
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
- double new_mag = (scalar instanceof RubyFloat)
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
- public Graphics2D g2;
60
+ public Graphics2D g2;
61
61
  // protected BufferedImage offscreen;
62
62
 
63
- Composite defaultComposite;
63
+ Composite defaultComposite;
64
64
 
65
- GeneralPath gpath;
65
+ GeneralPath gpath;
66
66
 
67
- // path for contours so gpath can be closed
68
- GeneralPath auxPath;
67
+ // path for contours so gpath can be closed
68
+ GeneralPath auxPath;
69
69
 
70
- boolean openContour;
70
+ boolean openContour;
71
71
 
72
- /// break the shape at the next vertex (next vertex() call is a moveto())
73
- boolean breakShape;
72
+ /// break the shape at the next vertex (next vertex() call is a moveto())
73
+ boolean breakShape;
74
74
 
75
- /// coordinates for internal curve calculation
76
- float[] curveCoordX;
77
- float[] curveCoordY;
78
- float[] curveDrawX;
79
- float[] curveDrawY;
75
+ /// coordinates for internal curve calculation
76
+ float[] curveCoordX;
77
+ float[] curveCoordY;
78
+ float[] curveDrawX;
79
+ float[] curveDrawY;
80
80
 
81
- int transformCount;
82
- AffineTransform transformStack[]
83
- = new AffineTransform[MATRIX_STACK_DEPTH];
84
- double[] transform = new double[6];
81
+ int transformCount;
82
+ AffineTransform transformStack[]
83
+ = new AffineTransform[MATRIX_STACK_DEPTH];
84
+ double[] transform = new double[6];
85
85
 
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();
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
- protected Color tintColorObject;
91
+ protected Color tintColorObject;
92
92
 
93
- protected Color fillColorObject;
94
- public boolean fillGradient;
95
- public Paint fillGradientObject;
93
+ protected Color fillColorObject;
94
+ public boolean fillGradient;
95
+ public Paint fillGradientObject;
96
96
 
97
- protected Stroke strokeObject;
98
- protected Color strokeColorObject;
99
- public boolean strokeGradient;
100
- public Paint strokeGradientObject;
97
+ protected Stroke strokeObject;
98
+ protected Color strokeColorObject;
99
+ public boolean strokeGradient;
100
+ public Paint strokeGradientObject;
101
101
 
102
- Font fontObject;
102
+ Font fontObject;
103
103
 
104
- //////////////////////////////////////////////////////////////
105
- // INTERNAL
106
- public PGraphicsJava2D() {
107
- }
104
+ //////////////////////////////////////////////////////////////
105
+ // INTERNAL
106
+ public PGraphicsJava2D() {
107
+ }
108
108
 
109
- //public void setParent(PApplet parent)
110
- //public void setPrimary(boolean primary)
111
- //public void setPath(String path)
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
- //public void dispose()
228
- @Override
229
- public PSurface createSurface() {
230
- return surface = new PSurfaceAWT(this);
231
- }
226
+ */
227
+ //public void dispose()
228
+ @Override
229
+ public PSurface createSurface() {
230
+ return surface = new PSurfaceAWT(this);
231
+ }
232
232
 
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
- @Override
238
- public Image getImage() {
239
- return image;
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
- * Returns the java.awt.Graphics2D object used by this renderer.
244
- */
245
- @Override
246
- public Object getNative() {
247
- return g2;
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
- // FRAME
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
- public Graphics2D checkImage() {
266
- if (image == null
267
- || ((BufferedImage) image).getWidth() != width * pixelDensity
268
- || ((BufferedImage) image).getHeight() != height * pixelDensity) {
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
- // Formerly this was broken into separate versions based on offscreen or
294
- // not, but we may as well create a compatible image; it won't hurt, right?
295
- // P.S.: Three years later, I'm happy to report it did in fact hurt [jv 2018-06-01]
296
- int wide = width * pixelDensity;
297
- int high = height * pixelDensity;
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
- // For now we expect non-premultiplied INT ARGB and the compatible image
301
- // might not be it... create the image directly. It's important that the
302
- // image has all four bands, otherwise we get garbage alpha during blending
303
- // (see https://github.com/processing/processing/pull/2645,
304
- // https://github.com/processing/processing/pull/3523)
305
- //
306
- // image = gc.createCompatibleImage(wide, high, Transparency.TRANSLUCENT);
307
- image = new BufferedImage(wide, high, BufferedImage.TYPE_INT_ARGB);
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
- @Override
313
- public void beginDraw() {
314
- g2 = checkImage();
315
-
316
- // Calling getGraphics() seems to nuke several settings.
317
- // It seems to be re-creating a new Graphics2D object each time.
318
- // https://github.com/processing/processing/issues/3331
319
- if (strokeObject != null) {
320
- g2.setStroke(strokeObject);
321
- }
322
- // https://github.com/processing/processing/issues/2617
323
- if (fontObject != null) {
324
- g2.setFont(fontObject);
325
- }
326
- // https://github.com/processing/processing/issues/4019
327
- if (blendMode != 0) {
328
- blendMode(blendMode);
329
- }
330
- handleSmooth();
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
- protected void handleSmooth() {
394
- if (smooth == 0) {
395
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
396
- RenderingHints.VALUE_ANTIALIAS_OFF);
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
- } else {
403
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
404
- RenderingHints.VALUE_ANTIALIAS_ON);
405
-
406
- if (smooth == 1 || smooth == 3) { // default is bicubic
407
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
408
- RenderingHints.VALUE_INTERPOLATION_BICUBIC);
409
- } else if (smooth == 2) {
410
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
411
- RenderingHints.VALUE_INTERPOLATION_BILINEAR);
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
- // http://docs.oracle.com/javase/tutorial/2d/text/renderinghints.html
415
- // Oracle Java text anti-aliasing on OS X looks like s*t compared to the
416
- // text rendering with Apple's old Java 6. Below, several attempts to fix:
417
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
418
- RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
419
- // Turns out this is the one that actually makes things work.
420
- // Kerning is still screwed up, however.
421
- g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
422
- RenderingHints.VALUE_FRACTIONALMETRICS_ON);
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
- @Override
434
- public void endDraw() {
435
- // hm, mark pixels as changed, because this will instantly do a full
436
- // copy of all the pixels to the surface.. so that's kind of a mess.
437
- //updatePixels();
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
- if (primaryGraphics) {
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
- } else {
470
- // TODO this is probably overkill for most tasks...
471
- loadPixels();
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
- // Marks pixels as modified so that the pixels will be updated.
481
- // Also sets mx1/y1/x2/y2 so that OpenGL will pick it up.
482
- setModified();
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
- g2.dispose();
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
- // SETTINGS
534
- //protected void checkSettings()
535
- @Override
536
- protected void defaultSettings() {
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
- defaultComposite = g2.getComposite();
550
+ defaultComposite = g2.getComposite();
547
551
  // }
548
- super.defaultSettings();
549
- }
552
+ super.defaultSettings();
553
+ }
550
554
 
551
- //protected void reapplySettings()
552
- //////////////////////////////////////////////////////////////
553
- // HINT
554
- @Override
555
- public void hint(int which) {
556
- // take care of setting the hint
557
- super.hint(which);
558
-
559
- // Avoid badness when drawing shorter strokes.
560
- // http://code.google.com/p/processing/issues/detail?id=1068
561
- // Unfortunately cannot always be enabled, because it makes the
562
- // stroke in many standard Processing examples really gross.
563
- if (which == ENABLE_STROKE_PURE) {
564
- g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
565
- RenderingHints.VALUE_STROKE_PURE);
566
- } else if (which == DISABLE_STROKE_PURE) {
567
- g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
568
- RenderingHints.VALUE_STROKE_DEFAULT);
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
- // SHAPE CREATION
574
- @Override
575
- protected PShape createShapeFamily(int type) {
576
- return new PShape(this, type);
577
- }
576
+ //////////////////////////////////////////////////////////////
577
+ // SHAPE CREATION
578
+ @Override
579
+ protected PShape createShapeFamily(int type) {
580
+ return new PShape(this, type);
581
+ }
578
582
 
579
- @Override
580
- protected PShape createShapePrimitive(int kind, float... p) {
581
- return new PShape(this, kind, p);
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
- // SHAPES
678
- @Override
679
- public void beginShape(int kind) {
680
- //super.beginShape(kind);
681
- shape = kind;
682
- vertexCount = 0;
683
- curveVertexCount = 0;
684
-
685
- // set gpath to null, because when mixing curves and straight
686
- // lines, vertexCount will be set back to zero, so vertexCount == 1
687
- // is no longer a good indicator of whether the shape is new.
688
- // this way, just check to see if gpath is null, and if it isn't
689
- // then just use it to continue the shape.
690
- gpath = null;
691
- auxPath = null;
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
- @Override
703
- public void vertex(float x, float y) {
704
- curveVertexCount = 0;
705
- //float vertex[];
706
-
707
- if (vertexCount == vertices.length) {
708
- float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT];
709
- System.arraycopy(vertices, 0, temp, 0, vertexCount);
710
- vertices = temp;
711
- //message(CHATTER, "allocating more vertices " + vertices.length);
712
- }
713
- // not everyone needs this, but just easier to store rather
714
- // than adding another moving part to the code...
715
- vertices[vertexCount][X] = x;
716
- vertices[vertexCount][Y] = y;
717
- vertexCount++;
718
-
719
- switch (shape) {
720
-
721
- case POINTS:
722
- point(x, y);
723
- break;
724
-
725
- case LINES:
726
- if ((vertexCount % 2) == 0) {
727
- line(vertices[vertexCount - 2][X],
728
- vertices[vertexCount - 2][Y], x, y);
729
- }
730
- break;
731
-
732
- case TRIANGLES:
733
- if ((vertexCount % 3) == 0) {
734
- triangle(vertices[vertexCount - 3][X],
735
- vertices[vertexCount - 3][Y],
736
- vertices[vertexCount - 2][X],
737
- vertices[vertexCount - 2][Y],
738
- x, y);
739
- }
740
- break;
741
-
742
- case TRIANGLE_STRIP:
743
- if (vertexCount >= 3) {
744
- triangle(vertices[vertexCount - 2][X],
745
- vertices[vertexCount - 2][Y],
746
- vertices[vertexCount - 1][X],
747
- vertices[vertexCount - 1][Y],
748
- vertices[vertexCount - 3][X],
749
- vertices[vertexCount - 3][Y]);
750
- }
751
- break;
752
-
753
- case TRIANGLE_FAN:
754
- if (vertexCount >= 3) {
755
- // This is an unfortunate implementation because the stroke for an
756
- // adjacent triangle will be repeated. However, if the stroke is not
757
- // redrawn, it will replace the adjacent line (when it lines up
758
- // perfectly) or show a faint line (when off by a small amount).
759
- // The alternative would be to wait, then draw the shape as a
760
- // polygon fill, followed by a series of vertices. But that's a
761
- // poor method when used with PDF, DXF, or other recording objects,
762
- // since discrete triangles would likely be preferred.
763
- triangle(vertices[0][X],
764
- vertices[0][Y],
765
- vertices[vertexCount - 2][X],
766
- vertices[vertexCount - 2][Y],
767
- x, y);
768
- }
769
- break;
770
-
771
- case QUAD:
772
- case QUADS:
773
- if ((vertexCount % 4) == 0) {
774
- quad(vertices[vertexCount - 4][X],
775
- vertices[vertexCount - 4][Y],
776
- vertices[vertexCount - 3][X],
777
- vertices[vertexCount - 3][Y],
778
- vertices[vertexCount - 2][X],
779
- vertices[vertexCount - 2][Y],
780
- x, y);
781
- }
782
- break;
783
-
784
- case QUAD_STRIP:
785
- // 0---2---4
786
- // | | |
787
- // 1---3---5
788
- if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) {
789
- quad(vertices[vertexCount - 4][X],
790
- vertices[vertexCount - 4][Y],
791
- vertices[vertexCount - 2][X],
792
- vertices[vertexCount - 2][Y],
793
- x, y,
794
- vertices[vertexCount - 3][X],
795
- vertices[vertexCount - 3][Y]);
796
- }
797
- break;
798
-
799
- case POLYGON:
800
- if (gpath == null) {
801
- gpath = new GeneralPath();
802
- gpath.moveTo(x, y);
803
- } else if (breakShape) {
804
- gpath.moveTo(x, y);
805
- breakShape = false;
806
- } else {
807
- gpath.lineTo(x, y);
808
- }
809
- break;
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
- @Override
814
- public void vertex(float x, float y, float z) {
815
- showDepthWarningXYZ("vertex");
816
- }
817
+ @Override
818
+ public void vertex(float x, float y, float z) {
819
+ showDepthWarningXYZ("vertex");
820
+ }
817
821
 
818
- @Override
819
- public void vertex(float[] v) {
820
- vertex(v[X], v[Y]);
821
- }
822
+ @Override
823
+ public void vertex(float[] v) {
824
+ vertex(v[X], v[Y]);
825
+ }
822
826
 
823
- @Override
824
- public void vertex(float x, float y, float u, float v) {
825
- showVariationWarning("vertex(x, y, u, v)");
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
- @Override
829
- public void vertex(float x, float y, float z, float u, float v) {
830
- showDepthWarningXYZ("vertex");
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
- @Override
834
- public void beginContour() {
835
- if (openContour) {
836
- PGraphics.showWarning("Already called beginContour()");
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
- // draw contours to auxiliary path so main path can be closed later
841
- GeneralPath contourPath = auxPath;
842
- auxPath = gpath;
843
- gpath = contourPath;
849
+ if (contourPath != null) { // first contour does not break
850
+ breakShape = true;
851
+ }
844
852
 
845
- if (contourPath != null) { // first contour does not break
846
- breakShape = true;
847
- }
853
+ openContour = true;
854
+ }
848
855
 
849
- openContour = true;
856
+ @Override
857
+ public void endContour() {
858
+ if (!openContour) {
859
+ PGraphics.showWarning("Need to call beginContour() first");
860
+ return;
850
861
  }
851
862
 
852
- @Override
853
- public void endContour() {
854
- if (!openContour) {
855
- PGraphics.showWarning("Need to call beginContour() first");
856
- return;
857
- }
863
+ // close this contour
864
+ if (gpath != null) {
865
+ gpath.closePath();
866
+ }
858
867
 
859
- // close this contour
860
- if (gpath != null) {
861
- gpath.closePath();
862
- }
868
+ // switch back to main path
869
+ GeneralPath contourPath = gpath;
870
+ gpath = auxPath;
871
+ auxPath = contourPath;
863
872
 
864
- // switch back to main path
865
- GeneralPath contourPath = gpath;
866
- gpath = auxPath;
867
- auxPath = contourPath;
873
+ openContour = false;
874
+ }
868
875
 
869
- openContour = false;
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
- @Override
873
- public void endShape(int mode) {
874
- if (openContour) { // correct automagically, notify user
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 (gpath != null) { // make sure something has been drawn
879
- if (shape == POLYGON) {
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
- shape = 0;
890
+ drawShape(gpath);
891
+ }
890
892
  }
893
+ shape = 0;
894
+ }
891
895
 
892
- //////////////////////////////////////////////////////////////
893
- // CLIPPING
894
- @Override
895
- protected void clipImpl(float x1, float y1, float x2, float y2) {
896
- g2.setClip(new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
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
- @Override
900
- public void noClip() {
901
- g2.setClip(null);
902
- }
903
+ @Override
904
+ public void noClip() {
905
+ g2.setClip(null);
906
+ }
903
907
 
904
- //////////////////////////////////////////////////////////////
905
- // BLEND
906
- /**
907
- * ( begin auto-generated from blendMode.xml )
908
- *
909
- * This is a new reference entry for Processing 2.0. It will be updated
910
- * shortly.
911
- *
912
- * ( end auto-generated )
913
- *
914
- * @webref Rendering
915
- * @param mode the blending mode to use
916
- */
917
- @Override
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
- } else {
923
- g2.setComposite(new Composite() {
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
- // Blending implementation cribbed from portions of Romain Guy's
936
- // demo and terrific writeup on blending modes in Java 2D.
937
- // http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
938
- private static final class BlendingContext implements CompositeContext {
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
- private int mode;
933
+ private final int mode;
941
934
 
942
- private BlendingContext(int mode) {
943
- this.mode = mode;
944
- }
935
+ private BlendingContext(int mode) {
936
+ this.mode = mode;
937
+ }
945
938
 
946
- public void dispose() {
947
- }
939
+ @Override
940
+ public void dispose() {
941
+ }
948
942
 
949
- public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
950
- // not sure if this is really necessary, since we control our buffers
951
- if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT
952
- || dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT
953
- || dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
954
- throw new IllegalStateException("Source and destination must store pixels as INT.");
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
- int width = Math.min(src.getWidth(), dstIn.getWidth());
958
- int height = Math.min(src.getHeight(), dstIn.getHeight());
952
+ int width = Math.min(src.getWidth(), dstIn.getWidth());
953
+ int height = Math.min(src.getHeight(), dstIn.getHeight());
959
954
 
960
- int[] srcPixels = new int[width];
961
- int[] dstPixels = new int[width];
955
+ int[] srcPixels = new int[width];
956
+ int[] dstPixels = new int[width];
962
957
 
963
- for (int y = 0; y < height; y++) {
964
- src.getDataElements(0, y, width, 1, srcPixels);
965
- dstIn.getDataElements(0, y, width, 1, dstPixels);
966
- for (int x = 0; x < width; x++) {
967
- dstPixels[x] = blendColor(dstPixels[x], srcPixels[x], mode);
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
- // BEZIER VERTICES
976
- @Override
977
- public void bezierVertex(float x1, float y1,
978
- float x2, float y2,
979
- float x3, float y3) {
980
- bezierVertexCheck();
981
- gpath.curveTo(x1, y1, x2, y2, x3, y3);
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
- @Override
985
- public void bezierVertex(float x2, float y2, float z2,
986
- float x3, float y3, float z3,
987
- float x4, float y4, float z4) {
988
- showDepthWarningXYZ("bezierVertex");
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
- // QUADRATIC BEZIER VERTICES
993
- @Override
994
- public void quadraticVertex(float ctrlX, float ctrlY,
995
- float endX, float endY) {
996
- bezierVertexCheck();
997
- Point2D cur = gpath.getCurrentPoint();
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
- float x1 = (float) cur.getX();
1000
- float y1 = (float) cur.getY();
994
+ float x1 = (float) cur.getX();
995
+ float y1 = (float) cur.getY();
1001
996
 
1002
- bezierVertex(x1 + ((ctrlX - x1) * 2 / 3.0f), y1 + ((ctrlY - y1) * 2 / 3.0f),
1003
- endX + ((ctrlX - endX) * 2 / 3.0f), endY + ((ctrlY - endY) * 2 / 3.0f),
1004
- endX, endY);
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
- @Override
1008
- public void quadraticVertex(float x2, float y2, float z2,
1009
- float x4, float y4, float z4) {
1010
- showDepthWarningXYZ("quadVertex");
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
- // CURVE VERTICES
1015
- @Override
1016
- protected void curveVertexCheck() {
1017
- super.curveVertexCheck();
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
- @Override
1028
- protected void curveVertexSegment(float x1, float y1,
1029
- float x2, float y2,
1030
- float x3, float y3,
1031
- float x4, float y4) {
1032
- curveCoordX[0] = x1;
1033
- curveCoordY[0] = y1;
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
- curveCoordX[1] = x2;
1036
- curveCoordY[1] = y2;
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
- curveCoordX[2] = x3;
1039
- curveCoordY[2] = y3;
1030
+ curveCoordX[1] = x2;
1031
+ curveCoordY[1] = y2;
1040
1032
 
1041
- curveCoordX[3] = x4;
1042
- curveCoordY[3] = y4;
1033
+ curveCoordX[2] = x3;
1034
+ curveCoordY[2] = y3;
1043
1035
 
1044
- curveToBezierMatrix.mult(curveCoordX, curveDrawX);
1045
- curveToBezierMatrix.mult(curveCoordY, curveDrawY);
1036
+ curveCoordX[3] = x4;
1037
+ curveCoordY[3] = y4;
1046
1038
 
1047
- // since the paths are continuous,
1048
- // only the first point needs the actual moveto
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
- gpath.curveTo(curveDrawX[1], curveDrawY[1],
1055
- curveDrawX[2], curveDrawY[2],
1056
- curveDrawX[3], curveDrawY[3]);
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
- @Override
1060
- public void curveVertex(float x, float y, float z) {
1061
- showDepthWarningXYZ("curveVertex");
1062
- }
1049
+ gpath.curveTo(curveDrawX[1], curveDrawY[1],
1050
+ curveDrawX[2], curveDrawY[2],
1051
+ curveDrawX[3], curveDrawY[3]);
1052
+ }
1063
1053
 
1064
- //////////////////////////////////////////////////////////////
1065
- // RENDERER
1066
- //public void flush()
1067
- //////////////////////////////////////////////////////////////
1068
- // POINT, LINE, TRIANGLE, QUAD
1069
- @Override
1070
- public void point(float x, float y) {
1071
- if (stroke) {
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
- line(x, y, x + EPSILON, y + EPSILON);
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
- @Override
1081
- public void line(float x1, float y1, float x2, float y2) {
1082
- line.setLine(x1, y1, x2, y2);
1083
- strokeShape(line);
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
- @Override
1087
- public void triangle(float x1, float y1, float x2, float y2,
1088
- float x3, float y3) {
1089
- gpath = new GeneralPath();
1090
- gpath.moveTo(x1, y1);
1091
- gpath.lineTo(x2, y2);
1092
- gpath.lineTo(x3, y3);
1093
- gpath.closePath();
1094
- drawShape(gpath);
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
- @Override
1098
- public void quad(float x1, float y1, float x2, float y2,
1099
- float x3, float y3, float x4, float y4) {
1100
- GeneralPath gp = new GeneralPath();
1101
- gp.moveTo(x1, y1);
1102
- gp.lineTo(x2, y2);
1103
- gp.lineTo(x3, y3);
1104
- gp.lineTo(x4, y4);
1105
- gp.closePath();
1106
- drawShape(gp);
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
- // ELLIPSE
1121
- //public void ellipseMode(int mode)
1122
- //public void ellipse(float a, float b, float c, float d)
1123
- @Override
1124
- protected void ellipseImpl(float x, float y, float w, float h) {
1125
- ellipse.setFrame(x, y, w, h);
1126
- drawShape(ellipse);
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
- // ARC
1131
- //public void arc(float a, float b, float c, float d,
1132
- // float start, float stop)
1133
- @Override
1134
- protected void arcImpl(float x, float y, float w, float h,
1135
- float start, float stop, int mode) {
1136
- // 0 to 90 in java would be 0 to -90 for p5 renderer
1137
- // but that won't work, so -90 to 0?
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
- start = -start * RAD_TO_DEG;
1140
- stop = -stop * RAD_TO_DEG;
1134
+ start = -start * RAD_TO_DEG;
1135
+ stop = -stop * RAD_TO_DEG;
1141
1136
 
1142
- // ok to do this because already checked for NaN
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
- float sweep = stop - start;
1153
-
1154
- // The defaults, before 2.0b7, were to stroke as Arc2D.OPEN, and then fill
1155
- // using Arc2D.PIE. That's a little wonky, but it's here for compatability.
1156
- int fillMode = Arc2D.PIE;
1157
- int strokeMode = Arc2D.OPEN;
1158
-
1159
- if (mode == OPEN) {
1160
- fillMode = Arc2D.OPEN;
1161
- //strokeMode = Arc2D.OPEN;
1162
-
1163
- } else if (mode == PIE) {
1164
- //fillMode = Arc2D.PIE;
1165
- strokeMode = Arc2D.PIE;
1166
-
1167
- } else if (mode == CHORD) {
1168
- fillMode = Arc2D.CHORD;
1169
- strokeMode = Arc2D.CHORD;
1170
- }
1171
-
1172
- if (fill) {
1173
- //System.out.println("filla");
1174
- arc.setArc(x, y, w, h, start, sweep, fillMode);
1175
- fillShape(arc);
1176
- }
1177
- if (stroke) {
1178
- //System.out.println("strokey");
1179
- arc.setArc(x, y, w, h, start, sweep, strokeMode);
1180
- strokeShape(arc);
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
- // JAVA2D SHAPE/PATH HANDLING
1186
- protected void fillShape(Shape s) {
1187
- if (fillGradient) {
1188
- g2.setPaint(fillGradientObject);
1189
- g2.fill(s);
1190
- } else if (fill) {
1191
- g2.setColor(fillColorObject);
1192
- g2.fill(s);
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
- protected void strokeShape(Shape s) {
1197
- if (strokeGradient) {
1198
- g2.setPaint(strokeGradientObject);
1199
- g2.draw(s);
1200
- } else if (stroke) {
1201
- g2.setColor(strokeColorObject);
1202
- g2.draw(s);
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
- protected void drawShape(Shape s) {
1207
- if (fillGradient) {
1208
- g2.setPaint(fillGradientObject);
1209
- g2.fill(s);
1210
- } else if (fill) {
1211
- g2.setColor(fillColorObject);
1212
- g2.fill(s);
1213
- }
1214
- if (strokeGradient) {
1215
- g2.setPaint(strokeGradientObject);
1216
- g2.draw(s);
1217
- } else if (stroke) {
1218
- g2.setColor(strokeColorObject);
1219
- g2.draw(s);
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
- // BOX
1225
- //public void box(float size)
1226
- @Override
1227
- public void box(float w, float h, float d) {
1228
- showMethodWarning("box");
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
- // SPHERE
1233
- //public void sphereDetail(int res)
1234
- //public void sphereDetail(int ures, int vres)
1235
- @Override
1236
- public void sphere(float r) {
1237
- showMethodWarning("sphere");
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
- // BEZIER
1242
- //public float bezierPoint(float a, float b, float c, float d, float t)
1243
- //public float bezierTangent(float a, float b, float c, float d, float t)
1244
- //protected void bezierInitCheck()
1245
- //protected void bezierInit()
1246
- /**
1247
- * Ignored (not needed) in Java 2D.
1248
- */
1249
- @Override
1250
- public void bezierDetail(int detail) {
1251
- }
1252
-
1253
- //public void bezier(float x1, float y1,
1254
- // float x2, float y2,
1255
- // float x3, float y3,
1256
- // float x4, float y4)
1257
- //public void bezier(float x1, float y1, float z1,
1258
- // float x2, float y2, float z2,
1259
- // float x3, float y3, float z3,
1260
- // float x4, float y4, float z4)
1261
- //////////////////////////////////////////////////////////////
1262
- // CURVE
1263
- //public float curvePoint(float a, float b, float c, float d, float t)
1264
- //public float curveTangent(float a, float b, float c, float d, float t)
1265
- /**
1266
- * Ignored (not needed) in Java 2D.
1267
- */
1268
- @Override
1269
- public void curveDetail(int detail) {
1270
- }
1271
-
1272
- //public void curveTightness(float tightness)
1273
- //protected void curveInitCheck()
1274
- //protected void curveInit()
1275
- //public void curve(float x1, float y1,
1276
- // float x2, float y2,
1277
- // float x3, float y3,
1278
- // float x4, float y4)
1279
- //public void curve(float x1, float y1, float z1,
1280
- // float x2, float y2, float z2,
1281
- // float x3, float y3, float z3,
1282
- // float x4, float y4, float z4)
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
- // IMAGE
1348
- //public void imageMode(int mode)
1349
- //public void image(PImage image, float x, float y)
1350
- //public void image(PImage image, float x, float y, float c, float d)
1351
- //public void image(PImage image,
1352
- // float a, float b, float c, float d,
1353
- // int u1, int v1, int u2, int v2)
1354
- /**
1355
- * Handle renderer-specific image drawing.
1356
- */
1357
- @Override
1358
- protected void imageImpl(PImage who,
1359
- float x1, float y1, float x2, float y2,
1360
- int u1, int v1, int u2, int v2) {
1361
- // Image not ready yet, or an error
1362
- if (who.width <= 0 || who.height <= 0) {
1363
- return;
1364
- }
1365
-
1366
- ImageCache cash = (ImageCache) getCache(who);
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
- // Nuke the cache if the image was resized
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
- if (cash == null) {
1377
- //System.out.println("making new image cache");
1378
- cash = new ImageCache(); //who);
1379
- setCache(who, cash);
1380
- who.updatePixels(); // mark the whole thing for update
1381
- who.setModified();
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
- // If image previously was tinted, or the color changed
1385
- // or the image was tinted, and tint is now disabled
1386
- if ((tint && !cash.tinted)
1387
- || (tint && (cash.tintedColor != tintColor))
1388
- || (!tint && cash.tinted)) {
1389
- // For tint change, mark all pixels as needing update.
1390
- who.updatePixels();
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
- if (who.isModified()) {
1394
- if (who.pixels == null) {
1395
- // This might be a PGraphics that hasn't been drawn to yet.
1396
- // Can't just bail because the cache has been created above.
1397
- // https://github.com/processing/processing/issues/2208
1398
- who.pixels = new int[who.pixelWidth * who.pixelHeight];
1399
- }
1400
- cash.update(who, tint, tintColor);
1401
- who.setModified(false);
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
- u1 *= who.pixelDensity;
1405
- v1 *= who.pixelDensity;
1406
- u2 *= who.pixelDensity;
1407
- v2 *= who.pixelDensity;
1405
+ u1 *= who.pixelDensity;
1406
+ v1 *= who.pixelDensity;
1407
+ u2 *= who.pixelDensity;
1408
+ v2 *= who.pixelDensity;
1408
1409
 
1409
- g2.drawImage(((ImageCache) getCache(who)).image,
1410
- (int) x1, (int) y1, (int) x2, (int) y2,
1411
- u1, v1, u2, v2, null);
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
- // Every few years I think "nah, Java2D couldn't possibly be that f*king
1414
- // slow, why are we doing this by hand?" then comes the affirmation:
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
- static class ImageCache {
1437
+ static class ImageCache {
1437
1438
 
1438
- boolean tinted;
1439
- int tintedColor;
1440
- int[] tintedTemp; // one row of tinted pixels
1441
- BufferedImage image;
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
- * Update the pixels of the cache image. Already determined that the
1454
- * tint has changed, or the pixels have changed, so should just go
1455
- * through with the update without further checks.
1456
- */
1457
- public void update(PImage source, boolean tint, int tintColor) {
1458
- //int bufferType = BufferedImage.TYPE_INT_ARGB;
1459
- int targetType = ARGB;
1460
- boolean opaque = (tintColor & 0xFF000000) == 0xFF000000;
1461
- if (source.format == RGB) {
1462
- if (!tint || (tint && opaque)) {
1463
- //bufferType = BufferedImage.TYPE_INT_RGB;
1464
- targetType = RGB;
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
- // Must always use an ARGB image, otherwise will write zeros
1472
- // in the alpha channel when drawn to the screen.
1473
- // https://github.com/processing/processing/issues/2030
1474
- if (image == null) {
1475
- image = new BufferedImage(source.pixelWidth, source.pixelHeight,
1476
- BufferedImage.TYPE_INT_ARGB);
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
- WritableRaster wr = image.getRaster();
1480
- if (tint) {
1481
- if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
1482
- tintedTemp = new int[source.pixelWidth];
1483
- }
1484
- int a2 = (tintColor >> 24) & 0xff;
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
- int r2 = (tintColor >> 16) & 0xff;
1488
- int g2 = (tintColor >> 8) & 0xff;
1489
- int b2 = (tintColor) & 0xff;
1490
-
1491
- //if (bufferType == BufferedImage.TYPE_INT_RGB) {
1492
- if (targetType == RGB) {
1493
- // The target image is opaque, meaning that the source image has no
1494
- // alpha (is not ARGB), and the tint has no alpha.
1495
- int index = 0;
1496
- for (int y = 0; y < source.pixelHeight; y++) {
1497
- for (int x = 0; x < source.pixelWidth; x++) {
1498
- int argb1 = source.pixels[index++];
1499
- int r1 = (argb1 >> 16) & 0xff;
1500
- int g1 = (argb1 >> 8) & 0xff;
1501
- int b1 = (argb1) & 0xff;
1502
-
1503
- // Prior to 2.1, the alpha channel was commented out here,
1504
- // but can't remember why (just thought unnecessary b/c of RGB?)
1505
- // https://github.com/processing/processing/issues/2030
1506
- tintedTemp[x] = 0xFF000000
1507
- | (((r2 * r1) & 0xff00) << 8)
1508
- | ((g2 * g1) & 0xff00)
1509
- | (((b2 * b1) & 0xff00) >> 8);
1510
- }
1511
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1512
- }
1513
- // could this be any slower?
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
- //} else if (bufferType == BufferedImage.TYPE_INT_ARGB) {
1520
- } else if (targetType == ARGB) {
1521
- if (source.format == RGB
1522
- && (tintColor & 0xffffff) == 0xffffff) {
1523
- int hi = tintColor & 0xff000000;
1524
- int index = 0;
1525
- for (int y = 0; y < source.pixelHeight; y++) {
1526
- for (int x = 0; x < source.pixelWidth; x++) {
1527
- tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
1528
- }
1529
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1530
- }
1531
- } else {
1532
- int index = 0;
1533
- for (int y = 0; y < source.pixelHeight; y++) {
1534
- if (source.format == RGB) {
1535
- int alpha = tintColor & 0xFF000000;
1536
- for (int x = 0; x < source.pixelWidth; x++) {
1537
- int argb1 = source.pixels[index++];
1538
- int r1 = (argb1 >> 16) & 0xff;
1539
- int g1 = (argb1 >> 8) & 0xff;
1540
- int b1 = (argb1) & 0xff;
1541
- tintedTemp[x] = alpha
1542
- | (((r2 * r1) & 0xff00) << 8)
1543
- | ((g2 * g1) & 0xff00)
1544
- | (((b2 * b1) & 0xff00) >> 8);
1545
- }
1546
- } else if (source.format == ARGB) {
1547
- for (int x = 0; x < source.pixelWidth; x++) {
1548
- int argb1 = source.pixels[index++];
1549
- int a1 = (argb1 >> 24) & 0xff;
1550
- int r1 = (argb1 >> 16) & 0xff;
1551
- int g1 = (argb1 >> 8) & 0xff;
1552
- int b1 = (argb1) & 0xff;
1553
- tintedTemp[x]
1554
- = (((a2 * a1) & 0xff00) << 16)
1555
- | (((r2 * r1) & 0xff00) << 8)
1556
- | ((g2 * g1) & 0xff00)
1557
- | (((b2 * b1) & 0xff00) >> 8);
1558
- }
1559
- } else if (source.format == ALPHA) {
1560
- int lower = tintColor & 0xFFFFFF;
1561
- for (int x = 0; x < source.pixelWidth; x++) {
1562
- int a1 = source.pixels[index++];
1563
- tintedTemp[x]
1564
- = (((a2 * a1) & 0xff00) << 16) | lower;
1565
- }
1566
- }
1567
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1568
- }
1569
- }
1570
- // Not sure why ARGB images take the scales in this order...
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
- } else { // !tint
1577
- if (targetType == RGB && (source.pixels[0] >> 24 == 0)) {
1578
- // If it's an RGB image and the high bits aren't set, need to set
1579
- // the high bits to opaque because we're drawing ARGB images.
1580
- source.filter(OPAQUE);
1581
- // Opting to just manipulate the image here, since it shouldn't
1582
- // affect anything else (and alpha(get(x, y)) should return 0xff).
1583
- // Wel also make no guarantees about the values of the pixels array
1584
- // in a PImage and how the high bits will be set.
1585
- }
1586
- // If no tint, just shove the pixels on in there verbatim
1587
- wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels);
1588
- }
1589
- this.tinted = tint;
1590
- this.tintedColor = tintColor;
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
- // SHAPE
1605
- //public void shapeMode(int mode)
1606
- //public void shape(PShape shape)
1607
- //public void shape(PShape shape, float x, float y)
1608
- //public void shape(PShape shape, float x, float y, float c, float d)
1609
- //////////////////////////////////////////////////////////////
1610
- // SHAPE I/O
1611
- //public PShape loadShape(String filename)
1612
- @Override
1613
- public PShape loadShape(String filename, String options) {
1614
- String extension = PApplet.getExtension(filename);
1615
- if (extension.equals("svg") || extension.equals("svgz")) {
1616
- return new PShapeJava2D(parent.loadXML(filename));
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
- // TEXT ATTRIBTUES
1624
- //public void textAlign(int align)
1625
- //public void textAlign(int alignX, int alignY)
1626
- @Override
1627
- public float textAscent() {
1628
- if (textFont == null) {
1629
- defaultFontOrDeath("textAscent");
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
- @Override
1641
- public float textDescent() {
1642
- if (textFont == null) {
1643
- defaultFontOrDeath("textDescent");
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
- //public void textFont(PFont which)
1654
- //public void textFont(PFont which, float size)
1655
- //public void textLeading(float leading)
1656
- //public void textMode(int mode)
1657
- @Override
1658
- protected boolean textModeCheck(int mode) {
1659
- return mode == MODEL;
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
- * Same as parent, but override for native version of the font.
1664
- * <p/>
1665
- * Called from textFontImpl and textSizeImpl, so the metrics will get
1666
- * recorded properly.
1667
- */
1668
- @Override
1669
- protected void handleTextSize(float size) {
1670
- // if a native version available, derive this font
1671
- Font font = (Font) textFont.getNative();
1672
- // don't derive again if the font size has not changed
1673
- if (font != null) {
1674
- if (font.getSize2D() != size) {
1675
- Map<TextAttribute, Object> map
1676
- = new HashMap<>();
1677
- map.put(TextAttribute.SIZE, size);
1678
- map.put(TextAttribute.KERNING,
1679
- TextAttribute.KERNING_ON);
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
- font = font.deriveFont(map);
1683
- }
1684
- g2.setFont(font);
1685
- textFont.setNative(font);
1686
- fontObject = font;
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
- //public float textWidth(char c)
1703
- //public float textWidth(String str)
1704
- @Override
1705
- protected float textWidthImpl(char buffer[], int start, int stop) {
1706
- if (textFont == null) {
1707
- defaultFontOrDeath("textWidth");
1708
- }
1709
- // Avoid "Zero length string passed to TextLayout constructor" error
1710
- if (start == stop) {
1711
- return 0;
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
- Font font = (Font) textFont.getNative();
1721
+ Font font = (Font) textFont.getNative();
1715
1722
  // System.out.println(font);
1716
- //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
1717
- if (font != null) {
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
- // maybe should use one of the newer/fancier functions for this?
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
- FontMetrics metrics = g2.getFontMetrics(font);
1723
- // Using fractional metrics makes the measurement worse, not better,
1724
- // at least on OS X 10.6 (November, 2010).
1725
- // TextLayout returns the same value as charsWidth().
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
- return (float) metrics.getStringBounds(buffer, start, stop, g2).getWidth();
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
- // TEXT
1752
- // None of the variations of text() are overridden from PGraphics.
1753
- //////////////////////////////////////////////////////////////
1754
- // TEXT IMPL
1755
- //protected void textLineAlignImpl(char buffer[], int start, int stop,
1756
- // float x, float y)
1757
- @Override
1758
- protected void textLineImpl(char buffer[], int start, int stop,
1759
- float x, float y) {
1760
- Font font = (Font) textFont.getNative();
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
- if (font != null) {
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
- Object antialias
1779
- = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
1780
- if (antialias == null) {
1781
- // if smooth() and noSmooth() not called, this will be null (0120)
1782
- antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT;
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
- // override the current smoothing setting based on the font
1786
- // also changes global setting for antialiasing, but this is because it's
1787
- // not possible to enable/disable them independently in some situations.
1788
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1789
- textFont.isSmooth()
1790
- ? RenderingHints.VALUE_ANTIALIAS_ON
1791
- : RenderingHints.VALUE_ANTIALIAS_OFF);
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
- g2.setColor(fillColorObject);
1800
+ g2.setColor(fillColorObject);
1794
1801
 
1795
- int length = stop - start;
1796
- if (length != 0) {
1797
- g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f));
1798
- // better to use round here? also, drawChars now just calls drawString
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
- // better to use drawString() with floats? (nope, draws the same)
1802
- //g2.drawString(new String(buffer, start, length), x, y);
1803
- // this didn't seem to help the scaling issue, and creates garbage
1804
- // because of a fairly heavyweight new temporary object
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
- // return to previous smoothing state if it was changed
1811
- //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias);
1812
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias);
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
- } else { // otherwise just do the default
1815
- super.textLineImpl(buffer, start, stop, x, y);
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
- // MATRIX STACK
1861
- @Override
1862
- public void pushMatrix() {
1863
- if (transformCount == transformStack.length) {
1864
- throw new RuntimeException("pushMatrix() cannot use push more than "
1865
- + transformStack.length + " times");
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
- @Override
1872
- public void popMatrix() {
1873
- if (transformCount == 0) {
1874
- throw new RuntimeException("missing a pushMatrix() "
1875
- + "to go with that popMatrix()");
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
- // MATRIX TRANSFORMS
1883
- @Override
1884
- public void translate(float tx, float ty) {
1885
- g2.translate(tx, ty);
1886
- }
1888
+ //////////////////////////////////////////////////////////////
1889
+ // MATRIX TRANSFORMS
1890
+ @Override
1891
+ public void translate(float tx, float ty) {
1892
+ g2.translate(tx, ty);
1893
+ }
1887
1894
 
1888
- //public void translate(float tx, float ty, float tz)
1889
- @Override
1890
- public void rotate(float angle) {
1891
- g2.rotate(angle);
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
- @Override
1895
- public void rotateX(float angle) {
1896
- showDepthWarning("rotateX");
1897
- }
1901
+ @Override
1902
+ public void rotateX(float angle) {
1903
+ showDepthWarning("rotateX");
1904
+ }
1898
1905
 
1899
- @Override
1900
- public void rotateY(float angle) {
1901
- showDepthWarning("rotateY");
1902
- }
1906
+ @Override
1907
+ public void rotateY(float angle) {
1908
+ showDepthWarning("rotateY");
1909
+ }
1903
1910
 
1904
- @Override
1905
- public void rotateZ(float angle) {
1906
- showDepthWarning("rotateZ");
1907
- }
1911
+ @Override
1912
+ public void rotateZ(float angle) {
1913
+ showDepthWarning("rotateZ");
1914
+ }
1908
1915
 
1909
- @Override
1910
- public void rotate(float angle, float vx, float vy, float vz) {
1911
- showVariationWarning("rotate");
1912
- }
1916
+ @Override
1917
+ public void rotate(float angle, float vx, float vy, float vz) {
1918
+ showVariationWarning("rotate");
1919
+ }
1913
1920
 
1914
- @Override
1915
- public void scale(float s) {
1916
- g2.scale(s, s);
1917
- }
1921
+ @Override
1922
+ public void scale(float s) {
1923
+ g2.scale(s, s);
1924
+ }
1918
1925
 
1919
- @Override
1920
- public void scale(float sx, float sy) {
1921
- g2.scale(sx, sy);
1922
- }
1926
+ @Override
1927
+ public void scale(float sx, float sy) {
1928
+ g2.scale(sx, sy);
1929
+ }
1923
1930
 
1924
- @Override
1925
- public void scale(float sx, float sy, float sz) {
1926
- showDepthWarningXYZ("scale");
1927
- }
1931
+ @Override
1932
+ public void scale(float sx, float sy, float sz) {
1933
+ showDepthWarningXYZ("scale");
1934
+ }
1928
1935
 
1929
- @Override
1930
- public void shearX(float angle) {
1931
- g2.shear(Math.tan(angle), 0);
1932
- }
1936
+ @Override
1937
+ public void shearX(float angle) {
1938
+ g2.shear(Math.tan(angle), 0);
1939
+ }
1933
1940
 
1934
- @Override
1935
- public void shearY(float angle) {
1936
- g2.shear(0, Math.tan(angle));
1937
- }
1941
+ @Override
1942
+ public void shearY(float angle) {
1943
+ g2.shear(0, Math.tan(angle));
1944
+ }
1938
1945
 
1939
- //////////////////////////////////////////////////////////////
1940
- // MATRIX MORE
1941
- @Override
1942
- public void resetMatrix() {
1943
- g2.setTransform(new AffineTransform());
1944
- g2.scale(pixelDensity, pixelDensity);
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
- //public void applyMatrix(PMatrix2D source)
1948
- @Override
1949
- public void applyMatrix(float n00, float n01, float n02,
1950
- float n10, float n11, float n12) {
1951
- //System.out.println("PGraphicsJava2D.applyMatrix()");
1952
- //System.out.println(new AffineTransform(n00, n10, n01, n11, n02, n12));
1953
- g2.transform(new AffineTransform(n00, n10, n01, n11, n02, n12));
1954
- //g2.transform(new AffineTransform(n00, n01, n02, n10, n11, n12));
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
- //public void applyMatrix(PMatrix3D source)
1958
- @Override
1959
- public void applyMatrix(float n00, float n01, float n02, float n03,
1960
- float n10, float n11, float n12, float n13,
1961
- float n20, float n21, float n22, float n23,
1962
- float n30, float n31, float n32, float n33) {
1963
- showVariationWarning("applyMatrix");
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
- // MATRIX GET/SET
1968
- @Override
1969
- public PMatrix getMatrix() {
1970
- return getMatrix((PMatrix2D) null);
1971
- }
1973
+ //////////////////////////////////////////////////////////////
1974
+ // MATRIX GET/SET
1975
+ @Override
1976
+ public PMatrix getMatrix() {
1977
+ return getMatrix((PMatrix2D) null);
1978
+ }
1972
1979
 
1973
- @Override
1974
- public PMatrix2D getMatrix(PMatrix2D target) {
1975
- if (target == null) {
1976
- target = new PMatrix2D();
1977
- }
1978
- g2.getTransform().getMatrix(transform);
1979
- target.set((float) transform[0], (float) transform[2], (float) transform[4],
1980
- (float) transform[1], (float) transform[3], (float) transform[5]);
1981
- return target;
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
- @Override
1985
- public PMatrix3D getMatrix(PMatrix3D target) {
1986
- showVariationWarning("getMatrix");
1987
- return target;
1988
- }
1991
+ @Override
1992
+ public PMatrix3D getMatrix(PMatrix3D target) {
1993
+ showVariationWarning("getMatrix");
1994
+ return target;
1995
+ }
1989
1996
 
1990
- //public void setMatrix(PMatrix source)
1991
- @Override
1992
- public void setMatrix(PMatrix2D source) {
1993
- g2.setTransform(new AffineTransform(source.m00, source.m10,
1994
- source.m01, source.m11,
1995
- source.m02, source.m12));
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
- @Override
1999
- public void setMatrix(PMatrix3D source) {
2000
- showVariationWarning("setMatrix");
2001
- }
2005
+ @Override
2006
+ public void setMatrix(PMatrix3D source) {
2007
+ showVariationWarning("setMatrix");
2008
+ }
2002
2009
 
2003
- @Override
2004
- public void printMatrix() {
2005
- getMatrix((PMatrix2D) null).print();
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
- @Override
2037
- public float screenY(float x, float y) {
2038
- g2.getTransform().getMatrix(transform);
2039
- return (float) transform[1] * x + (float) transform[3] * y + (float) transform[5];
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
- @Override
2043
- public float screenX(float x, float y, float z) {
2044
- showDepthWarningXYZ("screenX");
2045
- return 0;
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
- @Override
2049
- public float screenY(float x, float y, float z) {
2050
- showDepthWarningXYZ("screenY");
2051
- return 0;
2052
- }
2049
+ @Override
2050
+ public float screenX(float x, float y, float z) {
2051
+ showDepthWarningXYZ("screenX");
2052
+ return 0;
2053
+ }
2053
2054
 
2054
- @Override
2055
- public float screenZ(float x, float y, float z) {
2056
- showDepthWarningXYZ("screenZ");
2057
- return 0;
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
- @Override
2075
- public void strokeJoin(int join) {
2076
- super.strokeJoin(join);
2077
- strokeImpl();
2078
- }
2061
+ @Override
2062
+ public float screenZ(float x, float y, float z) {
2063
+ showDepthWarningXYZ("screenZ");
2064
+ return 0;
2065
+ }
2079
2066
 
2080
- @Override
2081
- public void strokeWeight(float weight) {
2082
- super.strokeWeight(weight);
2083
- strokeImpl();
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
- protected void strokeImpl() {
2087
- int cap = BasicStroke.CAP_BUTT;
2088
- if (strokeCap == ROUND) {
2089
- cap = BasicStroke.CAP_ROUND;
2090
- } else if (strokeCap == PROJECT) {
2091
- cap = BasicStroke.CAP_SQUARE;
2092
- }
2081
+ @Override
2082
+ public void strokeJoin(int join) {
2083
+ super.strokeJoin(join);
2084
+ strokeImpl();
2085
+ }
2093
2086
 
2094
- int join = BasicStroke.JOIN_BEVEL;
2095
- if (strokeJoin == MITER) {
2096
- join = BasicStroke.JOIN_MITER;
2097
- } else if (strokeJoin == ROUND) {
2098
- join = BasicStroke.JOIN_ROUND;
2099
- }
2087
+ @Override
2088
+ public void strokeWeight(float weight) {
2089
+ super.strokeWeight(weight);
2090
+ strokeImpl();
2091
+ }
2100
2092
 
2101
- strokeObject = new BasicStroke(strokeWeight, cap, join);
2102
- g2.setStroke(strokeObject);
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
- // STROKE
2107
- // noStroke() and stroke() inherited from PGraphics.
2108
- @Override
2109
- protected void strokeFromCalc() {
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
- // TINT
2117
- // noTint() and tint() inherited from PGraphics.
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
- // FILL
2127
- // noFill() and fill() inherited from PGraphics.
2128
- @Override
2129
- protected void fillFromCalc() {
2130
- super.fillFromCalc();
2131
- fillColorObject = new Color(fillColor, true);
2132
- fillGradient = false;
2133
- }
2134
-
2135
- //////////////////////////////////////////////////////////////
2136
- // MATERIAL PROPERTIES
2137
- //public void ambient(int rgb)
2138
- //public void ambient(float gray)
2139
- //public void ambient(float x, float y, float z)
2140
- //protected void ambientFromCalc()
2141
- //public void specular(int rgb)
2142
- //public void specular(float gray)
2143
- //public void specular(float x, float y, float z)
2144
- //protected void specularFromCalc()
2145
- //public void shininess(float shine)
2146
- //public void emissive(int rgb)
2147
- //public void emissive(float gray)
2148
- //public void emissive(float x, float y, float z )
2149
- //protected void emissiveFromCalc()
2150
- //////////////////////////////////////////////////////////////
2151
- // LIGHTS
2152
- //public void lights()
2153
- //public void noLights()
2154
- //public void ambientLight(float red, float green, float blue)
2155
- //public void ambientLight(float red, float green, float blue,
2156
- // float x, float y, float z)
2157
- //public void directionalLight(float red, float green, float blue,
2158
- // float nx, float ny, float nz)
2159
- //public void pointLight(float red, float green, float blue,
2160
- // float x, float y, float z)
2161
- //public void spotLight(float red, float green, float blue,
2162
- // float x, float y, float z,
2163
- // float nx, float ny, float nz,
2164
- // float angle, float concentration)
2165
- //public void lightFalloff(float constant, float linear, float quadratic)
2166
- //public void lightSpecular(float x, float y, float z)
2167
- //protected void lightPosition(int num, float x, float y, float z)
2168
- //protected void lightDirection(int num, float x, float y, float z)
2169
- //////////////////////////////////////////////////////////////
2170
- // BACKGROUND
2171
- int[] clearPixels;
2172
-
2173
- protected void clearPixels(int color) {
2174
- // On a hi-res display, image may be larger than width/height
2175
- int imageWidth = image.getWidth(null);
2176
- int imageHeight = image.getHeight(null);
2177
-
2178
- // Create a small array that can be used to set the pixels several times.
2179
- // Using a single-pixel line of length 'width' is a tradeoff between
2180
- // speed (setting each pixel individually is too slow) and memory
2181
- // (an array for width*height would waste lots of memory if it stayed
2182
- // resident, and would terrify the gc if it were re-created on each trip
2183
- // to background().
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
- WritableRaster raster = getRaster();
2187
- if ((clearPixels == null) || (clearPixels.length < imageWidth)) {
2188
- clearPixels = new int[imageWidth];
2189
- }
2190
- Arrays.fill(clearPixels, 0, imageWidth, backgroundColor);
2191
- for (int i = 0; i < imageHeight; i++) {
2192
- raster.setDataElements(0, i, imageWidth, 1, clearPixels);
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
- // background() methods inherited from PGraphics, along with the
2197
- // PImage version of backgroundImpl(), since it just calls set().
2198
- //public void backgroundImpl(PImage image)
2199
- @Override
2200
- public void backgroundImpl() {
2201
- if (backgroundAlpha) {
2202
- clearPixels(backgroundColor);
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
- } else {
2205
- Color bgColor = new Color(backgroundColor);
2206
- // seems to fire an additional event that causes flickering,
2207
- // like an extra background erase on OS X
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
- //new Exception().printStackTrace(System.out);
2212
- // in case people do transformations before background(),
2213
- // need to handle this with a push/reset/pop
2214
- Composite oldComposite = g2.getComposite();
2215
- g2.setComposite(defaultComposite);
2216
-
2217
- pushMatrix();
2218
- resetMatrix();
2219
- g2.setColor(bgColor); //, backgroundAlpha));
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
- // On a hi-res display, image may be larger than width/height
2222
- if (image != null) {
2223
- // image will be null in subclasses (i.e. PDF)
2224
- g2.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
2225
- } else {
2226
- // hope for the best if image is null
2227
- g2.fillRect(0, 0, width, height);
2228
- }
2229
- popMatrix();
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
- g2.setComposite(oldComposite);
2232
- }
2238
+ g2.setComposite(oldComposite);
2233
2239
  }
2240
+ }
2234
2241
 
2235
- //////////////////////////////////////////////////////////////
2236
- // COLOR MODE
2237
- // All colorMode() variations are inherited from PGraphics.
2238
- //////////////////////////////////////////////////////////////
2239
- // COLOR CALC
2240
- // colorCalc() and colorCalcARGB() inherited from PGraphics.
2241
- //////////////////////////////////////////////////////////////
2242
- // COLOR DATATYPE STUFFING
2243
- // final color() variations inherited.
2244
- //////////////////////////////////////////////////////////////
2245
- // COLOR DATATYPE EXTRACTION
2246
- // final methods alpha, red, green, blue,
2247
- // hue, saturation, and brightness all inherited.
2248
- //////////////////////////////////////////////////////////////
2249
- // COLOR DATATYPE INTERPOLATION
2250
- // both lerpColor variants inherited.
2251
- //////////////////////////////////////////////////////////////
2252
- // BEGIN/END RAW
2253
- @Override
2254
- public void beginRaw(PGraphics recorderRaw) {
2255
- showMethodWarning("beginRaw");
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
- @Override
2259
- public void endRaw() {
2260
- showMethodWarning("endRaw");
2261
- }
2262
-
2263
- //////////////////////////////////////////////////////////////
2264
- // WARNINGS and EXCEPTIONS
2265
- // showWarning and showException inherited.
2266
- //////////////////////////////////////////////////////////////
2267
- // RENDERER SUPPORT QUERIES
2268
- //public boolean displayable() // true
2269
- //public boolean is2D() // true
2270
- //public boolean is3D() // false
2271
- //////////////////////////////////////////////////////////////
2272
- // PIMAGE METHODS
2273
- // getImage, setCache, getCache, removeCache, isModified, setModified
2274
- protected WritableRaster getRaster() {
2275
- WritableRaster raster = null;
2276
- if (primaryGraphics) {
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
- // when possible, we'll try VolatileImage
2283
- raster = ((VolatileImage) image).getSnapshot().getRaster();
2284
- }
2285
- }
2286
- if (raster == null) {
2287
- raster = ((BufferedImage) image).getRaster();
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
- @Override
2305
- public void loadPixels() {
2306
- if (pixels == null || (pixels.length != pixelWidth * pixelHeight)) {
2307
- pixels = new int[pixelWidth * pixelHeight];
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
- WritableRaster raster = getRaster();
2311
- raster.getDataElements(0, 0, pixelWidth, pixelHeight, pixels);
2312
- if (raster.getNumBands() == 3) {
2313
- // Java won't set the high bits when RGB, returns 0 for alpha
2314
- // https://github.com/processing/processing/issues/2030
2315
- for (int i = 0; i < pixels.length; i++) {
2316
- pixels[i] = 0xff000000 | pixels[i];
2317
- }
2318
- }
2319
- //((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width);
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
- * Update the pixels[] buffer to the PGraphics image.
2339
- * <P>
2340
- * Unlike in PImage, where updatePixels() only requests that the update
2341
- * happens, in PGraphicsJava2D, this will happen immediately.
2342
- */
2343
- @Override
2344
- public void updatePixels(int x, int y, int c, int d) {
2345
- //if ((x == 0) && (y == 0) && (c == width) && (d == height)) {
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
- if ((x != 0) || (y != 0) || (c != pixelWidth) || (d != pixelHeight)) {
2348
- // Show a warning message, but continue anyway.
2349
- showVariationWarning("updatePixels(x, y, w, h)");
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
- if (pixels != null) {
2354
- getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
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
- // GET/SET
2371
- static int getset[] = new int[1];
2376
+ //////////////////////////////////////////////////////////////
2377
+ // GET/SET
2378
+ static int getset[] = new int[1];
2372
2379
 
2373
- @Override
2374
- public int get(int x, int y) {
2375
- if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
2376
- return 0;
2377
- }
2378
- //return ((BufferedImage) image).getRGB(x, y);
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
- WritableRaster raster = getRaster();
2381
- raster.getDataElements(x, y, getset);
2382
- if (raster.getNumBands() == 3) {
2383
- // https://github.com/processing/processing/issues/2030
2384
- return getset[0] | 0xff000000;
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
- //public PImage get(int x, int y, int w, int h)
2390
- @Override
2391
- protected void getImpl(int sourceX, int sourceY,
2392
- int sourceWidth, int sourceHeight,
2393
- PImage target, int targetX, int targetY) {
2394
- // last parameter to getRGB() is the scan size of the *target* buffer
2395
- //((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w);
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
- WritableRaster raster = getRaster();
2405
+ WritableRaster raster = getRaster();
2399
2406
 
2400
- if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) {
2401
- raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
2402
- // https://github.com/processing/processing/issues/2030
2403
- if (raster.getNumBands() == 3) {
2404
- target.filter(OPAQUE);
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
- // TODO optimize, incredibly inefficient to reallocate this much memory
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
- @Override
2432
- public void set(int x, int y, int argb) {
2433
- if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) {
2434
- return;
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
- getset[0] = argb;
2444
+ getset[0] = argb;
2438
2445
  // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2439
2446
  // WritableRaster raster = image.getRaster();
2440
- getRaster().setDataElements(x, y, getset);
2441
- }
2447
+ getRaster().setDataElements(x, y, getset);
2448
+ }
2442
2449
 
2443
- //public void set(int x, int y, PImage img)
2444
- @Override
2445
- protected void setImpl(PImage sourceImage,
2446
- int sourceX, int sourceY,
2447
- int sourceWidth, int sourceHeight,
2448
- int targetX, int targetY) {
2449
- WritableRaster raster = getRaster();
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
- if ((sourceX == 0) && (sourceY == 0)
2453
- && (sourceWidth == sourceImage.pixelWidth)
2454
- && (sourceHeight == sourceImage.pixelHeight)) {
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
- raster.setDataElements(targetX, targetY,
2459
- sourceImage.pixelWidth, sourceImage.pixelHeight,
2460
- sourceImage.pixels);
2461
- } else {
2462
- // TODO optimize, incredibly inefficient to reallocate this much memory
2463
- PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight);
2464
- raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels);
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
- // MASK
2470
- static final String MASK_WARNING
2471
- = "mask() cannot be used on the main drawing surface";
2475
+ //////////////////////////////////////////////////////////////
2476
+ // MASK
2477
+ static final String MASK_WARNING
2478
+ = "mask() cannot be used on the main drawing surface";
2472
2479
 
2473
- @Override
2474
- public void mask(int[] alpha) {
2475
- if (primaryGraphics) {
2476
- showWarning(MASK_WARNING);
2480
+ @Override
2481
+ public void mask(int[] alpha) {
2482
+ if (primaryGraphics) {
2483
+ showWarning(MASK_WARNING);
2477
2484
 
2478
- } else {
2479
- super.mask(alpha);
2480
- }
2485
+ } else {
2486
+ super.mask(alpha);
2481
2487
  }
2488
+ }
2482
2489
 
2483
- @Override
2484
- public void mask(PImage alpha) {
2485
- if (primaryGraphics) {
2486
- showWarning(MASK_WARNING);
2490
+ @Override
2491
+ public void mask(PImage alpha) {
2492
+ if (primaryGraphics) {
2493
+ showWarning(MASK_WARNING);
2487
2494
 
2488
- } else {
2489
- super.mask(alpha);
2490
- }
2495
+ } else {
2496
+ super.mask(alpha);
2491
2497
  }
2498
+ }
2492
2499
 
2493
- //////////////////////////////////////////////////////////////
2494
- // FILTER
2495
- // Because the PImage versions call loadPixels() and
2496
- // updatePixels(), no need to override anything here.
2497
- //public void filter(int kind)
2498
- //public void filter(int kind, float param)
2499
- //////////////////////////////////////////////////////////////
2500
- // COPY
2501
- @Override
2502
- public void copy(int sx, int sy, int sw, int sh,
2503
- int dx, int dy, int dw, int dh) {
2504
- if ((sw != dw) || (sh != dh)) {
2505
- g2.drawImage(image, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
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
- } else {
2508
- dx = dx - sx; // java2d's "dx" is the delta, not dest
2509
- dy = dy - sy;
2510
- g2.copyArea(sx, sy, sw, sh, dx, dy);
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
- @Override
2515
- public void copy(PImage src,
2516
- int sx, int sy, int sw, int sh,
2517
- int dx, int dy, int dw, int dh) {
2518
- g2.drawImage((Image) src.getNative(),
2519
- dx, dy, dx + dw, dy + dh,
2520
- sx, sy, sx + sw, sy + sh, null);
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
- // BLEND
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
- // SAVE
2538
+ //////////////////////////////////////////////////////////////
2539
+ // SAVE
2533
2540
  // public void save(String filename) {
2534
2541
  // loadPixels();
2535
2542
  // super.save(filename);