propane 3.3.1-java → 3.4.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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);