propane 3.3.1-java → 3.6.0-java

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