propane 3.1.0.pre-java → 3.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  3. data/CHANGELOG.md +1 -5
  4. data/README.md +23 -12
  5. data/Rakefile +23 -12
  6. data/lib/propane/helpers/version_error.rb +6 -0
  7. data/lib/propane/runner.rb +12 -0
  8. data/lib/propane/version.rb +1 -1
  9. data/library/slider/slider.rb +1 -1
  10. data/mvnw +234 -0
  11. data/mvnw.cmd +145 -0
  12. data/pom.xml +28 -27
  13. data/propane.gemspec +2 -2
  14. data/src/main/java/japplemenubar/JAppleMenuBar.java +41 -47
  15. data/src/main/java/monkstone/ColorUtil.java +1 -1
  16. data/src/main/java/monkstone/MathToolModule.java +12 -11
  17. data/src/main/java/monkstone/PropaneLibrary.java +9 -10
  18. data/src/main/java/monkstone/core/LibraryProxy.java +124 -113
  19. data/src/main/java/monkstone/fastmath/Deglut.java +86 -89
  20. data/src/main/java/monkstone/filechooser/Chooser.java +7 -13
  21. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -1
  22. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +4 -4
  23. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  24. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +9 -9
  25. data/src/main/java/monkstone/slider/SimpleSlider.java +0 -9
  26. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +11 -13
  27. data/src/main/java/monkstone/slider/Slider.java +1 -1
  28. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  29. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  30. data/src/main/java/monkstone/slider/WheelHandler.java +8 -9
  31. data/src/main/java/monkstone/vecmath/AppRender.java +2 -2
  32. data/src/main/java/monkstone/vecmath/ShapeRender.java +2 -2
  33. data/src/main/java/monkstone/vecmath/package-info.java +2 -2
  34. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +2 -2
  35. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  36. data/src/main/java/monkstone/videoevent/VideoInterface.java +11 -5
  37. data/src/main/java/monkstone/videoevent/package-info.java +2 -2
  38. data/src/main/java/processing/awt/PGraphicsJava2D.java +1742 -2243
  39. data/src/main/java/processing/awt/PShapeJava2D.java +268 -270
  40. data/src/main/java/processing/awt/PSurfaceAWT.java +821 -920
  41. data/src/main/java/processing/core/DesktopHandler.java +94 -0
  42. data/src/main/java/processing/core/PApplet.java +14170 -14082
  43. data/src/main/java/processing/core/PConstants.java +447 -473
  44. data/src/main/java/processing/core/PFont.java +867 -873
  45. data/src/main/java/processing/core/PGraphics.java +7193 -7428
  46. data/src/main/java/processing/core/PImage.java +3051 -3117
  47. data/src/main/java/processing/core/PMatrix.java +159 -172
  48. data/src/main/java/processing/core/PMatrix2D.java +403 -444
  49. data/src/main/java/processing/core/PMatrix3D.java +735 -749
  50. data/src/main/java/processing/core/PShape.java +2651 -2793
  51. data/src/main/java/processing/core/PShapeOBJ.java +415 -422
  52. data/src/main/java/processing/core/PShapeSVG.java +1466 -1475
  53. data/src/main/java/processing/core/PStyle.java +37 -40
  54. data/src/main/java/processing/core/PSurface.java +98 -103
  55. data/src/main/java/processing/core/PSurfaceNone.java +208 -236
  56. data/src/main/java/processing/core/PVector.java +961 -990
  57. data/src/main/java/processing/data/DoubleDict.java +709 -753
  58. data/src/main/java/processing/data/DoubleList.java +695 -748
  59. data/src/main/java/processing/data/FloatDict.java +702 -746
  60. data/src/main/java/processing/data/FloatList.java +697 -751
  61. data/src/main/java/processing/data/IntDict.java +673 -718
  62. data/src/main/java/processing/data/IntList.java +633 -699
  63. data/src/main/java/processing/data/JSONArray.java +873 -931
  64. data/src/main/java/processing/data/JSONObject.java +1165 -1262
  65. data/src/main/java/processing/data/JSONTokener.java +341 -351
  66. data/src/main/java/processing/data/LongDict.java +662 -707
  67. data/src/main/java/processing/data/LongList.java +634 -700
  68. data/src/main/java/processing/data/Sort.java +41 -37
  69. data/src/main/java/processing/data/StringDict.java +486 -522
  70. data/src/main/java/processing/data/StringList.java +580 -624
  71. data/src/main/java/processing/data/Table.java +3508 -3686
  72. data/src/main/java/processing/data/TableRow.java +183 -182
  73. data/src/main/java/processing/data/XML.java +883 -957
  74. data/src/main/java/processing/event/Event.java +66 -87
  75. data/src/main/java/processing/event/KeyEvent.java +41 -48
  76. data/src/main/java/processing/event/MouseEvent.java +93 -103
  77. data/src/main/java/processing/event/TouchEvent.java +6 -10
  78. data/src/main/java/processing/javafx/PGraphicsFX2D.java +5 -69
  79. data/src/main/java/processing/javafx/PSurfaceFX.java +2 -7
  80. data/src/main/java/processing/opengl/FontTexture.java +270 -290
  81. data/src/main/java/processing/opengl/FrameBuffer.java +363 -375
  82. data/src/main/java/processing/opengl/LinePath.java +500 -543
  83. data/src/main/java/processing/opengl/LineStroker.java +582 -593
  84. data/src/main/java/processing/opengl/PGL.java +2881 -2904
  85. data/src/main/java/processing/opengl/PGraphics2D.java +315 -408
  86. data/src/main/java/processing/opengl/PGraphics3D.java +72 -107
  87. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12043 -12230
  88. data/src/main/java/processing/opengl/PJOGL.java +1681 -1745
  89. data/src/main/java/processing/opengl/PShader.java +1257 -1260
  90. data/src/main/java/processing/opengl/PShapeOpenGL.java +4599 -4662
  91. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1030 -1047
  92. data/src/main/java/processing/opengl/Texture.java +1397 -1462
  93. data/src/main/java/processing/opengl/VertexBuffer.java +55 -57
  94. data/src/main/resources/icon/icon-1024.png +0 -0
  95. data/src/main/resources/icon/icon-128.png +0 -0
  96. data/src/main/resources/icon/icon-16.png +0 -0
  97. data/src/main/resources/icon/icon-256.png +0 -0
  98. data/src/main/resources/icon/icon-32.png +0 -0
  99. data/src/main/resources/icon/icon-48.png +0 -0
  100. data/src/main/resources/icon/icon-512.png +0 -0
  101. data/src/main/resources/icon/icon-64.png +0 -0
  102. data/vendors/Rakefile +1 -1
  103. metadata +12 -8
  104. data/src/main/java/processing/core/ThinkDifferent.java +0 -70
@@ -1,5 +1,3 @@
1
- /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
-
3
1
  /*
4
2
  Part of the Processing project - http://processing.org
5
3
 
@@ -20,8 +18,7 @@
20
18
  Public License along with this library; if not, write to the
21
19
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
20
  Boston, MA 02111-1307 USA
23
- */
24
-
21
+ */
25
22
  package processing.awt;
26
23
 
27
24
  import java.awt.*;
@@ -34,20 +31,20 @@ import java.util.Map;
34
31
 
35
32
  import processing.core.*;
36
33
 
37
-
38
34
  /**
39
35
  * Subclass for PGraphics that implements the graphics API using Java2D.
40
36
  * <p>
41
- * To get access to the Java 2D "Graphics2D" object for the default
42
- * renderer, use:
37
+ * To get access to the Java 2D "Graphics2D" object for the default renderer,
38
+ * use:
43
39
  * <PRE>
44
40
  * Graphics2D g2 = (Graphics2D) g.getNative();
45
- * </PRE>
46
- * This will let you do Graphics2D calls directly, but is not supported
47
- * in any way shape or form. Which just means "have fun, but don't complain
48
- * if it breaks."
41
+ * </PRE> This will let you do Graphics2D calls directly, but is not supported
42
+ * in any way shape or form. Which just means "have fun, but don't complain if
43
+ * it breaks."
49
44
  * <p>
50
- * Advanced <a href="http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html">debugging notes</a> for Java2D.
45
+ * Advanced
46
+ * <a href="http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html">debugging
47
+ * notes</a> for Java2D.
51
48
  */
52
49
  public class PGraphicsJava2D extends PGraphics {
53
50
  //// BufferStrategy strategy;
@@ -60,69 +57,58 @@ public class PGraphicsJava2D extends PGraphics {
60
57
  //// boolean useOffscreen = true; // ~40fps
61
58
  // boolean useOffscreen = false;
62
59
 
63
- public Graphics2D g2;
60
+ public Graphics2D g2;
64
61
  // protected BufferedImage offscreen;
65
62
 
66
- Composite defaultComposite;
67
-
68
- GeneralPath gpath;
69
-
70
- // path for contours so gpath can be closed
71
- GeneralPath auxPath;
72
-
73
- boolean openContour;
74
-
75
- /// break the shape at the next vertex (next vertex() call is a moveto())
76
- boolean breakShape;
77
-
78
- /// coordinates for internal curve calculation
79
- float[] curveCoordX;
80
- float[] curveCoordY;
81
- float[] curveDrawX;
82
- float[] curveDrawY;
83
-
84
- int transformCount;
85
- AffineTransform transformStack[] =
86
- new AffineTransform[MATRIX_STACK_DEPTH];
87
- double[] transform = new double[6];
88
-
89
- Line2D.Float line = new Line2D.Float();
90
- Ellipse2D.Float ellipse = new Ellipse2D.Float();
91
- Rectangle2D.Float rect = new Rectangle2D.Float();
92
- Arc2D.Float arc = new Arc2D.Float();
93
-
94
- protected Color tintColorObject;
95
-
96
- protected Color fillColorObject;
97
- public boolean fillGradient;
98
- public Paint fillGradientObject;
99
-
100
- protected Stroke strokeObject;
101
- protected Color strokeColorObject;
102
- public boolean strokeGradient;
103
- public Paint strokeGradientObject;
104
-
105
- Font fontObject;
106
-
63
+ Composite defaultComposite;
107
64
 
65
+ GeneralPath gpath;
108
66
 
109
- //////////////////////////////////////////////////////////////
67
+ // path for contours so gpath can be closed
68
+ GeneralPath auxPath;
110
69
 
111
- // INTERNAL
70
+ boolean openContour;
112
71
 
72
+ /// break the shape at the next vertex (next vertex() call is a moveto())
73
+ boolean breakShape;
113
74
 
114
- public PGraphicsJava2D() { }
75
+ /// coordinates for internal curve calculation
76
+ float[] curveCoordX;
77
+ float[] curveCoordY;
78
+ float[] curveDrawX;
79
+ float[] curveDrawY;
115
80
 
81
+ int transformCount;
82
+ AffineTransform transformStack[]
83
+ = new AffineTransform[MATRIX_STACK_DEPTH];
84
+ double[] transform = new double[6];
116
85
 
117
- //public void setParent(PApplet parent)
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();
118
90
 
91
+ protected Color tintColorObject;
119
92
 
120
- //public void setPrimary(boolean primary)
93
+ protected Color fillColorObject;
94
+ public boolean fillGradient;
95
+ public Paint fillGradientObject;
121
96
 
97
+ protected Stroke strokeObject;
98
+ protected Color strokeColorObject;
99
+ public boolean strokeGradient;
100
+ public Paint strokeGradientObject;
122
101
 
123
- //public void setPath(String path)
102
+ Font fontObject;
124
103
 
104
+ //////////////////////////////////////////////////////////////
105
+ // INTERNAL
106
+ public PGraphicsJava2D() {
107
+ }
125
108
 
109
+ //public void setParent(PApplet parent)
110
+ //public void setPrimary(boolean primary)
111
+ //public void setPath(String path)
126
112
  // /**
127
113
  // * Called in response to a resize event, handles setting the
128
114
  // * new width and height internally, as well as re-allocating
@@ -138,16 +124,12 @@ public class PGraphicsJava2D extends PGraphics {
138
124
  // allocate();
139
125
  // reapplySettings();
140
126
  // }
141
-
142
-
143
127
  // @Override
144
128
  // protected void allocate() {
145
129
  // //surface.initImage(this, width, height);
146
130
  // surface.initImage(this);
147
131
  // }
148
-
149
-
150
- /*
132
+ /*
151
133
  @Override
152
134
  protected void allocate() {
153
135
  // Tried this with RGB instead of ARGB for the primarySurface version,
@@ -219,9 +201,9 @@ public class PGraphicsJava2D extends PGraphics {
219
201
  image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
220
202
  g2 = (Graphics2D) image.getGraphics();
221
203
  }
222
- */
204
+ */
223
205
 
224
- /*
206
+ /*
225
207
  if (primarySurface) {
226
208
  Canvas canvas = ((PSurfaceAWT) surface).canvas;
227
209
 
@@ -242,45 +224,35 @@ public class PGraphicsJava2D extends PGraphics {
242
224
  g2 = (Graphics2D) image.getGraphics();
243
225
  }
244
226
  */
227
+ //public void dispose()
228
+ @Override
229
+ public PSurface createSurface() {
230
+ return surface = new PSurfaceAWT(this);
231
+ }
245
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
+ }
246
241
 
247
- //public void dispose()
248
-
249
-
250
- @Override
251
- public PSurface createSurface() {
252
- return surface = new PSurfaceAWT(this);
253
- }
254
-
255
-
256
- /**
257
- * Still need a means to get the java.awt.Image object, since getNative()
258
- * is going to return the {@link Graphics2D} object.
259
- */
260
- @Override
261
- public Image getImage() {
262
- return image;
263
- }
264
-
265
-
266
- /** Returns the java.awt.Graphics2D object used by this renderer. */
267
- @Override
268
- public Object getNative() {
269
- return g2;
270
- }
271
-
272
-
273
- //////////////////////////////////////////////////////////////
274
-
275
- // FRAME
276
-
242
+ /**
243
+ * Returns the java.awt.Graphics2D object used by this renderer.
244
+ */
245
+ @Override
246
+ public Object getNative() {
247
+ return g2;
248
+ }
277
249
 
250
+ //////////////////////////////////////////////////////////////
251
+ // FRAME
278
252
  // @Override
279
253
  // public boolean canDraw() {
280
254
  // return true;
281
255
  // }
282
-
283
-
284
256
  // @Override
285
257
  // public void requestDraw() {
286
258
  //// EventQueue.invokeLater(new Runnable() {
@@ -289,14 +261,11 @@ public class PGraphicsJava2D extends PGraphics {
289
261
  //// }
290
262
  //// });
291
263
  // }
292
-
293
-
294
264
  // Graphics2D g2old;
295
-
296
- public Graphics2D checkImage() {
297
- if (image == null ||
298
- ((BufferedImage) image).getWidth() != width*pixelDensity ||
299
- ((BufferedImage) image).getHeight() != height*pixelDensity) {
265
+ public Graphics2D checkImage() {
266
+ if (image == null
267
+ || ((BufferedImage) image).getWidth() != width * pixelDensity
268
+ || ((BufferedImage) image).getHeight() != height * pixelDensity) {
300
269
  // ((VolatileImage) image).getWidth() != width ||
301
270
  // ((VolatileImage) image).getHeight() != height) {
302
271
  // image = new BufferedImage(width * pixelFactor, height * pixelFactor
@@ -321,48 +290,46 @@ public class PGraphicsJava2D extends PGraphics {
321
290
  // GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
322
291
  // gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
323
292
  // }
324
-
325
- // Formerly this was broken into separate versions based on offscreen or
326
- // not, but we may as well create a compatible image; it won't hurt, right?
327
- // P.S.: Three years later, I'm happy to report it did in fact hurt [jv 2018-06-01]
328
- int wide = width * pixelDensity;
329
- int high = height * pixelDensity;
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;
330
298
  // System.out.println("re-creating image");
331
299
 
332
- // For now we expect non-premultiplied INT ARGB and the compatible image
333
- // might not be it... create the image directly. It's important that the
334
- // image has all four bands, otherwise we get garbage alpha during blending
335
- // (see https://github.com/processing/processing/pull/2645,
336
- // https://github.com/processing/processing/pull/3523)
337
- //
338
- // image = gc.createCompatibleImage(wide, high, Transparency.TRANSLUCENT);
339
- image = new BufferedImage(wide, high, BufferedImage.TYPE_INT_ARGB);
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();
340
310
  }
341
- return (Graphics2D) image.getGraphics();
342
- }
343
-
344
311
 
345
- @Override
346
- public void beginDraw() {
347
- g2 = checkImage();
312
+ @Override
313
+ public void beginDraw() {
314
+ g2 = checkImage();
348
315
 
349
- // Calling getGraphics() seems to nuke several settings.
350
- // It seems to be re-creating a new Graphics2D object each time.
351
- // https://github.com/processing/processing/issues/3331
352
- if (strokeObject != null) {
353
- g2.setStroke(strokeObject);
354
- }
355
- // https://github.com/processing/processing/issues/2617
356
- if (fontObject != null) {
357
- g2.setFont(fontObject);
358
- }
359
- // https://github.com/processing/processing/issues/4019
360
- if (blendMode != 0) {
361
- blendMode(blendMode);
362
- }
363
- handleSmooth();
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();
364
331
 
365
- /*
332
+ /*
366
333
  // NOTE: Calling image.getGraphics() will create a new Graphics context,
367
334
  // even if it's for the same image that's already had a context created.
368
335
  // Seems like a speed/memory issue, and also requires that all smoothing,
@@ -413,48 +380,46 @@ public class PGraphicsJava2D extends PGraphics {
413
380
  reapplySettings = true;
414
381
  }
415
382
  }
416
- */
417
-
418
- checkSettings();
419
- resetMatrix(); // reset model matrix
420
- vertexCount = 0;
421
- }
422
-
383
+ */
384
+ checkSettings();
385
+ resetMatrix(); // reset model matrix
386
+ vertexCount = 0;
387
+ }
423
388
 
424
- /**
425
- * Smoothing for Java2D is 2 for bilinear, and 3 for bicubic (the default).
426
- * Internally, smooth(1) is the default, smooth(0) is noSmooth().
427
- */
428
- protected void handleSmooth() {
429
- if (smooth == 0) {
430
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
431
- RenderingHints.VALUE_ANTIALIAS_OFF);
432
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
433
- RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
434
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
435
- RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
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
+ */
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);
436
401
 
437
- } else {
438
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
439
- RenderingHints.VALUE_ANTIALIAS_ON);
440
-
441
- if (smooth == 1 || smooth == 3) { // default is bicubic
442
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
443
- RenderingHints.VALUE_INTERPOLATION_BICUBIC);
444
- } else if (smooth == 2) {
445
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
446
- RenderingHints.VALUE_INTERPOLATION_BILINEAR);
447
- }
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
+ }
448
413
 
449
- // http://docs.oracle.com/javase/tutorial/2d/text/renderinghints.html
450
- // Oracle Java text anti-aliasing on OS X looks like s*t compared to the
451
- // text rendering with Apple's old Java 6. Below, several attempts to fix:
452
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
453
- RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
454
- // Turns out this is the one that actually makes things work.
455
- // Kerning is still screwed up, however.
456
- g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
457
- RenderingHints.VALUE_FRACTIONALMETRICS_ON);
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);
458
423
  // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
459
424
  // RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
460
425
  // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
@@ -462,18 +427,17 @@ public class PGraphicsJava2D extends PGraphics {
462
427
 
463
428
  // g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
464
429
  // RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
430
+ }
465
431
  }
466
- }
467
-
468
432
 
469
- @Override
470
- public void endDraw() {
471
- // hm, mark pixels as changed, because this will instantly do a full
472
- // copy of all the pixels to the surface.. so that's kind of a mess.
473
- //updatePixels();
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();
474
438
 
475
- if (primaryGraphics) {
476
- /*
439
+ if (primaryGraphics) {
440
+ /*
477
441
  //if (canvas != null) {
478
442
  if (useCanvas) {
479
443
  //System.out.println(canvas);
@@ -501,11 +465,11 @@ public class PGraphicsJava2D extends PGraphics {
501
465
  // g2.dispose();
502
466
  // System.out.println("not doing anything special in endDraw()");
503
467
  }
504
- */
505
- } else {
506
- // TODO this is probably overkill for most tasks...
507
- loadPixels();
508
- }
468
+ */
469
+ } else {
470
+ // TODO this is probably overkill for most tasks...
471
+ loadPixels();
472
+ }
509
473
 
510
474
  // // Marking as modified, and then calling updatePixels() in
511
475
  // // the super class, which just sets the mx1, my1, mx2, my2
@@ -513,16 +477,15 @@ public class PGraphicsJava2D extends PGraphics {
513
477
  // // full copy of the pixels to the surface in this.updatePixels().
514
478
  // setModified();
515
479
  // 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();
516
483
 
517
- // Marks pixels as modified so that the pixels will be updated.
518
- // Also sets mx1/y1/x2/y2 so that OpenGL will pick it up.
519
- setModified();
520
-
521
- g2.dispose();
522
- }
484
+ g2.dispose();
485
+ }
523
486
 
524
487
 
525
- /*
488
+ /*
526
489
  private void redraw() {
527
490
  // only need this check if the validate() call will use redraw()
528
491
  // if (strategy == null) return;
@@ -565,20 +528,12 @@ public class PGraphicsJava2D extends PGraphics {
565
528
  } while (strategy.contentsLost());
566
529
  PApplet.debug("PGraphicsJava2D.redraw() out of do { } block");
567
530
  }
568
- */
569
-
570
-
571
-
572
- //////////////////////////////////////////////////////////////
573
-
574
- // SETTINGS
575
-
576
-
577
- //protected void checkSettings()
578
-
579
-
580
- @Override
581
- protected void defaultSettings() {
531
+ */
532
+ //////////////////////////////////////////////////////////////
533
+ // SETTINGS
534
+ //protected void checkSettings()
535
+ @Override
536
+ protected void defaultSettings() {
582
537
  // if (!useCanvas) {
583
538
  // // Papered over another threading issue...
584
539
  // // See if this comes back now that the other issue is fixed.
@@ -588,65 +543,49 @@ public class PGraphicsJava2D extends PGraphics {
588
543
  //// Thread.sleep(5);
589
544
  //// } catch (InterruptedException e) { }
590
545
  //// }
591
- defaultComposite = g2.getComposite();
546
+ defaultComposite = g2.getComposite();
592
547
  // }
593
- super.defaultSettings();
594
- }
595
-
596
-
597
- //protected void reapplySettings()
598
-
599
-
600
-
601
- //////////////////////////////////////////////////////////////
602
-
603
- // HINT
604
-
605
-
606
- @Override
607
- public void hint(int which) {
608
- // take care of setting the hint
609
- super.hint(which);
610
-
611
- // Avoid badness when drawing shorter strokes.
612
- // http://code.google.com/p/processing/issues/detail?id=1068
613
- // Unfortunately cannot always be enabled, because it makes the
614
- // stroke in many standard Processing examples really gross.
615
- if (which == ENABLE_STROKE_PURE) {
616
- g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
617
- RenderingHints.VALUE_STROKE_PURE);
618
- } else if (which == DISABLE_STROKE_PURE) {
619
- g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
620
- RenderingHints.VALUE_STROKE_DEFAULT);
548
+ super.defaultSettings();
549
+ }
550
+
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
+ }
621
570
  }
622
- }
623
571
 
572
+ //////////////////////////////////////////////////////////////
573
+ // SHAPE CREATION
574
+ @Override
575
+ protected PShape createShapeFamily(int type) {
576
+ return new PShape(this, type);
577
+ }
624
578
 
625
-
626
- //////////////////////////////////////////////////////////////
627
-
628
- // SHAPE CREATION
629
-
630
-
631
- @Override
632
- protected PShape createShapeFamily(int type) {
633
- return new PShape(this, type);
634
- }
635
-
636
-
637
- @Override
638
- protected PShape createShapePrimitive(int kind, float... p) {
639
- return new PShape(this, kind, p);
640
- }
641
-
579
+ @Override
580
+ protected PShape createShapePrimitive(int kind, float... p) {
581
+ return new PShape(this, kind, p);
582
+ }
642
583
 
643
584
  // @Override
644
585
  // public PShape createShape(PShape source) {
645
586
  // return PShapeOpenGL.createShape2D(this, source);
646
587
  // }
647
-
648
-
649
- /*
588
+ /*
650
589
  protected PShape createShapeImpl(PGraphicsJava2D pg, int type) {
651
590
  PShape shape = null;
652
591
  if (type == PConstants.GROUP) {
@@ -660,10 +599,8 @@ public class PGraphicsJava2D extends PGraphics {
660
599
  //shape.set3D(false);
661
600
  return shape;
662
601
  }
663
- */
664
-
665
-
666
- /*
602
+ */
603
+ /*
667
604
  static protected PShape createShapeImpl(PGraphicsJava2D pg,
668
605
  int kind, float... p) {
669
606
  PShape shape = null;
@@ -735,752 +672,614 @@ public class PGraphicsJava2D extends PGraphics {
735
672
 
736
673
  return shape;
737
674
  }
738
- */
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
+ }
701
+
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;
810
+ }
811
+ }
812
+
813
+ @Override
814
+ public void vertex(float x, float y, float z) {
815
+ showDepthWarningXYZ("vertex");
816
+ }
739
817
 
818
+ @Override
819
+ public void vertex(float[] v) {
820
+ vertex(v[X], v[Y]);
821
+ }
740
822
 
823
+ @Override
824
+ public void vertex(float x, float y, float u, float v) {
825
+ showVariationWarning("vertex(x, y, u, v)");
826
+ }
741
827
 
742
- //////////////////////////////////////////////////////////////
828
+ @Override
829
+ public void vertex(float x, float y, float z, float u, float v) {
830
+ showDepthWarningXYZ("vertex");
831
+ }
743
832
 
744
- // SHAPES
833
+ @Override
834
+ public void beginContour() {
835
+ if (openContour) {
836
+ PGraphics.showWarning("Already called beginContour()");
837
+ return;
838
+ }
745
839
 
840
+ // draw contours to auxiliary path so main path can be closed later
841
+ GeneralPath contourPath = auxPath;
842
+ auxPath = gpath;
843
+ gpath = contourPath;
746
844
 
747
- @Override
748
- public void beginShape(int kind) {
749
- //super.beginShape(kind);
750
- shape = kind;
751
- vertexCount = 0;
752
- curveVertexCount = 0;
753
-
754
- // set gpath to null, because when mixing curves and straight
755
- // lines, vertexCount will be set back to zero, so vertexCount == 1
756
- // is no longer a good indicator of whether the shape is new.
757
- // this way, just check to see if gpath is null, and if it isn't
758
- // then just use it to continue the shape.
759
- gpath = null;
760
- auxPath = null;
761
- }
845
+ if (contourPath != null) { // first contour does not break
846
+ breakShape = true;
847
+ }
762
848
 
849
+ openContour = true;
850
+ }
763
851
 
764
- //public boolean edge(boolean e)
852
+ @Override
853
+ public void endContour() {
854
+ if (!openContour) {
855
+ PGraphics.showWarning("Need to call beginContour() first");
856
+ return;
857
+ }
765
858
 
859
+ // close this contour
860
+ if (gpath != null) {
861
+ gpath.closePath();
862
+ }
766
863
 
767
- //public void normal(float nx, float ny, float nz) {
864
+ // switch back to main path
865
+ GeneralPath contourPath = gpath;
866
+ gpath = auxPath;
867
+ auxPath = contourPath;
768
868
 
869
+ openContour = false;
870
+ }
769
871
 
770
- //public void textureMode(int mode)
872
+ @Override
873
+ public void endShape(int mode) {
874
+ if (openContour) { // correct automagically, notify user
875
+ endContour();
876
+ PGraphics.showWarning("Missing endContour() before endShape()");
877
+ }
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
+ }
888
+ }
889
+ shape = 0;
890
+ }
771
891
 
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
+ }
772
898
 
773
- @Override
774
- public void texture(PImage image) {
775
- showMethodWarning("texture");
776
- }
899
+ @Override
900
+ public void noClip() {
901
+ g2.setClip(null);
902
+ }
777
903
 
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);
778
921
 
779
- @Override
780
- public void vertex(float x, float y) {
781
- curveVertexCount = 0;
782
- //float vertex[];
783
-
784
- if (vertexCount == vertices.length) {
785
- float temp[][] = new float[vertexCount<<1][VERTEX_FIELD_COUNT];
786
- System.arraycopy(vertices, 0, temp, 0, vertexCount);
787
- vertices = temp;
788
- //message(CHATTER, "allocating more vertices " + vertices.length);
789
- }
790
- // not everyone needs this, but just easier to store rather
791
- // than adding another moving part to the code...
792
- vertices[vertexCount][X] = x;
793
- vertices[vertexCount][Y] = y;
794
- vertexCount++;
795
-
796
- switch (shape) {
797
-
798
- case POINTS:
799
- point(x, y);
800
- break;
801
-
802
- case LINES:
803
- if ((vertexCount % 2) == 0) {
804
- line(vertices[vertexCount-2][X],
805
- vertices[vertexCount-2][Y], x, y);
806
- }
807
- break;
808
-
809
- case TRIANGLES:
810
- if ((vertexCount % 3) == 0) {
811
- triangle(vertices[vertexCount - 3][X],
812
- vertices[vertexCount - 3][Y],
813
- vertices[vertexCount - 2][X],
814
- vertices[vertexCount - 2][Y],
815
- x, y);
816
- }
817
- break;
818
-
819
- case TRIANGLE_STRIP:
820
- if (vertexCount >= 3) {
821
- triangle(vertices[vertexCount - 2][X],
822
- vertices[vertexCount - 2][Y],
823
- vertices[vertexCount - 1][X],
824
- vertices[vertexCount - 1][Y],
825
- vertices[vertexCount - 3][X],
826
- vertices[vertexCount - 3][Y]);
827
- }
828
- break;
829
-
830
- case TRIANGLE_FAN:
831
- if (vertexCount >= 3) {
832
- // This is an unfortunate implementation because the stroke for an
833
- // adjacent triangle will be repeated. However, if the stroke is not
834
- // redrawn, it will replace the adjacent line (when it lines up
835
- // perfectly) or show a faint line (when off by a small amount).
836
- // The alternative would be to wait, then draw the shape as a
837
- // polygon fill, followed by a series of vertices. But that's a
838
- // poor method when used with PDF, DXF, or other recording objects,
839
- // since discrete triangles would likely be preferred.
840
- triangle(vertices[0][X],
841
- vertices[0][Y],
842
- vertices[vertexCount - 2][X],
843
- vertices[vertexCount - 2][Y],
844
- x, y);
845
- }
846
- break;
847
-
848
- case QUAD:
849
- case QUADS:
850
- if ((vertexCount % 4) == 0) {
851
- quad(vertices[vertexCount - 4][X],
852
- vertices[vertexCount - 4][Y],
853
- vertices[vertexCount - 3][X],
854
- vertices[vertexCount - 3][Y],
855
- vertices[vertexCount - 2][X],
856
- vertices[vertexCount - 2][Y],
857
- x, y);
858
- }
859
- break;
860
-
861
- case QUAD_STRIP:
862
- // 0---2---4
863
- // | | |
864
- // 1---3---5
865
- if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) {
866
- quad(vertices[vertexCount - 4][X],
867
- vertices[vertexCount - 4][Y],
868
- vertices[vertexCount - 2][X],
869
- vertices[vertexCount - 2][Y],
870
- x, y,
871
- vertices[vertexCount - 3][X],
872
- vertices[vertexCount - 3][Y]);
873
- }
874
- break;
922
+ } else {
923
+ g2.setComposite(new Composite() {
875
924
 
876
- case POLYGON:
877
- if (gpath == null) {
878
- gpath = new GeneralPath();
879
- gpath.moveTo(x, y);
880
- } else if (breakShape) {
881
- gpath.moveTo(x, y);
882
- breakShape = false;
883
- } else {
884
- gpath.lineTo(x, y);
885
- }
886
- break;
925
+ @Override
926
+ public CompositeContext createContext(ColorModel srcColorModel,
927
+ ColorModel dstColorModel,
928
+ RenderingHints hints) {
929
+ return new BlendingContext(blendMode);
930
+ }
931
+ });
932
+ }
887
933
  }
888
- }
889
-
890
934
 
891
- @Override
892
- public void vertex(float x, float y, float z) {
893
- showDepthWarningXYZ("vertex");
894
- }
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 {
895
939
 
896
- @Override
897
- public void vertex(float[] v) {
898
- vertex(v[X], v[Y]);
899
- }
940
+ private int mode;
900
941
 
942
+ private BlendingContext(int mode) {
943
+ this.mode = mode;
944
+ }
901
945
 
902
- @Override
903
- public void vertex(float x, float y, float u, float v) {
904
- showVariationWarning("vertex(x, y, u, v)");
905
- }
946
+ public void dispose() {
947
+ }
906
948
 
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
+ }
907
956
 
908
- @Override
909
- public void vertex(float x, float y, float z, float u, float v) {
910
- showDepthWarningXYZ("vertex");
911
- }
957
+ int width = Math.min(src.getWidth(), dstIn.getWidth());
958
+ int height = Math.min(src.getHeight(), dstIn.getHeight());
912
959
 
960
+ int[] srcPixels = new int[width];
961
+ int[] dstPixels = new int[width];
913
962
 
914
- @Override
915
- public void beginContour() {
916
- if (openContour) {
917
- PGraphics.showWarning("Already called beginContour()");
918
- return;
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
+ }
971
+ }
919
972
  }
920
973
 
921
- // draw contours to auxiliary path so main path can be closed later
922
- GeneralPath contourPath = auxPath;
923
- auxPath = gpath;
924
- gpath = contourPath;
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
+ }
925
983
 
926
- if (contourPath != null) { // first contour does not break
927
- breakShape = true;
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");
928
989
  }
929
990
 
930
- openContour = true;
931
- }
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();
932
998
 
999
+ float x1 = (float) cur.getX();
1000
+ float y1 = (float) cur.getY();
933
1001
 
934
- @Override
935
- public void endContour() {
936
- if (!openContour) {
937
- PGraphics.showWarning("Need to call beginContour() first");
938
- return;
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);
939
1005
  }
940
1006
 
941
- // close this contour
942
- if (gpath != null) gpath.closePath();
943
-
944
- // switch back to main path
945
- GeneralPath contourPath = gpath;
946
- gpath = auxPath;
947
- auxPath = contourPath;
948
-
949
- openContour = false;
950
- }
1007
+ @Override
1008
+ public void quadraticVertex(float x2, float y2, float z2,
1009
+ float x4, float y4, float z4) {
1010
+ showDepthWarningXYZ("quadVertex");
1011
+ }
951
1012
 
1013
+ //////////////////////////////////////////////////////////////
1014
+ // CURVE VERTICES
1015
+ @Override
1016
+ protected void curveVertexCheck() {
1017
+ super.curveVertexCheck();
952
1018
 
953
- @Override
954
- public void endShape(int mode) {
955
- if (openContour) { // correct automagically, notify user
956
- endContour();
957
- PGraphics.showWarning("Missing endContour() before endShape()");
958
- }
959
- if (gpath != null) { // make sure something has been drawn
960
- if (shape == POLYGON) {
961
- if (mode == CLOSE) {
962
- gpath.closePath();
1019
+ if (curveCoordX == null) {
1020
+ curveCoordX = new float[4];
1021
+ curveCoordY = new float[4];
1022
+ curveDrawX = new float[4];
1023
+ curveDrawY = new float[4];
963
1024
  }
964
- if (auxPath != null) {
965
- gpath.append(auxPath, false);
966
- }
967
- drawShape(gpath);
968
- }
969
1025
  }
970
- shape = 0;
971
- }
972
-
973
- //////////////////////////////////////////////////////////////
974
-
975
- // CLIPPING
976
-
977
-
978
- @Override
979
- protected void clipImpl(float x1, float y1, float x2, float y2) {
980
- g2.setClip(new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
981
- }
982
1026
 
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;
983
1034
 
984
- @Override
985
- public void noClip() {
986
- g2.setClip(null);
987
- }
1035
+ curveCoordX[1] = x2;
1036
+ curveCoordY[1] = y2;
988
1037
 
1038
+ curveCoordX[2] = x3;
1039
+ curveCoordY[2] = y3;
989
1040
 
1041
+ curveCoordX[3] = x4;
1042
+ curveCoordY[3] = y4;
990
1043
 
991
- //////////////////////////////////////////////////////////////
1044
+ curveToBezierMatrix.mult(curveCoordX, curveDrawX);
1045
+ curveToBezierMatrix.mult(curveCoordY, curveDrawY);
992
1046
 
993
- // BLEND
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
+ }
994
1053
 
995
- /**
996
- * ( begin auto-generated from blendMode.xml )
997
- *
998
- * This is a new reference entry for Processing 2.0. It will be updated shortly.
999
- *
1000
- * ( end auto-generated )
1001
- *
1002
- * @webref Rendering
1003
- * @param mode the blending mode to use
1004
- */
1005
- @Override
1006
- protected void blendModeImpl() {
1007
- if (blendMode == BLEND) {
1008
- g2.setComposite(defaultComposite);
1054
+ gpath.curveTo(curveDrawX[1], curveDrawY[1],
1055
+ curveDrawX[2], curveDrawY[2],
1056
+ curveDrawX[3], curveDrawY[3]);
1057
+ }
1009
1058
 
1010
- } else {
1011
- g2.setComposite(new Composite() {
1059
+ @Override
1060
+ public void curveVertex(float x, float y, float z) {
1061
+ showDepthWarningXYZ("curveVertex");
1062
+ }
1012
1063
 
1013
- @Override
1014
- public CompositeContext createContext(ColorModel srcColorModel,
1015
- ColorModel dstColorModel,
1016
- RenderingHints hints) {
1017
- return new BlendingContext(blendMode);
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) {
1072
+ // if (strokeWeight > 1) {
1073
+ line(x, y, x + EPSILON, y + EPSILON);
1074
+ // } else {
1075
+ // set((int) screenX(x, y), (int) screenY(x, y), strokeColor);
1076
+ // }
1018
1077
  }
1019
- });
1020
1078
  }
1021
- }
1022
1079
 
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
+ }
1023
1085
 
1024
- // Blending implementation cribbed from portions of Romain Guy's
1025
- // demo and terrific writeup on blending modes in Java 2D.
1026
- // http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
1027
- private static final class BlendingContext implements CompositeContext {
1028
- private int mode;
1029
-
1030
- private BlendingContext(int mode) {
1031
- this.mode = mode;
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);
1032
1095
  }
1033
1096
 
1034
- public void dispose() { }
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
+ }
1118
+
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
+ }
1128
+
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?
1138
+
1139
+ start = -start * RAD_TO_DEG;
1140
+ stop = -stop * RAD_TO_DEG;
1141
+
1142
+ // ok to do this because already checked for NaN
1143
+ // while (start < 0) {
1144
+ // start += 360;
1145
+ // stop += 360;
1146
+ // }
1147
+ // if (start > stop) {
1148
+ // float temp = start;
1149
+ // start = stop;
1150
+ // stop = temp;
1151
+ // }
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;
1035
1158
 
1036
- public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
1037
- // not sure if this is really necessary, since we control our buffers
1038
- if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
1039
- dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
1040
- dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
1041
- throw new IllegalStateException("Source and destination must store pixels as INT.");
1042
- }
1159
+ if (mode == OPEN) {
1160
+ fillMode = Arc2D.OPEN;
1161
+ //strokeMode = Arc2D.OPEN;
1043
1162
 
1044
- int width = Math.min(src.getWidth(), dstIn.getWidth());
1045
- int height = Math.min(src.getHeight(), dstIn.getHeight());
1163
+ } else if (mode == PIE) {
1164
+ //fillMode = Arc2D.PIE;
1165
+ strokeMode = Arc2D.PIE;
1046
1166
 
1047
- int[] srcPixels = new int[width];
1048
- int[] dstPixels = new int[width];
1167
+ } else if (mode == CHORD) {
1168
+ fillMode = Arc2D.CHORD;
1169
+ strokeMode = Arc2D.CHORD;
1170
+ }
1049
1171
 
1050
- for (int y = 0; y < height; y++) {
1051
- src.getDataElements(0, y, width, 1, srcPixels);
1052
- dstIn.getDataElements(0, y, width, 1, dstPixels);
1053
- for (int x = 0; x < width; x++) {
1054
- dstPixels[x] = blendColor(dstPixels[x], srcPixels[x], mode);
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);
1055
1181
  }
1056
- dstOut.setDataElements(0, y, width, 1, dstPixels);
1057
- }
1058
1182
  }
1059
- }
1060
1183
 
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
+ }
1194
+ }
1061
1195
 
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
+ }
1204
+ }
1062
1205
 
1063
- //////////////////////////////////////////////////////////////
1064
-
1065
- // BEZIER VERTICES
1066
-
1067
-
1068
- @Override
1069
- public void bezierVertex(float x1, float y1,
1070
- float x2, float y2,
1071
- float x3, float y3) {
1072
- bezierVertexCheck();
1073
- gpath.curveTo(x1, y1, x2, y2, x3, y3);
1074
- }
1075
-
1076
-
1077
- @Override
1078
- public void bezierVertex(float x2, float y2, float z2,
1079
- float x3, float y3, float z3,
1080
- float x4, float y4, float z4) {
1081
- showDepthWarningXYZ("bezierVertex");
1082
- }
1083
-
1084
-
1085
-
1086
- //////////////////////////////////////////////////////////////
1087
-
1088
- // QUADRATIC BEZIER VERTICES
1089
-
1090
-
1091
- @Override
1092
- public void quadraticVertex(float ctrlX, float ctrlY,
1093
- float endX, float endY) {
1094
- bezierVertexCheck();
1095
- Point2D cur = gpath.getCurrentPoint();
1096
-
1097
- float x1 = (float) cur.getX();
1098
- float y1 = (float) cur.getY();
1099
-
1100
- bezierVertex(x1 + ((ctrlX-x1)*2/3.0f), y1 + ((ctrlY-y1)*2/3.0f),
1101
- endX + ((ctrlX-endX)*2/3.0f), endY + ((ctrlY-endY)*2/3.0f),
1102
- endX, endY);
1103
- }
1104
-
1105
-
1106
- @Override
1107
- public void quadraticVertex(float x2, float y2, float z2,
1108
- float x4, float y4, float z4) {
1109
- showDepthWarningXYZ("quadVertex");
1110
- }
1111
-
1112
-
1113
-
1114
- //////////////////////////////////////////////////////////////
1115
-
1116
- // CURVE VERTICES
1117
-
1118
-
1119
- @Override
1120
- protected void curveVertexCheck() {
1121
- super.curveVertexCheck();
1122
-
1123
- if (curveCoordX == null) {
1124
- curveCoordX = new float[4];
1125
- curveCoordY = new float[4];
1126
- curveDrawX = new float[4];
1127
- curveDrawY = new float[4];
1128
- }
1129
- }
1130
-
1131
-
1132
- @Override
1133
- protected void curveVertexSegment(float x1, float y1,
1134
- float x2, float y2,
1135
- float x3, float y3,
1136
- float x4, float y4) {
1137
- curveCoordX[0] = x1;
1138
- curveCoordY[0] = y1;
1139
-
1140
- curveCoordX[1] = x2;
1141
- curveCoordY[1] = y2;
1142
-
1143
- curveCoordX[2] = x3;
1144
- curveCoordY[2] = y3;
1145
-
1146
- curveCoordX[3] = x4;
1147
- curveCoordY[3] = y4;
1148
-
1149
- curveToBezierMatrix.mult(curveCoordX, curveDrawX);
1150
- curveToBezierMatrix.mult(curveCoordY, curveDrawY);
1151
-
1152
- // since the paths are continuous,
1153
- // only the first point needs the actual moveto
1154
- if (gpath == null) {
1155
- gpath = new GeneralPath();
1156
- gpath.moveTo(curveDrawX[0], curveDrawY[0]);
1157
- }
1158
-
1159
- gpath.curveTo(curveDrawX[1], curveDrawY[1],
1160
- curveDrawX[2], curveDrawY[2],
1161
- curveDrawX[3], curveDrawY[3]);
1162
- }
1163
-
1164
-
1165
- @Override
1166
- public void curveVertex(float x, float y, float z) {
1167
- showDepthWarningXYZ("curveVertex");
1168
- }
1169
-
1170
-
1171
-
1172
- //////////////////////////////////////////////////////////////
1173
-
1174
- // RENDERER
1175
-
1176
-
1177
- //public void flush()
1178
-
1179
-
1180
-
1181
- //////////////////////////////////////////////////////////////
1182
-
1183
- // POINT, LINE, TRIANGLE, QUAD
1184
-
1185
-
1186
- @Override
1187
- public void point(float x, float y) {
1188
- if (stroke) {
1189
- // if (strokeWeight > 1) {
1190
- line(x, y, x + EPSILON, y + EPSILON);
1191
- // } else {
1192
- // set((int) screenX(x, y), (int) screenY(x, y), strokeColor);
1193
- // }
1194
- }
1195
- }
1196
-
1197
-
1198
- @Override
1199
- public void line(float x1, float y1, float x2, float y2) {
1200
- line.setLine(x1, y1, x2, y2);
1201
- strokeShape(line);
1202
- }
1203
-
1204
-
1205
- @Override
1206
- public void triangle(float x1, float y1, float x2, float y2,
1207
- float x3, float y3) {
1208
- gpath = new GeneralPath();
1209
- gpath.moveTo(x1, y1);
1210
- gpath.lineTo(x2, y2);
1211
- gpath.lineTo(x3, y3);
1212
- gpath.closePath();
1213
- drawShape(gpath);
1214
- }
1215
-
1216
-
1217
- @Override
1218
- public void quad(float x1, float y1, float x2, float y2,
1219
- float x3, float y3, float x4, float y4) {
1220
- GeneralPath gp = new GeneralPath();
1221
- gp.moveTo(x1, y1);
1222
- gp.lineTo(x2, y2);
1223
- gp.lineTo(x3, y3);
1224
- gp.lineTo(x4, y4);
1225
- gp.closePath();
1226
- drawShape(gp);
1227
- }
1228
-
1229
-
1230
-
1231
- //////////////////////////////////////////////////////////////
1232
-
1233
- // RECT
1234
-
1235
-
1236
- //public void rectMode(int mode)
1237
-
1238
-
1239
- //public void rect(float a, float b, float c, float d)
1240
-
1241
-
1242
- @Override
1243
- protected void rectImpl(float x1, float y1, float x2, float y2) {
1244
- rect.setFrame(x1, y1, x2-x1, y2-y1);
1245
- drawShape(rect);
1246
- }
1247
-
1248
-
1249
-
1250
- //////////////////////////////////////////////////////////////
1251
-
1252
- // ELLIPSE
1253
-
1254
-
1255
- //public void ellipseMode(int mode)
1256
-
1257
-
1258
- //public void ellipse(float a, float b, float c, float d)
1259
-
1260
-
1261
- @Override
1262
- protected void ellipseImpl(float x, float y, float w, float h) {
1263
- ellipse.setFrame(x, y, w, h);
1264
- drawShape(ellipse);
1265
- }
1266
-
1267
-
1268
-
1269
- //////////////////////////////////////////////////////////////
1270
-
1271
- // ARC
1272
-
1273
-
1274
- //public void arc(float a, float b, float c, float d,
1275
- // float start, float stop)
1276
-
1277
-
1278
- @Override
1279
- protected void arcImpl(float x, float y, float w, float h,
1280
- float start, float stop, int mode) {
1281
- // 0 to 90 in java would be 0 to -90 for p5 renderer
1282
- // but that won't work, so -90 to 0?
1283
-
1284
- start = -start * RAD_TO_DEG;
1285
- stop = -stop * RAD_TO_DEG;
1286
-
1287
- // ok to do this because already checked for NaN
1288
- // while (start < 0) {
1289
- // start += 360;
1290
- // stop += 360;
1291
- // }
1292
- // if (start > stop) {
1293
- // float temp = start;
1294
- // start = stop;
1295
- // stop = temp;
1296
- // }
1297
- float sweep = stop - start;
1298
-
1299
- // The defaults, before 2.0b7, were to stroke as Arc2D.OPEN, and then fill
1300
- // using Arc2D.PIE. That's a little wonky, but it's here for compatability.
1301
- int fillMode = Arc2D.PIE;
1302
- int strokeMode = Arc2D.OPEN;
1303
-
1304
- if (mode == OPEN) {
1305
- fillMode = Arc2D.OPEN;
1306
- //strokeMode = Arc2D.OPEN;
1307
-
1308
- } else if (mode == PIE) {
1309
- //fillMode = Arc2D.PIE;
1310
- strokeMode = Arc2D.PIE;
1311
-
1312
- } else if (mode == CHORD) {
1313
- fillMode = Arc2D.CHORD;
1314
- strokeMode = Arc2D.CHORD;
1315
- }
1316
-
1317
- if (fill) {
1318
- //System.out.println("filla");
1319
- arc.setArc(x, y, w, h, start, sweep, fillMode);
1320
- fillShape(arc);
1321
- }
1322
- if (stroke) {
1323
- //System.out.println("strokey");
1324
- arc.setArc(x, y, w, h, start, sweep, strokeMode);
1325
- strokeShape(arc);
1326
- }
1327
- }
1328
-
1329
-
1330
-
1331
- //////////////////////////////////////////////////////////////
1332
-
1333
- // JAVA2D SHAPE/PATH HANDLING
1334
-
1335
-
1336
- protected void fillShape(Shape s) {
1337
- if (fillGradient) {
1338
- g2.setPaint(fillGradientObject);
1339
- g2.fill(s);
1340
- } else if (fill) {
1341
- g2.setColor(fillColorObject);
1342
- g2.fill(s);
1343
- }
1344
- }
1345
-
1346
-
1347
- protected void strokeShape(Shape s) {
1348
- if (strokeGradient) {
1349
- g2.setPaint(strokeGradientObject);
1350
- g2.draw(s);
1351
- } else if (stroke) {
1352
- g2.setColor(strokeColorObject);
1353
- g2.draw(s);
1354
- }
1355
- }
1356
-
1357
-
1358
- protected void drawShape(Shape s) {
1359
- if (fillGradient) {
1360
- g2.setPaint(fillGradientObject);
1361
- g2.fill(s);
1362
- } else if (fill) {
1363
- g2.setColor(fillColorObject);
1364
- g2.fill(s);
1365
- }
1366
- if (strokeGradient) {
1367
- g2.setPaint(strokeGradientObject);
1368
- g2.draw(s);
1369
- } else if (stroke) {
1370
- g2.setColor(strokeColorObject);
1371
- g2.draw(s);
1372
- }
1373
- }
1374
-
1375
-
1376
-
1377
- //////////////////////////////////////////////////////////////
1378
-
1379
- // BOX
1380
-
1381
-
1382
- //public void box(float size)
1383
-
1384
-
1385
- @Override
1386
- public void box(float w, float h, float d) {
1387
- showMethodWarning("box");
1388
- }
1389
-
1390
-
1391
-
1392
- //////////////////////////////////////////////////////////////
1393
-
1394
- // SPHERE
1395
-
1396
-
1397
- //public void sphereDetail(int res)
1398
-
1399
-
1400
- //public void sphereDetail(int ures, int vres)
1401
-
1402
-
1403
- @Override
1404
- public void sphere(float r) {
1405
- showMethodWarning("sphere");
1406
- }
1407
-
1408
-
1409
-
1410
- //////////////////////////////////////////////////////////////
1411
-
1412
- // BEZIER
1413
-
1414
-
1415
- //public float bezierPoint(float a, float b, float c, float d, float t)
1416
-
1417
-
1418
- //public float bezierTangent(float a, float b, float c, float d, float t)
1419
-
1420
-
1421
- //protected void bezierInitCheck()
1422
-
1423
-
1424
- //protected void bezierInit()
1425
-
1426
-
1427
- /** Ignored (not needed) in Java 2D. */
1428
- @Override
1429
- public void bezierDetail(int detail) {
1430
- }
1431
-
1432
-
1433
- //public void bezier(float x1, float y1,
1434
- // float x2, float y2,
1435
- // float x3, float y3,
1436
- // float x4, float y4)
1437
-
1438
-
1439
- //public void bezier(float x1, float y1, float z1,
1440
- // float x2, float y2, float z2,
1441
- // float x3, float y3, float z3,
1442
- // float x4, float y4, float z4)
1443
-
1444
-
1445
-
1446
- //////////////////////////////////////////////////////////////
1447
-
1448
- // CURVE
1449
-
1450
-
1451
- //public float curvePoint(float a, float b, float c, float d, float t)
1452
-
1453
-
1454
- //public float curveTangent(float a, float b, float c, float d, float t)
1455
-
1456
-
1457
- /** Ignored (not needed) in Java 2D. */
1458
- @Override
1459
- public void curveDetail(int detail) {
1460
- }
1461
-
1462
- //public void curveTightness(float tightness)
1463
-
1464
-
1465
- //protected void curveInitCheck()
1466
-
1467
-
1468
- //protected void curveInit()
1469
-
1470
-
1471
- //public void curve(float x1, float y1,
1472
- // float x2, float y2,
1473
- // float x3, float y3,
1474
- // float x4, float y4)
1475
-
1476
-
1477
- //public void curve(float x1, float y1, float z1,
1478
- // float x2, float y2, float z2,
1479
- // float x3, float y3, float z3,
1480
- // float x4, float y4, float z4)
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
+ }
1221
+ }
1481
1222
 
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
+ }
1482
1230
 
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
+ }
1483
1239
 
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)
1484
1283
  // //////////////////////////////////////////////////////////////
1485
1284
  //
1486
1285
  // // SMOOTH
@@ -1544,87 +1343,75 @@ public class PGraphicsJava2D extends PGraphics {
1544
1343
  // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1545
1344
  // RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
1546
1345
  // }
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
+ }
1547
1365
 
1366
+ ImageCache cash = (ImageCache) getCache(who);
1548
1367
 
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
+ }
1549
1375
 
1550
- //////////////////////////////////////////////////////////////
1551
-
1552
- // IMAGE
1553
-
1554
-
1555
- //public void imageMode(int mode)
1556
-
1557
-
1558
- //public void image(PImage image, float x, float y)
1559
-
1560
-
1561
- //public void image(PImage image, float x, float y, float c, float d)
1562
-
1563
-
1564
- //public void image(PImage image,
1565
- // float a, float b, float c, float d,
1566
- // int u1, int v1, int u2, int v2)
1567
-
1568
-
1569
- /**
1570
- * Handle renderer-specific image drawing.
1571
- */
1572
- @Override
1573
- protected void imageImpl(PImage who,
1574
- float x1, float y1, float x2, float y2,
1575
- int u1, int v1, int u2, int v2) {
1576
- // Image not ready yet, or an error
1577
- if (who.width <= 0 || who.height <= 0) return;
1578
-
1579
- ImageCache cash = (ImageCache) getCache(who);
1580
-
1581
- // Nuke the cache if the image was resized
1582
- if (cash != null) {
1583
- if (who.pixelWidth != cash.image.getWidth() ||
1584
- who.pixelHeight != cash.image.getHeight()) {
1585
- cash = null;
1586
- }
1587
- }
1588
-
1589
- if (cash == null) {
1590
- //System.out.println("making new image cache");
1591
- cash = new ImageCache(); //who);
1592
- setCache(who, cash);
1593
- who.updatePixels(); // mark the whole thing for update
1594
- who.setModified();
1595
- }
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
+ }
1596
1383
 
1597
- // If image previously was tinted, or the color changed
1598
- // or the image was tinted, and tint is now disabled
1599
- if ((tint && !cash.tinted) ||
1600
- (tint && (cash.tintedColor != tintColor)) ||
1601
- (!tint && cash.tinted)) {
1602
- // For tint change, mark all pixels as needing update.
1603
- who.updatePixels();
1604
- }
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
+ }
1605
1392
 
1606
- if (who.isModified()) {
1607
- if (who.pixels == null) {
1608
- // This might be a PGraphics that hasn't been drawn to yet.
1609
- // Can't just bail because the cache has been created above.
1610
- // https://github.com/processing/processing/issues/2208
1611
- who.pixels = new int[who.pixelWidth * who.pixelHeight];
1612
- }
1613
- cash.update(who, tint, tintColor);
1614
- who.setModified(false);
1615
- }
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
+ }
1616
1403
 
1617
- u1 *= who.pixelDensity;
1618
- v1 *= who.pixelDensity;
1619
- u2 *= who.pixelDensity;
1620
- v2 *= who.pixelDensity;
1404
+ u1 *= who.pixelDensity;
1405
+ v1 *= who.pixelDensity;
1406
+ u2 *= who.pixelDensity;
1407
+ v2 *= who.pixelDensity;
1621
1408
 
1622
- g2.drawImage(((ImageCache) getCache(who)).image,
1623
- (int) x1, (int) y1, (int) x2, (int) y2,
1624
- u1, v1, u2, v2, null);
1409
+ g2.drawImage(((ImageCache) getCache(who)).image,
1410
+ (int) x1, (int) y1, (int) x2, (int) y2,
1411
+ u1, v1, u2, v2, null);
1625
1412
 
1626
- // Every few years I think "nah, Java2D couldn't possibly be that f*king
1627
- // slow, why are we doing this by hand?" then comes the affirmation:
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:
1628
1415
  // Composite oldComp = null;
1629
1416
  // if (false && tint) {
1630
1417
  // oldComp = g2.getComposite();
@@ -1644,14 +1431,14 @@ public class PGraphicsJava2D extends PGraphics {
1644
1431
  // if (oldComp != null) {
1645
1432
  // g2.setComposite(oldComp);
1646
1433
  // }
1647
- }
1434
+ }
1648
1435
 
1436
+ static class ImageCache {
1649
1437
 
1650
- static class ImageCache {
1651
- boolean tinted;
1652
- int tintedColor;
1653
- int[] tintedTemp; // one row of tinted pixels
1654
- BufferedImage image;
1438
+ boolean tinted;
1439
+ int tintedColor;
1440
+ int[] tintedTemp; // one row of tinted pixels
1441
+ BufferedImage image;
1655
1442
  // BufferedImage compat;
1656
1443
 
1657
1444
  // public ImageCache(PImage source) {
@@ -1662,146 +1449,145 @@ public class PGraphicsJava2D extends PGraphics {
1662
1449
  // //System.out.println("making new buffered image");
1663
1450
  //// image = new BufferedImage(source.width, source.height, type);
1664
1451
  // }
1665
-
1666
- /**
1667
- * Update the pixels of the cache image. Already determined that the tint
1668
- * has changed, or the pixels have changed, so should just go through
1669
- * with the update without further checks.
1670
- */
1671
- public void update(PImage source, boolean tint, int tintColor) {
1672
- //int bufferType = BufferedImage.TYPE_INT_ARGB;
1673
- int targetType = ARGB;
1674
- boolean opaque = (tintColor & 0xFF000000) == 0xFF000000;
1675
- if (source.format == RGB) {
1676
- if (!tint || (tint && opaque)) {
1677
- //bufferType = BufferedImage.TYPE_INT_RGB;
1678
- targetType = RGB;
1679
- }
1680
- }
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
+ }
1681
1467
  // boolean wrongType = (image != null) && (image.getType() != bufferType);
1682
1468
  // if ((image == null) || wrongType) {
1683
1469
  // image = new BufferedImage(source.width, source.height, bufferType);
1684
1470
  // }
1685
- // Must always use an ARGB image, otherwise will write zeros
1686
- // in the alpha channel when drawn to the screen.
1687
- // https://github.com/processing/processing/issues/2030
1688
- if (image == null) {
1689
- image = new BufferedImage(source.pixelWidth, source.pixelHeight,
1690
- BufferedImage.TYPE_INT_ARGB);
1691
- }
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
+ }
1692
1478
 
1693
- WritableRaster wr = image.getRaster();
1694
- if (tint) {
1695
- if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
1696
- tintedTemp = new int[source.pixelWidth];
1697
- }
1698
- int a2 = (tintColor >> 24) & 0xff;
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;
1699
1485
  // System.out.println("tint color is " + a2);
1700
1486
  // System.out.println("source.pixels[0] alpha is " + (source.pixels[0] >>> 24));
1701
- int r2 = (tintColor >> 16) & 0xff;
1702
- int g2 = (tintColor >> 8) & 0xff;
1703
- int b2 = (tintColor) & 0xff;
1704
-
1705
- //if (bufferType == BufferedImage.TYPE_INT_RGB) {
1706
- if (targetType == RGB) {
1707
- // The target image is opaque, meaning that the source image has no
1708
- // alpha (is not ARGB), and the tint has no alpha.
1709
- int index = 0;
1710
- for (int y = 0; y < source.pixelHeight; y++) {
1711
- for (int x = 0; x < source.pixelWidth; x++) {
1712
- int argb1 = source.pixels[index++];
1713
- int r1 = (argb1 >> 16) & 0xff;
1714
- int g1 = (argb1 >> 8) & 0xff;
1715
- int b1 = (argb1) & 0xff;
1716
-
1717
- // Prior to 2.1, the alpha channel was commented out here,
1718
- // but can't remember why (just thought unnecessary b/c of RGB?)
1719
- // https://github.com/processing/processing/issues/2030
1720
- tintedTemp[x] = 0xFF000000 |
1721
- (((r2 * r1) & 0xff00) << 8) |
1722
- ((g2 * g1) & 0xff00) |
1723
- (((b2 * b1) & 0xff00) >> 8);
1724
- }
1725
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1726
- }
1727
- // could this be any slower?
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?
1728
1514
  // float[] scales = { tintR, tintG, tintB };
1729
1515
  // float[] offsets = new float[3];
1730
1516
  // RescaleOp op = new RescaleOp(scales, offsets, null);
1731
1517
  // op.filter(image, image);
1732
1518
 
1733
- //} else if (bufferType == BufferedImage.TYPE_INT_ARGB) {
1734
- } else if (targetType == ARGB) {
1735
- if (source.format == RGB &&
1736
- (tintColor & 0xffffff) == 0xffffff) {
1737
- int hi = tintColor & 0xff000000;
1738
- int index = 0;
1739
- for (int y = 0; y < source.pixelHeight; y++) {
1740
- for (int x = 0; x < source.pixelWidth; x++) {
1741
- tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
1742
- }
1743
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1744
- }
1745
- } else {
1746
- int index = 0;
1747
- for (int y = 0; y < source.pixelHeight; y++) {
1748
- if (source.format == RGB) {
1749
- int alpha = tintColor & 0xFF000000;
1750
- for (int x = 0; x < source.pixelWidth; x++) {
1751
- int argb1 = source.pixels[index++];
1752
- int r1 = (argb1 >> 16) & 0xff;
1753
- int g1 = (argb1 >> 8) & 0xff;
1754
- int b1 = (argb1) & 0xff;
1755
- tintedTemp[x] = alpha |
1756
- (((r2 * r1) & 0xff00) << 8) |
1757
- ((g2 * g1) & 0xff00) |
1758
- (((b2 * b1) & 0xff00) >> 8);
1759
- }
1760
- } else if (source.format == ARGB) {
1761
- for (int x = 0; x < source.pixelWidth; x++) {
1762
- int argb1 = source.pixels[index++];
1763
- int a1 = (argb1 >> 24) & 0xff;
1764
- int r1 = (argb1 >> 16) & 0xff;
1765
- int g1 = (argb1 >> 8) & 0xff;
1766
- int b1 = (argb1) & 0xff;
1767
- tintedTemp[x] =
1768
- (((a2 * a1) & 0xff00) << 16) |
1769
- (((r2 * r1) & 0xff00) << 8) |
1770
- ((g2 * g1) & 0xff00) |
1771
- (((b2 * b1) & 0xff00) >> 8);
1772
- }
1773
- } else if (source.format == ALPHA) {
1774
- int lower = tintColor & 0xFFFFFF;
1775
- for (int x = 0; x < source.pixelWidth; x++) {
1776
- int a1 = source.pixels[index++];
1777
- tintedTemp[x] =
1778
- (((a2 * a1) & 0xff00) << 16) | lower;
1779
- }
1780
- }
1781
- wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp);
1782
- }
1783
- }
1784
- // Not sure why ARGB images take the scales in this order...
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...
1785
1571
  // float[] scales = { tintR, tintG, tintB, tintA };
1786
1572
  // float[] offsets = new float[4];
1787
1573
  // RescaleOp op = new RescaleOp(scales, offsets, null);
1788
1574
  // op.filter(image, image);
1789
- }
1790
- } else { // !tint
1791
- if (targetType == RGB && (source.pixels[0] >> 24 == 0)) {
1792
- // If it's an RGB image and the high bits aren't set, need to set
1793
- // the high bits to opaque because we're drawing ARGB images.
1794
- source.filter(OPAQUE);
1795
- // Opting to just manipulate the image here, since it shouldn't
1796
- // affect anything else (and alpha(get(x, y)) should return 0xff).
1797
- // Wel also make no guarantees about the values of the pixels array
1798
- // in a PImage and how the high bits will be set.
1799
- }
1800
- // If no tint, just shove the pixels on in there verbatim
1801
- wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels);
1802
- }
1803
- this.tinted = tint;
1804
- this.tintedColor = tintColor;
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;
1805
1591
 
1806
1592
  // GraphicsConfiguration gc = parent.getGraphicsConfiguration();
1807
1593
  // compat = gc.createCompatibleImage(image.getWidth(),
@@ -1811,966 +1597,729 @@ public class PGraphicsJava2D extends PGraphics {
1811
1597
  // Graphics2D g = compat.createGraphics();
1812
1598
  // g.drawImage(image, 0, 0, null);
1813
1599
  // g.dispose();
1600
+ }
1814
1601
  }
1815
- }
1816
-
1817
-
1818
-
1819
- //////////////////////////////////////////////////////////////
1820
-
1821
- // SHAPE
1822
-
1823
-
1824
- //public void shapeMode(int mode)
1825
-
1826
-
1827
- //public void shape(PShape shape)
1828
-
1829
-
1830
- //public void shape(PShape shape, float x, float y)
1831
-
1832
-
1833
- //public void shape(PShape shape, float x, float y, float c, float d)
1834
-
1835
1602
 
1836
- //////////////////////////////////////////////////////////////
1837
-
1838
- // SHAPE I/O
1839
-
1840
-
1841
- //public PShape loadShape(String filename)
1842
-
1843
-
1844
- @Override
1845
- public PShape loadShape(String filename, String options) {
1846
- String extension = PApplet.getExtension(filename);
1847
- if (extension.equals("svg") || extension.equals("svgz")) {
1848
- return new PShapeJava2D(parent.loadXML(filename));
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;
1849
1620
  }
1850
- PGraphics.showWarning("Unsupported format: " + filename);
1851
- return null;
1852
- }
1853
-
1854
-
1855
-
1856
- //////////////////////////////////////////////////////////////
1857
-
1858
- // TEXT ATTRIBTUES
1859
-
1860
-
1861
- //public void textAlign(int align)
1862
-
1863
-
1864
- //public void textAlign(int alignX, int alignY)
1865
1621
 
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
+ }
1866
1631
 
1867
- @Override
1868
- public float textAscent() {
1869
- if (textFont == null) {
1870
- defaultFontOrDeath("textAscent");
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();
1871
1638
  }
1872
1639
 
1873
- Font font = (Font) textFont.getNative();
1874
- if (font != null) {
1875
- //return getFontMetrics(font).getAscent();
1876
- return g2.getFontMetrics(font).getAscent();
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();
1877
1651
  }
1878
- return super.textAscent();
1879
- }
1880
-
1881
1652
 
1882
- @Override
1883
- public float textDescent() {
1884
- if (textFont == null) {
1885
- defaultFontOrDeath("textDescent");
1886
- }
1887
- Font font = (Font) textFont.getNative();
1888
- if (font != null) {
1889
- //return getFontMetrics(font).getDescent();
1890
- return g2.getFontMetrics(font).getDescent();
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;
1891
1660
  }
1892
- return super.textDescent();
1893
- }
1894
-
1895
-
1896
- //public void textFont(PFont which)
1897
1661
 
1898
-
1899
- //public void textFont(PFont which, float size)
1900
-
1901
-
1902
- //public void textLeading(float leading)
1903
-
1904
-
1905
- //public void textMode(int mode)
1906
-
1907
-
1908
- @Override
1909
- protected boolean textModeCheck(int mode) {
1910
- return mode == MODEL;
1911
- }
1912
-
1913
-
1914
- /**
1915
- * Same as parent, but override for native version of the font.
1916
- * <p/>
1917
- * Called from textFontImpl and textSizeImpl, so the metrics
1918
- * will get recorded properly.
1919
- */
1920
- @Override
1921
- protected void handleTextSize(float size) {
1922
- // if a native version available, derive this font
1923
- Font font = (Font) textFont.getNative();
1924
- // don't derive again if the font size has not changed
1925
- if (font != null) {
1926
- if (font.getSize2D() != size) {
1927
- Map<TextAttribute, Object> map =
1928
- new HashMap<>();
1929
- map.put(TextAttribute.SIZE, size);
1930
- map.put(TextAttribute.KERNING,
1931
- TextAttribute.KERNING_ON);
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);
1932
1680
  // map.put(TextAttribute.TRACKING,
1933
1681
  // TextAttribute.TRACKING_TIGHT);
1934
- font = font.deriveFont(map);
1935
- }
1936
- g2.setFont(font);
1937
- textFont.setNative(font);
1938
- fontObject = font;
1939
-
1940
- /*
1941
- Map<TextAttribute, ?> attrs = font.getAttributes();
1942
- for (TextAttribute ta : attrs.keySet()) {
1943
- System.out.println(ta + " -> " + attrs.get(ta));
1944
- }
1945
- */
1946
- }
1947
-
1948
- // take care of setting the textSize and textLeading vars
1949
- // this has to happen second, because it calls textAscent()
1950
- // (which requires the native font metrics to be set)
1951
- super.handleTextSize(size);
1952
- }
1953
-
1954
-
1955
- //public float textWidth(char c)
1956
-
1957
-
1958
- //public float textWidth(String str)
1959
-
1960
-
1961
- @Override
1962
- protected float textWidthImpl(char buffer[], int start, int stop) {
1963
- if (textFont == null) {
1964
- defaultFontOrDeath("textWidth");
1965
- }
1966
- // Avoid "Zero length string passed to TextLayout constructor" error
1967
- if (start == stop) {
1968
- return 0;
1969
- }
1970
-
1971
- Font font = (Font) textFont.getNative();
1972
- // System.out.println(font);
1973
- //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
1974
- if (font != null) {
1975
- // System.out.println("using charswidth for " + new String(buffer, start, stop-start));
1976
- // maybe should use one of the newer/fancier functions for this?
1977
- // int length = stop - start;
1978
- // FontMetrics metrics = getFontMetrics(font);
1979
- FontMetrics metrics = g2.getFontMetrics(font);
1980
- // Using fractional metrics makes the measurement worse, not better,
1981
- // at least on OS X 10.6 (November, 2010).
1982
- // TextLayout returns the same value as charsWidth().
1983
- // System.err.println("using native");
1984
- // g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
1985
- // RenderingHints.VALUE_FRACTIONALMETRICS_ON);
1986
- // float m1 = metrics.charsWidth(buffer, start, length);
1987
- // float m2 = (float) metrics.getStringBounds(buffer, start, stop, g2).getWidth();
1988
- // TextLayout tl = new TextLayout(new String(buffer, start, length), font, g2.getFontRenderContext());
1989
- // float m3 = (float) tl.getBounds().getWidth();
1990
- // System.err.println(m1 + " " + m2 + " " + m3);
1991
- ////// return m1;
1992
- //// return m2;
1993
- //// return metrics.charsWidth(buffer, start, length);
1994
- // return m2;
1995
- return (float)
1996
- metrics.getStringBounds(buffer, start, stop, g2).getWidth();
1997
- }
1998
- // System.err.println("not native");
1999
- return super.textWidthImpl(buffer, start, stop);
2000
- }
2001
-
2002
-
2003
- // protected void beginTextScreenMode() {
2004
- // loadPixels();
2005
- // }
2006
-
2007
-
2008
- // protected void endTextScreenMode() {
2009
- // updatePixels();
2010
- // }
2011
-
2012
-
2013
- //////////////////////////////////////////////////////////////
2014
-
2015
- // TEXT
2016
-
2017
- // None of the variations of text() are overridden from PGraphics.
2018
-
2019
-
2020
-
2021
- //////////////////////////////////////////////////////////////
2022
-
2023
- // TEXT IMPL
2024
-
2025
-
2026
- //protected void textLineAlignImpl(char buffer[], int start, int stop,
2027
- // float x, float y)
2028
-
2029
-
2030
- @Override
2031
- protected void textLineImpl(char buffer[], int start, int stop,
2032
- float x, float y) {
2033
- Font font = (Font) textFont.getNative();
2034
- // if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
2035
- if (font != null) {
2036
- /*
2037
- // save the current setting for text smoothing. note that this is
2038
- // different from the smooth() function, because the font smoothing
2039
- // is controlled when the font is created, not now as it's drawn.
2040
- // fixed a bug in 0116 that handled this incorrectly.
2041
- Object textAntialias =
2042
- g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
2043
-
2044
- // override the current text smoothing setting based on the font
2045
- // (don't change the global smoothing settings)
2046
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
2047
- textFont.smooth ?
2048
- RenderingHints.VALUE_ANTIALIAS_ON :
2049
- RenderingHints.VALUE_ANTIALIAS_OFF);
2050
- */
2051
- Object antialias =
2052
- g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
2053
- if (antialias == null) {
2054
- // if smooth() and noSmooth() not called, this will be null (0120)
2055
- antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT;
2056
- }
2057
-
2058
- // override the current smoothing setting based on the font
2059
- // also changes global setting for antialiasing, but this is because it's
2060
- // not possible to enable/disable them independently in some situations.
2061
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
2062
- textFont.isSmooth() ?
2063
- RenderingHints.VALUE_ANTIALIAS_ON :
2064
- RenderingHints.VALUE_ANTIALIAS_OFF);
2065
-
2066
- g2.setColor(fillColorObject);
2067
-
2068
- int length = stop - start;
2069
- if (length != 0) {
2070
- g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f));
2071
- // better to use round here? also, drawChars now just calls drawString
2072
- // g2.drawString(new String(buffer, start, stop - start), Math.round(x), Math.round(y));
2073
-
2074
- // better to use drawString() with floats? (nope, draws the same)
2075
- //g2.drawString(new String(buffer, start, length), x, y);
2076
-
2077
- // this didn't seem to help the scaling issue, and creates garbage
2078
- // because of a fairly heavyweight new temporary object
2079
- // java.awt.font.GlyphVector gv =
2080
- // font.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop - start));
2081
- // g2.drawGlyphVector(gv, x, y);
2082
- }
2083
-
2084
- // return to previous smoothing state if it was changed
2085
- //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias);
2086
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias);
2087
-
2088
- } else { // otherwise just do the default
2089
- super.textLineImpl(buffer, start, stop, x, y);
2090
- }
2091
- }
2092
-
2093
-
2094
- // /**
2095
- // * Convenience method to get a legit FontMetrics object. Where possible,
2096
- // * override this any renderer subclass so that you're not using what's
2097
- // * returned by getDefaultToolkit() to get your metrics.
2098
- // */
2099
- // @SuppressWarnings("deprecation")
2100
- // public FontMetrics getFontMetrics(Font font) { // ignore
2101
- // Frame frame = parent.frame;
2102
- // if (frame != null) {
2103
- // return frame.getToolkit().getFontMetrics(font);
2104
- // }
2105
- // return Toolkit.getDefaultToolkit().getFontMetrics(font);
2106
- // }
2107
- //
2108
- //
2109
- // /**
2110
- // * Convenience method to jump through some Java2D hoops and get an FRC.
2111
- // */
2112
- // public FontRenderContext getFontRenderContext(Font font) { // ignore
2113
- // return getFontMetrics(font).getFontRenderContext();
2114
- // }
2115
-
2116
- /*
2117
- Toolkit toolkit;
2118
-
2119
- @SuppressWarnings("deprecation")
2120
- protected FontMetrics getFontMetrics(Font font) {
2121
- if (toolkit == null) {
2122
- try {
2123
- Canvas canvas = (Canvas) surface.getNative();
2124
- toolkit = canvas.getToolkit();
2125
- } catch (Exception e) {
2126
- // May error out if it's a PSurfaceNone or similar
2127
- toolkit = Toolkit.getDefaultToolkit();
2128
- }
2129
- }
2130
- return toolkit.getFontMetrics(font);
2131
- //return (g2 != null) ? g2.getFontMetrics(font) : super.getFontMetrics(font);
2132
- }
2133
- */
2134
-
2135
-
2136
- //////////////////////////////////////////////////////////////
2137
-
2138
- // MATRIX STACK
2139
-
2140
-
2141
- @Override
2142
- public void pushMatrix() {
2143
- if (transformCount == transformStack.length) {
2144
- throw new RuntimeException("pushMatrix() cannot use push more than " +
2145
- transformStack.length + " times");
2146
- }
2147
- transformStack[transformCount] = g2.getTransform();
2148
- transformCount++;
2149
- }
2150
-
2151
-
2152
- @Override
2153
- public void popMatrix() {
2154
- if (transformCount == 0) {
2155
- throw new RuntimeException("missing a pushMatrix() " +
2156
- "to go with that popMatrix()");
2157
- }
2158
- transformCount--;
2159
- g2.setTransform(transformStack[transformCount]);
2160
- }
2161
-
2162
-
2163
-
2164
- //////////////////////////////////////////////////////////////
2165
-
2166
- // MATRIX TRANSFORMS
2167
-
2168
-
2169
- @Override
2170
- public void translate(float tx, float ty) {
2171
- g2.translate(tx, ty);
2172
- }
2173
-
2174
-
2175
- //public void translate(float tx, float ty, float tz)
2176
-
2177
-
2178
- @Override
2179
- public void rotate(float angle) {
2180
- g2.rotate(angle);
2181
- }
2182
-
2183
-
2184
- @Override
2185
- public void rotateX(float angle) {
2186
- showDepthWarning("rotateX");
2187
- }
2188
-
2189
-
2190
- @Override
2191
- public void rotateY(float angle) {
2192
- showDepthWarning("rotateY");
2193
- }
2194
-
2195
-
2196
- @Override
2197
- public void rotateZ(float angle) {
2198
- showDepthWarning("rotateZ");
2199
- }
2200
-
2201
-
2202
- @Override
2203
- public void rotate(float angle, float vx, float vy, float vz) {
2204
- showVariationWarning("rotate");
2205
- }
2206
-
2207
-
2208
- @Override
2209
- public void scale(float s) {
2210
- g2.scale(s, s);
2211
- }
2212
-
2213
-
2214
- @Override
2215
- public void scale(float sx, float sy) {
2216
- g2.scale(sx, sy);
2217
- }
2218
-
2219
-
2220
- @Override
2221
- public void scale(float sx, float sy, float sz) {
2222
- showDepthWarningXYZ("scale");
2223
- }
2224
-
2225
-
2226
- @Override
2227
- public void shearX(float angle) {
2228
- g2.shear(Math.tan(angle), 0);
2229
- }
2230
-
2231
-
2232
- @Override
2233
- public void shearY(float angle) {
2234
- g2.shear(0, Math.tan(angle));
2235
- }
2236
-
2237
-
2238
-
2239
- //////////////////////////////////////////////////////////////
2240
-
2241
- // MATRIX MORE
2242
-
2243
-
2244
- @Override
2245
- public void resetMatrix() {
2246
- g2.setTransform(new AffineTransform());
2247
- g2.scale(pixelDensity, pixelDensity);
2248
- }
2249
-
2250
-
2251
- //public void applyMatrix(PMatrix2D source)
2252
-
2253
-
2254
- @Override
2255
- public void applyMatrix(float n00, float n01, float n02,
2256
- float n10, float n11, float n12) {
2257
- //System.out.println("PGraphicsJava2D.applyMatrix()");
2258
- //System.out.println(new AffineTransform(n00, n10, n01, n11, n02, n12));
2259
- g2.transform(new AffineTransform(n00, n10, n01, n11, n02, n12));
2260
- //g2.transform(new AffineTransform(n00, n01, n02, n10, n11, n12));
2261
- }
2262
-
2263
-
2264
- //public void applyMatrix(PMatrix3D source)
2265
-
2266
-
2267
- @Override
2268
- public void applyMatrix(float n00, float n01, float n02, float n03,
2269
- float n10, float n11, float n12, float n13,
2270
- float n20, float n21, float n22, float n23,
2271
- float n30, float n31, float n32, float n33) {
2272
- showVariationWarning("applyMatrix");
2273
- }
2274
-
2275
-
2276
-
2277
- //////////////////////////////////////////////////////////////
2278
-
2279
- // MATRIX GET/SET
2280
-
2281
-
2282
- @Override
2283
- public PMatrix getMatrix() {
2284
- return getMatrix((PMatrix2D) null);
2285
- }
2286
-
2287
-
2288
- @Override
2289
- public PMatrix2D getMatrix(PMatrix2D target) {
2290
- if (target == null) {
2291
- target = new PMatrix2D();
2292
- }
2293
- g2.getTransform().getMatrix(transform);
2294
- target.set((float) transform[0], (float) transform[2], (float) transform[4],
2295
- (float) transform[1], (float) transform[3], (float) transform[5]);
2296
- return target;
2297
- }
2298
-
2299
-
2300
- @Override
2301
- public PMatrix3D getMatrix(PMatrix3D target) {
2302
- showVariationWarning("getMatrix");
2303
- return target;
2304
- }
2305
-
2306
-
2307
- //public void setMatrix(PMatrix source)
2308
-
2309
-
2310
- @Override
2311
- public void setMatrix(PMatrix2D source) {
2312
- g2.setTransform(new AffineTransform(source.m00, source.m10,
2313
- source.m01, source.m11,
2314
- source.m02, source.m12));
2315
- }
2316
-
2317
-
2318
- @Override
2319
- public void setMatrix(PMatrix3D source) {
2320
- showVariationWarning("setMatrix");
2321
- }
2322
-
2323
-
2324
- @Override
2325
- public void printMatrix() {
2326
- getMatrix((PMatrix2D) null).print();
2327
- }
2328
-
2329
-
2330
-
2331
- //////////////////////////////////////////////////////////////
2332
-
2333
- // CAMERA and PROJECTION
2334
-
2335
- // Inherit the plaintive warnings from PGraphics
2336
-
2337
-
2338
- //public void beginCamera()
2339
- //public void endCamera()
2340
- //public void camera()
2341
- //public void camera(float eyeX, float eyeY, float eyeZ,
2342
- // float centerX, float centerY, float centerZ,
2343
- // float upX, float upY, float upZ)
2344
- //public void printCamera()
2345
-
2346
- //public void ortho()
2347
- //public void ortho(float left, float right,
2348
- // float bottom, float top,
2349
- // float near, float far)
2350
- //public void perspective()
2351
- //public void perspective(float fov, float aspect, float near, float far)
2352
- //public void frustum(float left, float right,
2353
- // float bottom, float top,
2354
- // float near, float far)
2355
- //public void printProjection()
2356
-
2357
-
2358
-
2359
- //////////////////////////////////////////////////////////////
2360
-
2361
- // SCREEN and MODEL transforms
2362
-
2363
-
2364
- @Override
2365
- public float screenX(float x, float y) {
2366
- g2.getTransform().getMatrix(transform);
2367
- return (float)transform[0]*x + (float)transform[2]*y + (float)transform[4];
2368
- }
2369
-
2370
-
2371
- @Override
2372
- public float screenY(float x, float y) {
2373
- g2.getTransform().getMatrix(transform);
2374
- return (float)transform[1]*x + (float)transform[3]*y + (float)transform[5];
2375
- }
2376
-
2377
-
2378
- @Override
2379
- public float screenX(float x, float y, float z) {
2380
- showDepthWarningXYZ("screenX");
2381
- return 0;
2382
- }
2383
-
2384
-
2385
- @Override
2386
- public float screenY(float x, float y, float z) {
2387
- showDepthWarningXYZ("screenY");
2388
- return 0;
2389
- }
2390
-
2391
-
2392
- @Override
2393
- public float screenZ(float x, float y, float z) {
2394
- showDepthWarningXYZ("screenZ");
2395
- return 0;
2396
- }
2397
-
2398
-
2399
- //public float modelX(float x, float y, float z)
2400
-
2401
-
2402
- //public float modelY(float x, float y, float z)
2403
-
2404
-
2405
- //public float modelZ(float x, float y, float z)
2406
-
2407
-
2408
-
2409
- //////////////////////////////////////////////////////////////
2410
-
2411
- // STYLE
2412
-
2413
- // pushStyle(), popStyle(), style() and getStyle() inherited.
2414
-
2415
-
2416
-
2417
- //////////////////////////////////////////////////////////////
2418
-
2419
- // STROKE CAP/JOIN/WEIGHT
2420
-
2421
-
2422
- @Override
2423
- public void strokeCap(int cap) {
2424
- super.strokeCap(cap);
2425
- strokeImpl();
2426
- }
2427
-
2428
-
2429
- @Override
2430
- public void strokeJoin(int join) {
2431
- super.strokeJoin(join);
2432
- strokeImpl();
2433
- }
2434
-
2435
-
2436
- @Override
2437
- public void strokeWeight(float weight) {
2438
- super.strokeWeight(weight);
2439
- strokeImpl();
2440
- }
2441
-
2442
-
2443
- protected void strokeImpl() {
2444
- int cap = BasicStroke.CAP_BUTT;
2445
- if (strokeCap == ROUND) {
2446
- cap = BasicStroke.CAP_ROUND;
2447
- } else if (strokeCap == PROJECT) {
2448
- cap = BasicStroke.CAP_SQUARE;
2449
- }
2450
-
2451
- int join = BasicStroke.JOIN_BEVEL;
2452
- if (strokeJoin == MITER) {
2453
- join = BasicStroke.JOIN_MITER;
2454
- } else if (strokeJoin == ROUND) {
2455
- join = BasicStroke.JOIN_ROUND;
2456
- }
2457
-
2458
- strokeObject = new BasicStroke(strokeWeight, cap, join);
2459
- g2.setStroke(strokeObject);
2460
- }
2461
-
2462
-
2463
-
2464
- //////////////////////////////////////////////////////////////
2465
-
2466
- // STROKE
2467
-
2468
- // noStroke() and stroke() inherited from PGraphics.
2469
-
2470
-
2471
- @Override
2472
- protected void strokeFromCalc() {
2473
- super.strokeFromCalc();
2474
- strokeColorObject = new Color(strokeColor, true);
2475
- strokeGradient = false;
2476
- }
2477
-
2478
-
2479
-
2480
- //////////////////////////////////////////////////////////////
2481
-
2482
- // TINT
2483
-
2484
- // noTint() and tint() inherited from PGraphics.
2485
-
2486
-
2487
- @Override
2488
- protected void tintFromCalc() {
2489
- super.tintFromCalc();
2490
- // TODO actually implement tinted images
2491
- tintColorObject = new Color(tintColor, true);
2492
- }
2493
-
2494
-
2495
-
2496
- //////////////////////////////////////////////////////////////
2497
-
2498
- // FILL
2499
-
2500
- // noFill() and fill() inherited from PGraphics.
2501
-
2502
-
2503
- @Override
2504
- protected void fillFromCalc() {
2505
- super.fillFromCalc();
2506
- fillColorObject = new Color(fillColor, true);
2507
- fillGradient = false;
2508
- }
2509
-
2510
-
2511
-
2512
- //////////////////////////////////////////////////////////////
2513
-
2514
- // MATERIAL PROPERTIES
2515
-
2516
-
2517
- //public void ambient(int rgb)
2518
- //public void ambient(float gray)
2519
- //public void ambient(float x, float y, float z)
2520
- //protected void ambientFromCalc()
2521
- //public void specular(int rgb)
2522
- //public void specular(float gray)
2523
- //public void specular(float x, float y, float z)
2524
- //protected void specularFromCalc()
2525
- //public void shininess(float shine)
2526
- //public void emissive(int rgb)
2527
- //public void emissive(float gray)
2528
- //public void emissive(float x, float y, float z )
2529
- //protected void emissiveFromCalc()
2530
-
2531
-
2532
-
2533
- //////////////////////////////////////////////////////////////
2534
-
2535
- // LIGHTS
2536
-
2537
-
2538
- //public void lights()
2539
- //public void noLights()
2540
- //public void ambientLight(float red, float green, float blue)
2541
- //public void ambientLight(float red, float green, float blue,
2542
- // float x, float y, float z)
2543
- //public void directionalLight(float red, float green, float blue,
2544
- // float nx, float ny, float nz)
2545
- //public void pointLight(float red, float green, float blue,
2546
- // float x, float y, float z)
2547
- //public void spotLight(float red, float green, float blue,
2548
- // float x, float y, float z,
2549
- // float nx, float ny, float nz,
2550
- // float angle, float concentration)
2551
- //public void lightFalloff(float constant, float linear, float quadratic)
2552
- //public void lightSpecular(float x, float y, float z)
2553
- //protected void lightPosition(int num, float x, float y, float z)
2554
- //protected void lightDirection(int num, float x, float y, float z)
2555
-
2556
-
2557
-
2558
- //////////////////////////////////////////////////////////////
2559
-
2560
- // BACKGROUND
2561
-
2562
-
2563
- int[] clearPixels;
2564
-
2565
- protected void clearPixels(int color) {
2566
- // On a hi-res display, image may be larger than width/height
2567
- int imageWidth = image.getWidth(null);
2568
- int imageHeight = image.getHeight(null);
2569
-
2570
- // Create a small array that can be used to set the pixels several times.
2571
- // Using a single-pixel line of length 'width' is a tradeoff between
2572
- // speed (setting each pixel individually is too slow) and memory
2573
- // (an array for width*height would waste lots of memory if it stayed
2574
- // resident, and would terrify the gc if it were re-created on each trip
2575
- // to background().
2576
- // WritableRaster raster = ((BufferedImage) image).getRaster();
2577
- // WritableRaster raster = image.getRaster();
2578
- WritableRaster raster = getRaster();
2579
- if ((clearPixels == null) || (clearPixels.length < imageWidth)) {
2580
- clearPixels = new int[imageWidth];
2581
- }
2582
- Arrays.fill(clearPixels, 0, imageWidth, backgroundColor);
2583
- for (int i = 0; i < imageHeight; i++) {
2584
- raster.setDataElements(0, i, imageWidth, 1, clearPixels);
2585
- }
2586
- }
2587
-
2588
- // background() methods inherited from PGraphics, along with the
2589
- // PImage version of backgroundImpl(), since it just calls set().
2590
-
2591
-
2592
- //public void backgroundImpl(PImage image)
2593
-
2594
-
2595
- @Override
2596
- public void backgroundImpl() {
2597
- if (backgroundAlpha) {
2598
- clearPixels(backgroundColor);
2599
-
2600
- } else {
2601
- Color bgColor = new Color(backgroundColor);
2602
- // seems to fire an additional event that causes flickering,
2603
- // like an extra background erase on OS X
2604
- // if (canvas != null) {
2605
- // canvas.setBackground(bgColor);
2606
- // }
2607
- //new Exception().printStackTrace(System.out);
2608
- // in case people do transformations before background(),
2609
- // need to handle this with a push/reset/pop
2610
- Composite oldComposite = g2.getComposite();
2611
- g2.setComposite(defaultComposite);
2612
-
2613
- pushMatrix();
2614
- resetMatrix();
2615
- g2.setColor(bgColor); //, backgroundAlpha));
2616
- // g2.fillRect(0, 0, width, height);
2617
- // On a hi-res display, image may be larger than width/height
2618
- if (image != null) {
2619
- // image will be null in subclasses (i.e. PDF)
2620
- g2.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
2621
- } else {
2622
- // hope for the best if image is null
2623
- g2.fillRect(0, 0, width, height);
2624
- }
2625
- popMatrix();
2626
-
2627
- g2.setComposite(oldComposite);
2628
- }
2629
- }
2630
-
2631
-
2632
-
2633
- //////////////////////////////////////////////////////////////
2634
-
2635
- // COLOR MODE
2636
-
2637
- // All colorMode() variations are inherited from PGraphics.
2638
-
2639
-
2640
-
2641
- //////////////////////////////////////////////////////////////
2642
-
2643
- // COLOR CALC
2644
-
2645
- // colorCalc() and colorCalcARGB() inherited from PGraphics.
2646
-
2647
-
2648
-
2649
- //////////////////////////////////////////////////////////////
2650
-
2651
- // COLOR DATATYPE STUFFING
2652
-
2653
- // final color() variations inherited.
2654
-
2655
-
2656
-
2657
- //////////////////////////////////////////////////////////////
1682
+ font = font.deriveFont(map);
1683
+ }
1684
+ g2.setFont(font);
1685
+ textFont.setNative(font);
1686
+ fontObject = font;
2658
1687
 
2659
- // COLOR DATATYPE EXTRACTION
1688
+ /*
1689
+ Map<TextAttribute, ?> attrs = font.getAttributes();
1690
+ for (TextAttribute ta : attrs.keySet()) {
1691
+ System.out.println(ta + " -> " + attrs.get(ta));
1692
+ }
1693
+ */
1694
+ }
2660
1695
 
2661
- // final methods alpha, red, green, blue,
2662
- // hue, saturation, and brightness all inherited.
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
+ }
2663
1701
 
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
+ }
2664
1713
 
1714
+ Font font = (Font) textFont.getNative();
1715
+ // System.out.println(font);
1716
+ //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
1717
+ if (font != null) {
1718
+ // System.out.println("using charswidth for " + new String(buffer, start, stop-start));
1719
+ // maybe should use one of the newer/fancier functions for this?
1720
+ // int length = stop - start;
1721
+ // 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().
1726
+ // System.err.println("using native");
1727
+ // g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
1728
+ // RenderingHints.VALUE_FRACTIONALMETRICS_ON);
1729
+ // float m1 = metrics.charsWidth(buffer, start, length);
1730
+ // float m2 = (float) metrics.getStringBounds(buffer, start, stop, g2).getWidth();
1731
+ // TextLayout tl = new TextLayout(new String(buffer, start, length), font, g2.getFontRenderContext());
1732
+ // float m3 = (float) tl.getBounds().getWidth();
1733
+ // System.err.println(m1 + " " + m2 + " " + m3);
1734
+ ////// return m1;
1735
+ //// return m2;
1736
+ //// return metrics.charsWidth(buffer, start, length);
1737
+ // 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);
1742
+ }
2665
1743
 
2666
- //////////////////////////////////////////////////////////////
1744
+ // protected void beginTextScreenMode() {
1745
+ // loadPixels();
1746
+ // }
1747
+ // protected void endTextScreenMode() {
1748
+ // updatePixels();
1749
+ // }
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();
1761
+ // if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
1762
+ if (font != null) {
1763
+ /*
1764
+ // save the current setting for text smoothing. note that this is
1765
+ // different from the smooth() function, because the font smoothing
1766
+ // is controlled when the font is created, not now as it's drawn.
1767
+ // fixed a bug in 0116 that handled this incorrectly.
1768
+ Object textAntialias =
1769
+ g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
2667
1770
 
2668
- // COLOR DATATYPE INTERPOLATION
1771
+ // override the current text smoothing setting based on the font
1772
+ // (don't change the global smoothing settings)
1773
+ g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1774
+ textFont.smooth ?
1775
+ RenderingHints.VALUE_ANTIALIAS_ON :
1776
+ 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
+ }
2669
1784
 
2670
- // both lerpColor variants inherited.
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);
2671
1792
 
1793
+ g2.setColor(fillColorObject);
2672
1794
 
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
1799
+ // g2.drawString(new String(buffer, start, stop - start), Math.round(x), Math.round(y));
2673
1800
 
2674
- //////////////////////////////////////////////////////////////
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
1805
+ // java.awt.font.GlyphVector gv =
1806
+ // font.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop - start));
1807
+ // g2.drawGlyphVector(gv, x, y);
1808
+ }
2675
1809
 
2676
- // BEGIN/END RAW
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);
2677
1813
 
1814
+ } else { // otherwise just do the default
1815
+ super.textLineImpl(buffer, start, stop, x, y);
1816
+ }
1817
+ }
2678
1818
 
2679
- @Override
2680
- public void beginRaw(PGraphics recorderRaw) {
2681
- showMethodWarning("beginRaw");
2682
- }
1819
+ // /**
1820
+ // * Convenience method to get a legit FontMetrics object. Where possible,
1821
+ // * override this any renderer subclass so that you're not using what's
1822
+ // * returned by getDefaultToolkit() to get your metrics.
1823
+ // */
1824
+ // @SuppressWarnings("deprecation")
1825
+ // public FontMetrics getFontMetrics(Font font) { // ignore
1826
+ // Frame frame = parent.frame;
1827
+ // if (frame != null) {
1828
+ // return frame.getToolkit().getFontMetrics(font);
1829
+ // }
1830
+ // return Toolkit.getDefaultToolkit().getFontMetrics(font);
1831
+ // }
1832
+ //
1833
+ //
1834
+ // /**
1835
+ // * Convenience method to jump through some Java2D hoops and get an FRC.
1836
+ // */
1837
+ // public FontRenderContext getFontRenderContext(Font font) { // ignore
1838
+ // return getFontMetrics(font).getFontRenderContext();
1839
+ // }
2683
1840
 
1841
+ /*
1842
+ Toolkit toolkit;
2684
1843
 
2685
- @Override
2686
- public void endRaw() {
2687
- showMethodWarning("endRaw");
1844
+ @SuppressWarnings("deprecation")
1845
+ protected FontMetrics getFontMetrics(Font font) {
1846
+ if (toolkit == null) {
1847
+ try {
1848
+ Canvas canvas = (Canvas) surface.getNative();
1849
+ toolkit = canvas.getToolkit();
1850
+ } catch (Exception e) {
1851
+ // May error out if it's a PSurfaceNone or similar
1852
+ toolkit = Toolkit.getDefaultToolkit();
1853
+ }
1854
+ }
1855
+ return toolkit.getFontMetrics(font);
1856
+ //return (g2 != null) ? g2.getFontMetrics(font) : super.getFontMetrics(font);
2688
1857
  }
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++;
1869
+ }
2689
1870
 
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]);
1879
+ }
2690
1880
 
1881
+ //////////////////////////////////////////////////////////////
1882
+ // MATRIX TRANSFORMS
1883
+ @Override
1884
+ public void translate(float tx, float ty) {
1885
+ g2.translate(tx, ty);
1886
+ }
2691
1887
 
2692
- //////////////////////////////////////////////////////////////
1888
+ //public void translate(float tx, float ty, float tz)
1889
+ @Override
1890
+ public void rotate(float angle) {
1891
+ g2.rotate(angle);
1892
+ }
2693
1893
 
2694
- // WARNINGS and EXCEPTIONS
1894
+ @Override
1895
+ public void rotateX(float angle) {
1896
+ showDepthWarning("rotateX");
1897
+ }
2695
1898
 
2696
- // showWarning and showException inherited.
1899
+ @Override
1900
+ public void rotateY(float angle) {
1901
+ showDepthWarning("rotateY");
1902
+ }
2697
1903
 
1904
+ @Override
1905
+ public void rotateZ(float angle) {
1906
+ showDepthWarning("rotateZ");
1907
+ }
2698
1908
 
1909
+ @Override
1910
+ public void rotate(float angle, float vx, float vy, float vz) {
1911
+ showVariationWarning("rotate");
1912
+ }
2699
1913
 
2700
- //////////////////////////////////////////////////////////////
1914
+ @Override
1915
+ public void scale(float s) {
1916
+ g2.scale(s, s);
1917
+ }
2701
1918
 
2702
- // RENDERER SUPPORT QUERIES
1919
+ @Override
1920
+ public void scale(float sx, float sy) {
1921
+ g2.scale(sx, sy);
1922
+ }
2703
1923
 
1924
+ @Override
1925
+ public void scale(float sx, float sy, float sz) {
1926
+ showDepthWarningXYZ("scale");
1927
+ }
2704
1928
 
2705
- //public boolean displayable() // true
1929
+ @Override
1930
+ public void shearX(float angle) {
1931
+ g2.shear(Math.tan(angle), 0);
1932
+ }
2706
1933
 
1934
+ @Override
1935
+ public void shearY(float angle) {
1936
+ g2.shear(0, Math.tan(angle));
1937
+ }
2707
1938
 
2708
- //public boolean is2D() // true
1939
+ //////////////////////////////////////////////////////////////
1940
+ // MATRIX MORE
1941
+ @Override
1942
+ public void resetMatrix() {
1943
+ g2.setTransform(new AffineTransform());
1944
+ g2.scale(pixelDensity, pixelDensity);
1945
+ }
2709
1946
 
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
+ }
2710
1956
 
2711
- //public boolean is3D() // false
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
+ }
2712
1965
 
1966
+ //////////////////////////////////////////////////////////////
1967
+ // MATRIX GET/SET
1968
+ @Override
1969
+ public PMatrix getMatrix() {
1970
+ return getMatrix((PMatrix2D) null);
1971
+ }
2713
1972
 
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
+ }
1983
+
1984
+ @Override
1985
+ public PMatrix3D getMatrix(PMatrix3D target) {
1986
+ showVariationWarning("getMatrix");
1987
+ return target;
1988
+ }
1989
+
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
+
1998
+ @Override
1999
+ public void setMatrix(PMatrix3D source) {
2000
+ showVariationWarning("setMatrix");
2001
+ }
2002
+
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
+ }
2035
+
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
+ }
2041
+
2042
+ @Override
2043
+ public float screenX(float x, float y, float z) {
2044
+ showDepthWarningXYZ("screenX");
2045
+ return 0;
2046
+ }
2047
+
2048
+ @Override
2049
+ public float screenY(float x, float y, float z) {
2050
+ showDepthWarningXYZ("screenY");
2051
+ return 0;
2052
+ }
2053
+
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
+ }
2073
+
2074
+ @Override
2075
+ public void strokeJoin(int join) {
2076
+ super.strokeJoin(join);
2077
+ strokeImpl();
2078
+ }
2079
+
2080
+ @Override
2081
+ public void strokeWeight(float weight) {
2082
+ super.strokeWeight(weight);
2083
+ strokeImpl();
2084
+ }
2085
+
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
+ }
2714
2093
 
2715
- //////////////////////////////////////////////////////////////
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
+ }
2716
2100
 
2717
- // PIMAGE METHODS
2101
+ strokeObject = new BasicStroke(strokeWeight, cap, join);
2102
+ g2.setStroke(strokeObject);
2103
+ }
2104
+
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;
2113
+ }
2114
+
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
+ }
2124
+
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().
2184
+ // WritableRaster raster = ((BufferedImage) image).getRaster();
2185
+ // 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
+ }
2194
+ }
2718
2195
 
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);
2719
2203
 
2720
- // getImage, setCache, getCache, removeCache, isModified, setModified
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
2208
+ // if (canvas != null) {
2209
+ // canvas.setBackground(bgColor);
2210
+ // }
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));
2220
+ // 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();
2721
2230
 
2231
+ g2.setComposite(oldComposite);
2232
+ }
2233
+ }
2722
2234
 
2723
- protected WritableRaster getRaster() {
2724
- WritableRaster raster = null;
2725
- if (primaryGraphics) {
2726
- /*
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
+ }
2257
+
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
+ /*
2727
2278
  // 'offscreen' will probably be removed in the next release
2728
2279
  if (useOffscreen) {
2729
2280
  raster = offscreen.getRaster();
2730
2281
  } else*/ if (image instanceof VolatileImage) {
2731
- // when possible, we'll try VolatileImage
2732
- raster = ((VolatileImage) image).getSnapshot().getRaster();
2733
- }
2734
- }
2735
- if (raster == null) {
2736
- raster = ((BufferedImage) image).getRaster();
2737
- }
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
+ }
2738
2289
 
2739
- // On Raspberry Pi (and perhaps other platforms, the color buffer won't
2740
- // necessarily be the int array that we'd like. Need to convert it here.
2741
- // Not that this would probably mean getRaster() would need to work more
2742
- // like loadRaster/updateRaster because the pixels will need to be
2743
- // temporarily moved to (and later from) a buffer that's understood by
2744
- // the rest of the Processing source.
2745
- // https://github.com/processing/processing/issues/2010
2746
- if (raster.getTransferType() != DataBuffer.TYPE_INT) {
2747
- System.err.println("See https://github.com/processing/processing/issues/2010");
2748
- throw new RuntimeException("Pixel operations are not supported on this device.");
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;
2749
2302
  }
2750
- return raster;
2751
- }
2752
2303
 
2304
+ @Override
2305
+ public void loadPixels() {
2306
+ if (pixels == null || (pixels.length != pixelWidth * pixelHeight)) {
2307
+ pixels = new int[pixelWidth * pixelHeight];
2308
+ }
2753
2309
 
2754
- @Override
2755
- public void loadPixels() {
2756
- if (pixels == null || (pixels.length != pixelWidth*pixelHeight)) {
2757
- pixels = new int[pixelWidth * pixelHeight];
2758
- }
2759
-
2760
- WritableRaster raster = getRaster();
2761
- raster.getDataElements(0, 0, pixelWidth, pixelHeight, pixels);
2762
- if (raster.getNumBands() == 3) {
2763
- // Java won't set the high bits when RGB, returns 0 for alpha
2764
- // https://github.com/processing/processing/issues/2030
2765
- for (int i = 0; i < pixels.length; i++) {
2766
- pixels[i] = 0xff000000 | pixels[i];
2767
- }
2768
- }
2769
- //((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width);
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);
2770
2320
  // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2771
2321
  // WritableRaster raster = image.getRaster();
2772
- }
2773
-
2322
+ }
2774
2323
 
2775
2324
  // /**
2776
2325
  // * Update the pixels[] buffer to the PGraphics image.
@@ -2785,30 +2334,27 @@ public class PGraphicsJava2D extends PGraphics {
2785
2334
  //// WritableRaster raster = image.getRaster();
2786
2335
  // updatePixels(0, 0, width, height);
2787
2336
  // }
2788
-
2789
-
2790
- /**
2791
- * Update the pixels[] buffer to the PGraphics image.
2792
- * <P>
2793
- * Unlike in PImage, where updatePixels() only requests that the
2794
- * update happens, in PGraphicsJava2D, this will happen immediately.
2795
- */
2796
- @Override
2797
- public void updatePixels(int x, int y, int c, int d) {
2798
- //if ((x == 0) && (y == 0) && (c == width) && (d == height)) {
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)) {
2799
2346
  // System.err.format("%d %d %d %d .. w/h = %d %d .. pw/ph = %d %d %n", x, y, c, d, width, height, pixelWidth, pixelHeight);
2800
- if ((x != 0) || (y != 0) || (c != pixelWidth) || (d != pixelHeight)) {
2801
- // Show a warning message, but continue anyway.
2802
- showVariationWarning("updatePixels(x, y, w, h)");
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)");
2803
2350
  // new Exception().printStackTrace(System.out);
2804
- }
2351
+ }
2805
2352
  // updatePixels();
2806
- if (pixels != null) {
2807
- getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
2353
+ if (pixels != null) {
2354
+ getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
2355
+ }
2356
+ modified = true;
2808
2357
  }
2809
- modified = true;
2810
- }
2811
-
2812
2358
 
2813
2359
  // @Override
2814
2360
  // protected void updatePixelsImpl(int x, int y, int w, int h) {
@@ -2820,217 +2366,170 @@ public class PGraphicsJava2D extends PGraphics {
2820
2366
  // }
2821
2367
  // getRaster().setDataElements(0, 0, width, height, pixels);
2822
2368
  // }
2823
-
2824
-
2825
-
2826
- //////////////////////////////////////////////////////////////
2827
-
2828
- // GET/SET
2829
-
2830
-
2831
- static int getset[] = new int[1];
2832
-
2833
-
2834
- @Override
2835
- public int get(int x, int y) {
2836
- if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0;
2837
- //return ((BufferedImage) image).getRGB(x, y);
2369
+ //////////////////////////////////////////////////////////////
2370
+ // GET/SET
2371
+ static int getset[] = new int[1];
2372
+
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);
2838
2379
  // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2839
- WritableRaster raster = getRaster();
2840
- raster.getDataElements(x, y, getset);
2841
- if (raster.getNumBands() == 3) {
2842
- // https://github.com/processing/processing/issues/2030
2843
- return getset[0] | 0xff000000;
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];
2844
2387
  }
2845
- return getset[0];
2846
- }
2847
-
2848
-
2849
- //public PImage get(int x, int y, int w, int h)
2850
-
2851
2388
 
2852
- @Override
2853
- protected void getImpl(int sourceX, int sourceY,
2854
- int sourceWidth, int sourceHeight,
2855
- PImage target, int targetX, int targetY) {
2856
- // last parameter to getRGB() is the scan size of the *target* buffer
2857
- //((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w);
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);
2858
2396
  // WritableRaster raster =
2859
2397
  // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2860
- WritableRaster raster = getRaster();
2861
-
2862
- if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) {
2863
- raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
2864
- // https://github.com/processing/processing/issues/2030
2865
- if (raster.getNumBands() == 3) {
2866
- target.filter(OPAQUE);
2867
- }
2398
+ WritableRaster raster = getRaster();
2868
2399
 
2869
- } else {
2870
- // TODO optimize, incredibly inefficient to reallocate this much memory
2871
- int[] temp = new int[sourceWidth * sourceHeight];
2872
- raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, temp);
2873
-
2874
- // Copy the temporary output pixels over to the outgoing image
2875
- int sourceOffset = 0;
2876
- int targetOffset = targetY*target.pixelWidth + targetX;
2877
- for (int y = 0; y < sourceHeight; y++) {
2878
- if (raster.getNumBands() == 3) {
2879
- for (int i = 0; i < sourceWidth; i++) {
2880
- // Need to set the high bits for this feller
2400
+ if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) {
2401
+ raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
2881
2402
  // https://github.com/processing/processing/issues/2030
2882
- target.pixels[targetOffset + i] = 0xFF000000 | temp[sourceOffset + i];
2883
- }
2403
+ if (raster.getNumBands() == 3) {
2404
+ target.filter(OPAQUE);
2405
+ }
2406
+
2884
2407
  } else {
2885
- System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth);
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
+ }
2886
2428
  }
2887
- sourceOffset += sourceWidth;
2888
- targetOffset += target.pixelWidth;
2889
- }
2890
2429
  }
2891
- }
2892
2430
 
2893
-
2894
- @Override
2895
- public void set(int x, int y, int argb) {
2896
- if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) return;
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
+ }
2897
2436
  // ((BufferedImage) image).setRGB(x, y, argb);
2898
- getset[0] = argb;
2437
+ getset[0] = argb;
2899
2438
  // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2900
2439
  // WritableRaster raster = image.getRaster();
2901
- getRaster().setDataElements(x, y, getset);
2902
- }
2903
-
2904
-
2905
- //public void set(int x, int y, PImage img)
2906
-
2440
+ getRaster().setDataElements(x, y, getset);
2441
+ }
2907
2442
 
2908
- @Override
2909
- protected void setImpl(PImage sourceImage,
2910
- int sourceX, int sourceY,
2911
- int sourceWidth, int sourceHeight,
2912
- int targetX, int targetY) {
2913
- WritableRaster raster = getRaster();
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();
2914
2450
  // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2915
2451
 
2916
- if ((sourceX == 0) && (sourceY == 0) &&
2917
- (sourceWidth == sourceImage.pixelWidth) &&
2918
- (sourceHeight == sourceImage.pixelHeight)) {
2452
+ if ((sourceX == 0) && (sourceY == 0)
2453
+ && (sourceWidth == sourceImage.pixelWidth)
2454
+ && (sourceHeight == sourceImage.pixelHeight)) {
2919
2455
  // System.out.format("%d %d %dx%d %d%n", targetX, targetY,
2920
2456
  // sourceImage.width, sourceImage.height,
2921
2457
  // sourceImage.pixels.length);
2922
- raster.setDataElements(targetX, targetY,
2923
- sourceImage.pixelWidth, sourceImage.pixelHeight,
2924
- sourceImage.pixels);
2925
- } else {
2926
- // TODO optimize, incredibly inefficient to reallocate this much memory
2927
- PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight);
2928
- raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels);
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
+ }
2929
2466
  }
2930
- }
2931
-
2932
-
2933
-
2934
- //////////////////////////////////////////////////////////////
2935
2467
 
2936
- // MASK
2468
+ //////////////////////////////////////////////////////////////
2469
+ // MASK
2470
+ static final String MASK_WARNING
2471
+ = "mask() cannot be used on the main drawing surface";
2937
2472
 
2473
+ @Override
2474
+ public void mask(int[] alpha) {
2475
+ if (primaryGraphics) {
2476
+ showWarning(MASK_WARNING);
2938
2477
 
2939
- static final String MASK_WARNING =
2940
- "mask() cannot be used on the main drawing surface";
2941
-
2942
-
2943
- @Override
2944
- public void mask(int[] alpha) {
2945
- if (primaryGraphics) {
2946
- showWarning(MASK_WARNING);
2947
-
2948
- } else {
2949
- super.mask(alpha);
2478
+ } else {
2479
+ super.mask(alpha);
2480
+ }
2950
2481
  }
2951
- }
2952
2482
 
2483
+ @Override
2484
+ public void mask(PImage alpha) {
2485
+ if (primaryGraphics) {
2486
+ showWarning(MASK_WARNING);
2953
2487
 
2954
- @Override
2955
- public void mask(PImage alpha) {
2956
- if (primaryGraphics) {
2957
- showWarning(MASK_WARNING);
2958
-
2959
- } else {
2960
- super.mask(alpha);
2488
+ } else {
2489
+ super.mask(alpha);
2490
+ }
2961
2491
  }
2962
- }
2963
-
2964
-
2965
-
2966
- //////////////////////////////////////////////////////////////
2967
-
2968
- // FILTER
2969
-
2970
- // Because the PImage versions call loadPixels() and
2971
- // updatePixels(), no need to override anything here.
2972
-
2973
2492
 
2974
- //public void filter(int kind)
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);
2975
2506
 
2976
-
2977
- //public void filter(int kind, float param)
2978
-
2979
-
2980
-
2981
- //////////////////////////////////////////////////////////////
2982
-
2983
- // COPY
2984
-
2985
-
2986
- @Override
2987
- public void copy(int sx, int sy, int sw, int sh,
2988
- int dx, int dy, int dw, int dh) {
2989
- if ((sw != dw) || (sh != dh)) {
2990
- g2.drawImage(image, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
2991
-
2992
- } else {
2993
- dx = dx - sx; // java2d's "dx" is the delta, not dest
2994
- dy = dy - sy;
2995
- g2.copyArea(sx, sy, sw, sh, dx, dy);
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
+ }
2996
2512
  }
2997
- }
2998
-
2999
-
3000
- @Override
3001
- public void copy(PImage src,
3002
- int sx, int sy, int sw, int sh,
3003
- int dx, int dy, int dw, int dh) {
3004
- g2.drawImage((Image) src.getNative(),
3005
- dx, dy, dx + dw, dy + dh,
3006
- sx, sy, sx + sw, sy + sh, null);
3007
- }
3008
-
3009
-
3010
-
3011
- //////////////////////////////////////////////////////////////
3012
-
3013
- // BLEND
3014
2513
 
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
+ }
3015
2522
 
2523
+ //////////////////////////////////////////////////////////////
2524
+ // BLEND
3016
2525
  // static public int blendColor(int c1, int c2, int mode)
3017
-
3018
-
3019
2526
  // public void blend(int sx, int sy, int sw, int sh,
3020
2527
  // int dx, int dy, int dw, int dh, int mode)
3021
-
3022
-
3023
2528
  // public void blend(PImage src,
3024
2529
  // int sx, int sy, int sw, int sh,
3025
2530
  // int dx, int dy, int dw, int dh, int mode)
3026
-
3027
-
3028
-
3029
- //////////////////////////////////////////////////////////////
3030
-
3031
- // SAVE
3032
-
3033
-
2531
+ //////////////////////////////////////////////////////////////
2532
+ // SAVE
3034
2533
  // public void save(String filename) {
3035
2534
  // loadPixels();
3036
2535
  // super.save(filename);