propane 3.1.0.pre-java → 3.2.0-java

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