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
@@ -0,0 +1,377 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2015 The Processing Foundation
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License version 2.1 as published by the Free Software Foundation.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General
18
+ Public License along with this library; if not, write to the
19
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
+ Boston, MA 02111-1307 USA
21
+ */
22
+
23
+ package processing.awt;
24
+
25
+ import java.awt.Graphics2D;
26
+ import java.awt.Image;
27
+ import java.awt.RenderingHints;
28
+ import java.awt.Transparency;
29
+ import java.awt.image.BufferedImage;
30
+ import java.awt.image.DataBuffer;
31
+ import java.awt.image.DataBufferInt;
32
+ import java.awt.image.PixelGrabber;
33
+ import java.awt.image.WritableRaster;
34
+ import java.io.BufferedOutputStream;
35
+ import java.io.File;
36
+ import java.io.IOException;
37
+ import java.util.Iterator;
38
+
39
+ import javax.imageio.IIOImage;
40
+ import javax.imageio.ImageIO;
41
+ import javax.imageio.ImageTypeSpecifier;
42
+ import javax.imageio.ImageWriteParam;
43
+ import javax.imageio.ImageWriter;
44
+ import javax.imageio.metadata.IIOInvalidTreeException;
45
+ import javax.imageio.metadata.IIOMetadata;
46
+ import javax.imageio.metadata.IIOMetadataNode;
47
+
48
+ import processing.core.PApplet;
49
+ import processing.core.PImage;
50
+
51
+
52
+ public class PImageAWT extends PImage {
53
+
54
+ /**
55
+ * Construct a new PImage from a java.awt.Image. This constructor assumes
56
+ * that you've done the work of making sure a MediaTracker has been used
57
+ * to fully download the data and that the img is valid.
58
+ *
59
+ * @nowebref
60
+ * @param img assumes a MediaTracker has been used to fully download
61
+ * the data and the img is valid
62
+ */
63
+ public PImageAWT(Image img) {
64
+ format = RGB;
65
+ if (img instanceof BufferedImage) {
66
+ BufferedImage bi = (BufferedImage) img;
67
+ width = bi.getWidth();
68
+ height = bi.getHeight();
69
+ int type = bi.getType();
70
+ if (type == BufferedImage.TYPE_3BYTE_BGR ||
71
+ type == BufferedImage.TYPE_4BYTE_ABGR) {
72
+ pixels = new int[width * height];
73
+ bi.getRGB(0, 0, width, height, pixels, 0, width);
74
+ if (type == BufferedImage.TYPE_4BYTE_ABGR) {
75
+ format = ARGB;
76
+ } else {
77
+ opaque();
78
+ }
79
+ } else {
80
+ DataBuffer db = bi.getRaster().getDataBuffer();
81
+ if (db instanceof DataBufferInt) {
82
+ pixels = ((DataBufferInt) db).getData();
83
+ if (type == BufferedImage.TYPE_INT_ARGB) {
84
+ format = ARGB;
85
+ } else if (type == BufferedImage.TYPE_INT_RGB) {
86
+ opaque();
87
+ }
88
+ }
89
+ }
90
+ }
91
+ // Implements fall-through if not DataBufferInt above, or not a
92
+ // known type, or not DataBufferInt for the data itself.
93
+ if (pixels == null) { // go the old school Java 1.0 route
94
+ width = img.getWidth(null);
95
+ height = img.getHeight(null);
96
+ pixels = new int[width * height];
97
+ PixelGrabber pg =
98
+ new PixelGrabber(img, 0, 0, width, height, pixels, 0, width);
99
+ try {
100
+ pg.grabPixels();
101
+ } catch (InterruptedException e) { }
102
+ }
103
+ pixelDensity = 1;
104
+ pixelWidth = width;
105
+ pixelHeight = height;
106
+ }
107
+
108
+
109
+ /**
110
+ * Use the getNative() method instead, which allows library interfaces to be
111
+ * written in a cross-platform fashion for desktop, Android, and others.
112
+ * This is still included for PGraphics objects, which may need the image.
113
+ */
114
+ public Image getImage() { // ignore
115
+ return (Image) getNative();
116
+ }
117
+
118
+
119
+ /**
120
+ * Returns a native BufferedImage from this PImage.
121
+ */
122
+ @Override
123
+ public Object getNative() { // ignore
124
+ loadPixels();
125
+ int type = (format == RGB) ?
126
+ BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
127
+ BufferedImage image = new BufferedImage(pixelWidth, pixelHeight, type);
128
+ WritableRaster wr = image.getRaster();
129
+ wr.setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
130
+ return image;
131
+ }
132
+
133
+
134
+ @Override
135
+ public void resize(int w, int h) { // ignore
136
+ if (w <= 0 && h <= 0) {
137
+ throw new IllegalArgumentException("width or height must be > 0 for resize");
138
+ }
139
+
140
+ if (w == 0) { // Use height to determine relative size
141
+ float diff = (float) h / (float) height;
142
+ w = (int) (width * diff);
143
+ } else if (h == 0) { // Use the width to determine relative size
144
+ float diff = (float) w / (float) width;
145
+ h = (int) (height * diff);
146
+ }
147
+
148
+ BufferedImage img =
149
+ shrinkImage((BufferedImage) getNative(), w*pixelDensity, h*pixelDensity);
150
+
151
+ PImage temp = new PImageAWT(img);
152
+ this.pixelWidth = temp.width;
153
+ this.pixelHeight = temp.height;
154
+
155
+ // Get the resized pixel array
156
+ this.pixels = temp.pixels;
157
+
158
+ this.width = pixelWidth / pixelDensity;
159
+ this.height = pixelHeight / pixelDensity;
160
+
161
+ // Mark the pixels array as altered
162
+ updatePixels();
163
+ }
164
+
165
+
166
+ // Adapted from getFasterScaledInstance() method from page 111 of
167
+ // "Filthy Rich Clients" by Chet Haase and Romain Guy
168
+ // Additional modifications and simplifications have been added,
169
+ // plus a fix to deal with an infinite loop if images are expanded.
170
+ // http://code.google.com/p/processing/issues/detail?id=1463
171
+ static private BufferedImage shrinkImage(BufferedImage img,
172
+ int targetWidth, int targetHeight) {
173
+ int type = (img.getTransparency() == Transparency.OPAQUE) ?
174
+ BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
175
+ BufferedImage outgoing = img;
176
+ BufferedImage scratchImage = null;
177
+ Graphics2D g2 = null;
178
+ int prevW = outgoing.getWidth();
179
+ int prevH = outgoing.getHeight();
180
+ boolean isTranslucent = img.getTransparency() != Transparency.OPAQUE;
181
+
182
+ // Use multi-step technique: start with original size, then scale down in
183
+ // multiple passes with drawImage() until the target size is reached
184
+ int w = img.getWidth();
185
+ int h = img.getHeight();
186
+
187
+ do {
188
+ if (w > targetWidth) {
189
+ w /= 2;
190
+ // if this is the last step, do the exact size
191
+ if (w < targetWidth) {
192
+ w = targetWidth;
193
+ }
194
+ } else if (targetWidth >= w) {
195
+ w = targetWidth;
196
+ }
197
+ if (h > targetHeight) {
198
+ h /= 2;
199
+ if (h < targetHeight) {
200
+ h = targetHeight;
201
+ }
202
+ } else if (targetHeight >= h) {
203
+ h = targetHeight;
204
+ }
205
+ if (scratchImage == null || isTranslucent) {
206
+ // Use a single scratch buffer for all iterations and then copy
207
+ // to the final, correctly-sized image before returning
208
+ scratchImage = new BufferedImage(w, h, type);
209
+ g2 = scratchImage.createGraphics();
210
+ }
211
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
212
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
213
+ g2.drawImage(outgoing, 0, 0, w, h, 0, 0, prevW, prevH, null);
214
+ prevW = w;
215
+ prevH = h;
216
+ outgoing = scratchImage;
217
+ } while (w != targetWidth || h != targetHeight);
218
+ g2.dispose();
219
+
220
+
221
+ // If we used a scratch buffer that is larger than our target size,
222
+ // create an image of the right size and copy the results into it
223
+ if (targetWidth != outgoing.getWidth() ||
224
+ targetHeight != outgoing.getHeight()) {
225
+ scratchImage = new BufferedImage(targetWidth, targetHeight, type);
226
+ g2 = scratchImage.createGraphics();
227
+ g2.drawImage(outgoing, 0, 0, null);
228
+ g2.dispose();
229
+ outgoing = scratchImage;
230
+ }
231
+ return outgoing;
232
+ }
233
+
234
+
235
+ @Override
236
+ protected boolean saveImpl(String filename) {
237
+ if (saveImageFormats == null) {
238
+ saveImageFormats = javax.imageio.ImageIO.getWriterFormatNames();
239
+ }
240
+ try {
241
+ if (saveImageFormats != null) {
242
+ for (String saveImageFormat : saveImageFormats) {
243
+ if (filename.endsWith("." + saveImageFormat)) {
244
+ if (!saveImageIO(filename)) {
245
+ System.err.println("Error while saving image.");
246
+ return false;
247
+ }
248
+ return true;
249
+ }
250
+ }
251
+ }
252
+ } catch (IOException e) {
253
+ }
254
+ return false;
255
+ }
256
+
257
+
258
+ protected String[] saveImageFormats;
259
+
260
+
261
+ /**
262
+ * Use ImageIO functions from Java 1.4 and later to handle image save.
263
+ * Various formats are supported, typically jpeg, png, bmp, and wbmp.
264
+ * To get a list of the supported formats for writing, use: <BR>
265
+ * <TT>println(javax.imageio.ImageIO.getReaderFormatNames())</TT>
266
+ *
267
+ * @path The path to which the file should be written.
268
+ */
269
+ protected boolean saveImageIO(String path) throws IOException {
270
+ try {
271
+ int outputFormat = (format == ARGB) ?
272
+ BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
273
+
274
+ String extension =
275
+ path.substring(path.lastIndexOf('.') + 1).toLowerCase();
276
+
277
+ // JPEG and BMP images that have an alpha channel set get pretty unhappy.
278
+ // BMP just doesn't write, and JPEG writes it as a CMYK image.
279
+ // http://code.google.com/p/processing/issues/detail?id=415
280
+ if (extension.equals("bmp") || extension.equals("jpg") || extension.equals("jpeg")) {
281
+ outputFormat = BufferedImage.TYPE_INT_RGB;
282
+ }
283
+
284
+ BufferedImage bimage = new BufferedImage(pixelWidth, pixelHeight, outputFormat);
285
+ bimage.setRGB(0, 0, pixelWidth, pixelHeight, pixels, 0, pixelWidth);
286
+
287
+ File file = new File(path);
288
+
289
+ ImageWriter writer = null;
290
+ ImageWriteParam param = null;
291
+ IIOMetadata metadata = null;
292
+
293
+ if (extension.equals("jpg") || extension.equals("jpeg")) {
294
+ if ((writer = imageioWriter("jpeg")) != null) {
295
+ // Set JPEG quality to 90% with baseline optimization. Setting this
296
+ // to 1 was a huge jump (about triple the size), so this seems good.
297
+ // Oddly, a smaller file size than Photoshop at 90%, but I suppose
298
+ // it's a completely different algorithm.
299
+ param = writer.getDefaultWriteParam();
300
+ param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
301
+ param.setCompressionQuality(0.9f);
302
+ }
303
+ }
304
+
305
+ if (extension.equals("png")) {
306
+ if ((writer = imageioWriter("png")) != null) {
307
+ param = writer.getDefaultWriteParam();
308
+ if (false) {
309
+ metadata = imageioDPI(writer, param, 100);
310
+ }
311
+ }
312
+ }
313
+
314
+ if (writer != null) {
315
+ try (BufferedOutputStream output = new BufferedOutputStream(PApplet.createOutput(file))) {
316
+ writer.setOutput(ImageIO.createImageOutputStream(output));
317
+ // writer.write(null, new IIOImage(bimage, null, null), param);
318
+ writer.write(metadata, new IIOImage(bimage, null, metadata), param);
319
+ writer.dispose();
320
+
321
+ output.flush();
322
+ }
323
+ return true;
324
+ }
325
+ // If iter.hasNext() somehow fails up top, it falls through to here
326
+ return javax.imageio.ImageIO.write(bimage, extension, file);
327
+
328
+ } catch (IOException e) {
329
+ throw new IOException("image save failed.");
330
+ }
331
+ }
332
+
333
+
334
+ private ImageWriter imageioWriter(String extension) {
335
+ Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(extension);
336
+ if (iter.hasNext()) {
337
+ return iter.next();
338
+ }
339
+ return null;
340
+ }
341
+
342
+
343
+ private IIOMetadata imageioDPI(ImageWriter writer, ImageWriteParam param, double dpi) {
344
+ // http://stackoverflow.com/questions/321736/how-to-set-dpi-information-in-an-image
345
+ ImageTypeSpecifier typeSpecifier =
346
+ ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
347
+ IIOMetadata metadata =
348
+ writer.getDefaultImageMetadata(typeSpecifier, param);
349
+
350
+ if (!metadata.isReadOnly() && metadata.isStandardMetadataFormatSupported()) {
351
+ // for PNG, it's dots per millimeter
352
+ double dotsPerMilli = dpi / 25.4;
353
+
354
+ IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
355
+ horiz.setAttribute("value", Double.toString(dotsPerMilli));
356
+
357
+ IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
358
+ vert.setAttribute("value", Double.toString(dotsPerMilli));
359
+
360
+ IIOMetadataNode dim = new IIOMetadataNode("Dimension");
361
+ dim.appendChild(horiz);
362
+ dim.appendChild(vert);
363
+
364
+ IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
365
+ root.appendChild(dim);
366
+
367
+ try {
368
+ metadata.mergeTree("javax_imageio_1.0", root);
369
+ return metadata;
370
+
371
+ } catch (IIOInvalidTreeException e) {
372
+ System.err.println("Could not set the DPI of the output image");
373
+ }
374
+ }
375
+ return null;
376
+ }
377
+ }
@@ -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
 
@@ -16,7 +18,8 @@
16
18
  Public License along with this library; if not, write to the
17
19
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
20
  Boston, MA 02111-1307 USA
19
- */
21
+ */
22
+
20
23
  package processing.awt;
21
24
 
22
25
  import java.awt.Paint;
@@ -35,48 +38,50 @@ import processing.core.PGraphics;
35
38
  import processing.core.PShapeSVG;
36
39
  import processing.data.*;
37
40
 
41
+
38
42
  /**
39
- * Implements features for PShape that are specific to AWT and Java2D. At the
40
- * moment, this is gradients and java.awt.Paint handling.
43
+ * Implements features for PShape that are specific to AWT and Java2D.
44
+ * At the moment, this is gradients and java.awt.Paint handling.
41
45
  */
42
46
  public class PShapeJava2D extends PShapeSVG {
47
+ Paint strokeGradientPaint;
48
+ Paint fillGradientPaint;
43
49
 
44
- Paint strokeGradientPaint;
45
- Paint fillGradientPaint;
46
50
 
47
- public PShapeJava2D(XML svg) {
48
- super(svg);
49
- }
51
+ public PShapeJava2D(XML svg) {
52
+ super(svg);
53
+ }
50
54
 
51
- public PShapeJava2D(PShapeSVG parent, XML properties, boolean parseKids) {
52
- super(parent, properties, parseKids);
53
- }
54
55
 
55
- @Override
56
- protected void setParent(PShapeSVG parent) {
57
- super.setParent(parent);
56
+ public PShapeJava2D(PShapeSVG parent, XML properties, boolean parseKids) {
57
+ super(parent, properties, parseKids);
58
+ }
58
59
 
59
- if (parent instanceof PShapeJava2D) {
60
- PShapeJava2D pj = (PShapeJava2D) parent;
61
- fillGradientPaint = pj.fillGradientPaint;
62
- strokeGradientPaint = pj.strokeGradientPaint;
63
60
 
64
- } else { // parent is null or not Java2D
65
- fillGradientPaint = null;
66
- strokeGradientPaint = null;
67
- }
68
- }
61
+ @Override
62
+ protected void setParent(PShapeSVG parent) {
63
+ super.setParent(parent);
69
64
 
70
- /**
71
- * Factory method for subclasses.
72
- */
73
- @Override
74
- protected PShapeSVG createShape(PShapeSVG parent, XML properties, boolean parseKids) {
75
- return new PShapeJava2D(parent, properties, parseKids);
65
+ if (parent instanceof PShapeJava2D) {
66
+ PShapeJava2D pj = (PShapeJava2D) parent;
67
+ fillGradientPaint = pj.fillGradientPaint;
68
+ strokeGradientPaint = pj.strokeGradientPaint;
69
+
70
+ } else { // parent is null or not Java2D
71
+ fillGradientPaint = null;
72
+ strokeGradientPaint = null;
76
73
  }
74
+ }
75
+
76
+
77
+ /** Factory method for subclasses. */
78
+ @Override
79
+ protected PShapeSVG createShape(PShapeSVG parent, XML properties, boolean parseKids) {
80
+ return new PShapeJava2D(parent, properties, parseKids);
81
+ }
77
82
 
78
83
 
79
- /*
84
+ /*
80
85
  @Override
81
86
  public void setColor(String colorText, boolean isFill) {
82
87
  super.setColor(colorText, isFill);
@@ -88,239 +93,240 @@ public class PShapeJava2D extends PShapeSVG {
88
93
  strokeGradientPaint = calcGradientPaint(strokeGradient);
89
94
  }
90
95
  }
91
- */
92
- static class LinearGradientPaint implements Paint {
93
-
94
- float x1, y1, x2, y2;
95
- float[] offset;
96
- int[] color;
97
- int count;
98
- float opacity;
99
-
100
- public LinearGradientPaint(float x1, float y1, float x2, float y2,
101
- float[] offset, int[] color, int count,
102
- float opacity) {
103
- this.x1 = x1;
104
- this.y1 = y1;
105
- this.x2 = x2;
106
- this.y2 = y2;
107
- this.offset = offset;
108
- this.color = color;
109
- this.count = count;
110
- this.opacity = opacity;
111
- }
112
-
113
- public PaintContext createContext(ColorModel cm,
114
- Rectangle deviceBounds, Rectangle2D userBounds,
115
- AffineTransform xform, RenderingHints hints) {
116
- Point2D t1 = xform.transform(new Point2D.Float(x1, y1), null);
117
- Point2D t2 = xform.transform(new Point2D.Float(x2, y2), null);
118
- return new LinearGradientContext((float) t1.getX(), (float) t1.getY(),
119
- (float) t2.getX(), (float) t2.getY());
120
- }
121
-
122
- public int getTransparency() {
123
- return TRANSLUCENT; // why not.. rather than checking each color
124
- }
96
+ */
97
+
98
+
99
+ static class LinearGradientPaint implements Paint {
100
+ float x1, y1, x2, y2;
101
+ float[] offset;
102
+ int[] color;
103
+ int count;
104
+ float opacity;
105
+
106
+ public LinearGradientPaint(float x1, float y1, float x2, float y2,
107
+ float[] offset, int[] color, int count,
108
+ float opacity) {
109
+ this.x1 = x1;
110
+ this.y1 = y1;
111
+ this.x2 = x2;
112
+ this.y2 = y2;
113
+ this.offset = offset;
114
+ this.color = color;
115
+ this.count = count;
116
+ this.opacity = opacity;
117
+ }
125
118
 
126
- public class LinearGradientContext implements PaintContext {
119
+ @Override
120
+ public PaintContext createContext(ColorModel cm,
121
+ Rectangle deviceBounds, Rectangle2D userBounds,
122
+ AffineTransform xform, RenderingHints hints) {
123
+ Point2D t1 = xform.transform(new Point2D.Float(x1, y1), null);
124
+ Point2D t2 = xform.transform(new Point2D.Float(x2, y2), null);
125
+ return new LinearGradientContext((float) t1.getX(), (float) t1.getY(),
126
+ (float) t2.getX(), (float) t2.getY());
127
+ }
127
128
 
128
- int ACCURACY = 2;
129
- float tx1, ty1, tx2, ty2;
129
+ @Override
130
+ public int getTransparency() {
131
+ return TRANSLUCENT; // why not.. rather than checking each color
132
+ }
130
133
 
131
- public LinearGradientContext(float tx1, float ty1, float tx2, float ty2) {
132
- this.tx1 = tx1;
133
- this.ty1 = ty1;
134
- this.tx2 = tx2;
135
- this.ty2 = ty2;
136
- }
134
+ public class LinearGradientContext implements PaintContext {
135
+ int ACCURACY = 2;
136
+ float tx1, ty1, tx2, ty2;
137
+
138
+ public LinearGradientContext(float tx1, float ty1, float tx2, float ty2) {
139
+ this.tx1 = tx1;
140
+ this.ty1 = ty1;
141
+ this.tx2 = tx2;
142
+ this.ty2 = ty2;
143
+ }
144
+
145
+ @Override
146
+ public void dispose() { }
147
+
148
+ @Override
149
+ public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
150
+
151
+ @Override
152
+ public Raster getRaster(int x, int y, int w, int h) {
153
+ WritableRaster raster =
154
+ getColorModel().createCompatibleWritableRaster(w, h);
155
+
156
+ int[] data = new int[w * h * 4];
157
+
158
+ // make normalized version of base vector
159
+ float nx = tx2 - tx1;
160
+ float ny = ty2 - ty1;
161
+ float len = (float) Math.sqrt(nx*nx + ny*ny);
162
+ if (len != 0) {
163
+ nx /= len;
164
+ ny /= len;
165
+ }
137
166
 
138
- public void dispose() {
167
+ int span = (int) PApplet.dist(tx1, ty1, tx2, ty2) * ACCURACY;
168
+ if (span <= 0) {
169
+ //System.err.println("span is too small");
170
+ // annoying edge case where the gradient isn't legit
171
+ int index = 0;
172
+ for (int j = 0; j < h; j++) {
173
+ for (int i = 0; i < w; i++) {
174
+ data[index++] = 0;
175
+ data[index++] = 0;
176
+ data[index++] = 0;
177
+ data[index++] = 255;
139
178
  }
179
+ }
140
180
 
141
- public ColorModel getColorModel() {
142
- return ColorModel.getRGBdefault();
181
+ } else {
182
+ int[][] interp = new int[span][4];
183
+ int prev = 0;
184
+ for (int i = 1; i < count; i++) {
185
+ int c0 = color[i-1];
186
+ int c1 = color[i];
187
+ int last = (int) (offset[i] * (span-1));
188
+ //System.out.println("last is " + last);
189
+ for (int j = prev; j <= last; j++) {
190
+ float btwn = PApplet.norm(j, prev, last);
191
+ interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
192
+ interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
193
+ interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
194
+ interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
195
+ //System.out.println(j + " " + interp[j][0] + " " + interp[j][1] + " " + interp[j][2]);
143
196
  }
144
-
145
- public Raster getRaster(int x, int y, int w, int h) {
146
- WritableRaster raster
147
- = getColorModel().createCompatibleWritableRaster(w, h);
148
-
149
- int[] data = new int[w * h * 4];
150
-
151
- // make normalized version of base vector
152
- float nx = tx2 - tx1;
153
- float ny = ty2 - ty1;
154
- float len = (float) Math.sqrt(nx * nx + ny * ny);
155
- if (len != 0) {
156
- nx /= len;
157
- ny /= len;
158
- }
159
-
160
- int span = (int) PApplet.dist(tx1, ty1, tx2, ty2) * ACCURACY;
161
- if (span <= 0) {
162
- //System.err.println("span is too small");
163
- // annoying edge case where the gradient isn't legit
164
- int index = 0;
165
- for (int j = 0; j < h; j++) {
166
- for (int i = 0; i < w; i++) {
167
- data[index++] = 0;
168
- data[index++] = 0;
169
- data[index++] = 0;
170
- data[index++] = 255;
171
- }
172
- }
173
-
174
- } else {
175
- int[][] interp = new int[span][4];
176
- int prev = 0;
177
- for (int i = 1; i < count; i++) {
178
- int c0 = color[i - 1];
179
- int c1 = color[i];
180
- int last = (int) (offset[i] * (span - 1));
181
- //System.out.println("last is " + last);
182
- for (int j = prev; j <= last; j++) {
183
- float btwn = PApplet.norm(j, prev, last);
184
- interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
185
- interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
186
- interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
187
- interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
188
- //System.out.println(j + " " + interp[j][0] + " " + interp[j][1] + " " + interp[j][2]);
189
- }
190
- prev = last;
191
- }
192
-
193
- int index = 0;
194
- for (int j = 0; j < h; j++) {
195
- for (int i = 0; i < w; i++) {
196
- //float distance = 0; //PApplet.dist(cx, cy, x + i, y + j);
197
- //int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
198
- float px = (x + i) - tx1;
199
- float py = (y + j) - ty1;
200
- // distance up the line is the dot product of the normalized
201
- // vector of the gradient start/stop by the point being tested
202
- int which = (int) ((px * nx + py * ny) * ACCURACY);
203
- if (which < 0) {
204
- which = 0;
205
- }
206
- if (which > interp.length - 1) {
207
- which = interp.length - 1;
208
- }
209
- //if (which > 138) System.out.println("grabbing " + which);
210
-
211
- data[index++] = interp[which][0];
212
- data[index++] = interp[which][1];
213
- data[index++] = interp[which][2];
214
- data[index++] = interp[which][3];
215
- }
216
- }
217
- }
218
- raster.setPixels(0, 0, w, h, data);
219
-
220
- return raster;
197
+ prev = last;
198
+ }
199
+
200
+ int index = 0;
201
+ for (int j = 0; j < h; j++) {
202
+ for (int i = 0; i < w; i++) {
203
+ //float distance = 0; //PApplet.dist(cx, cy, x + i, y + j);
204
+ //int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
205
+ float px = (x + i) - tx1;
206
+ float py = (y + j) - ty1;
207
+ // distance up the line is the dot product of the normalized
208
+ // vector of the gradient start/stop by the point being tested
209
+ int which = (int) ((px*nx + py*ny) * ACCURACY);
210
+ if (which < 0) which = 0;
211
+ if (which > interp.length-1) which = interp.length-1;
212
+ //if (which > 138) System.out.println("grabbing " + which);
213
+
214
+ data[index++] = interp[which][0];
215
+ data[index++] = interp[which][1];
216
+ data[index++] = interp[which][2];
217
+ data[index++] = interp[which][3];
221
218
  }
219
+ }
222
220
  }
223
- }
224
-
225
- static class RadialGradientPaint implements Paint {
226
-
227
- float cx, cy, radius;
228
- float[] offset;
229
- int[] color;
230
- int count;
231
- float opacity;
232
-
233
- public RadialGradientPaint(float cx, float cy, float radius,
234
- float[] offset, int[] color, int count,
235
- float opacity) {
236
- this.cx = cx;
237
- this.cy = cy;
238
- this.radius = radius;
239
- this.offset = offset;
240
- this.color = color;
241
- this.count = count;
242
- this.opacity = opacity;
243
- }
221
+ raster.setPixels(0, 0, w, h, data);
244
222
 
245
- public PaintContext createContext(ColorModel cm,
246
- Rectangle deviceBounds, Rectangle2D userBounds,
247
- AffineTransform xform, RenderingHints hints) {
248
- return new RadialGradientContext();
249
- }
223
+ return raster;
224
+ }
225
+ }
226
+ }
250
227
 
251
- public int getTransparency() {
252
- return TRANSLUCENT;
253
- }
254
228
 
255
- public class RadialGradientContext implements PaintContext {
229
+ static class RadialGradientPaint implements Paint {
230
+ float cx, cy, radius;
231
+ float[] offset;
232
+ int[] color;
233
+ int count;
234
+ float opacity;
235
+
236
+ public RadialGradientPaint(float cx, float cy, float radius,
237
+ float[] offset, int[] color, int count,
238
+ float opacity) {
239
+ this.cx = cx;
240
+ this.cy = cy;
241
+ this.radius = radius;
242
+ this.offset = offset;
243
+ this.color = color;
244
+ this.count = count;
245
+ this.opacity = opacity;
246
+ }
256
247
 
257
- int ACCURACY = 5;
248
+ @Override
249
+ public PaintContext createContext(ColorModel cm,
250
+ Rectangle deviceBounds, Rectangle2D userBounds,
251
+ AffineTransform xform, RenderingHints hints) {
252
+ return new RadialGradientContext();
253
+ }
258
254
 
259
- public void dispose() {
260
- }
255
+ @Override
256
+ public int getTransparency() {
257
+ return TRANSLUCENT;
258
+ }
261
259
 
262
- public ColorModel getColorModel() {
263
- return ColorModel.getRGBdefault();
264
- }
260
+ public class RadialGradientContext implements PaintContext {
261
+ int ACCURACY = 5;
262
+
263
+ @Override
264
+ public void dispose() {}
265
+
266
+ @Override
267
+ public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
268
+
269
+ @Override
270
+ public Raster getRaster(int x, int y, int w, int h) {
271
+ WritableRaster raster =
272
+ getColorModel().createCompatibleWritableRaster(w, h);
273
+
274
+ int span = (int) radius * ACCURACY;
275
+ int[][] interp = new int[span][4];
276
+ int prev = 0;
277
+ for (int i = 1; i < count; i++) {
278
+ int c0 = color[i-1];
279
+ int c1 = color[i];
280
+ int last = (int) (offset[i] * (span - 1));
281
+ for (int j = prev; j <= last; j++) {
282
+ float btwn = PApplet.norm(j, prev, last);
283
+ interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
284
+ interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
285
+ interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
286
+ interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
287
+ }
288
+ prev = last;
289
+ }
265
290
 
266
- public Raster getRaster(int x, int y, int w, int h) {
267
- WritableRaster raster
268
- = getColorModel().createCompatibleWritableRaster(w, h);
269
-
270
- int span = (int) radius * ACCURACY;
271
- int[][] interp = new int[span][4];
272
- int prev = 0;
273
- for (int i = 1; i < count; i++) {
274
- int c0 = color[i - 1];
275
- int c1 = color[i];
276
- int last = (int) (offset[i] * (span - 1));
277
- for (int j = prev; j <= last; j++) {
278
- float btwn = PApplet.norm(j, prev, last);
279
- interp[j][0] = (int) PApplet.lerp((c0 >> 16) & 0xff, (c1 >> 16) & 0xff, btwn);
280
- interp[j][1] = (int) PApplet.lerp((c0 >> 8) & 0xff, (c1 >> 8) & 0xff, btwn);
281
- interp[j][2] = (int) PApplet.lerp(c0 & 0xff, c1 & 0xff, btwn);
282
- interp[j][3] = (int) (PApplet.lerp((c0 >> 24) & 0xff, (c1 >> 24) & 0xff, btwn) * opacity);
283
- }
284
- prev = last;
285
- }
286
-
287
- int[] data = new int[w * h * 4];
288
- int index = 0;
289
- for (int j = 0; j < h; j++) {
290
- for (int i = 0; i < w; i++) {
291
- float distance = PApplet.dist(cx, cy, x + i, y + j);
292
- int which = PApplet.min((int) (distance * ACCURACY), interp.length - 1);
293
-
294
- data[index++] = interp[which][0];
295
- data[index++] = interp[which][1];
296
- data[index++] = interp[which][2];
297
- data[index++] = interp[which][3];
298
- }
299
- }
300
- raster.setPixels(0, 0, w, h, data);
301
-
302
- return raster;
303
- }
291
+ int[] data = new int[w * h * 4];
292
+ int index = 0;
293
+ for (int j = 0; j < h; j++) {
294
+ for (int i = 0; i < w; i++) {
295
+ float distance = PApplet.dist(cx, cy, x + i, y + j);
296
+ int which = PApplet.min((int) (distance * ACCURACY), interp.length-1);
297
+
298
+ data[index++] = interp[which][0];
299
+ data[index++] = interp[which][1];
300
+ data[index++] = interp[which][2];
301
+ data[index++] = interp[which][3];
302
+ }
304
303
  }
304
+ raster.setPixels(0, 0, w, h, data);
305
+
306
+ return raster;
307
+ }
305
308
  }
309
+ }
306
310
 
307
- protected Paint calcGradientPaint(Gradient gradient) {
308
- if (gradient instanceof LinearGradient) {
311
+
312
+ protected Paint calcGradientPaint(Gradient gradient) {
313
+ if (gradient instanceof LinearGradient) {
309
314
  // System.out.println("creating linear gradient");
310
- LinearGradient grad = (LinearGradient) gradient;
311
- return new LinearGradientPaint(grad.x1, grad.y1, grad.x2, grad.y2,
312
- grad.offset, grad.color, grad.count,
313
- opacity);
315
+ LinearGradient grad = (LinearGradient) gradient;
316
+ return new LinearGradientPaint(grad.x1, grad.y1, grad.x2, grad.y2,
317
+ grad.offset, grad.color, grad.count,
318
+ opacity);
314
319
 
315
- } else if (gradient instanceof RadialGradient) {
320
+ } else if (gradient instanceof RadialGradient) {
316
321
  // System.out.println("creating radial gradient");
317
- RadialGradient grad = (RadialGradient) gradient;
318
- return new RadialGradientPaint(grad.cx, grad.cy, grad.r,
319
- grad.offset, grad.color, grad.count,
320
- opacity);
321
- }
322
- return null;
322
+ RadialGradient grad = (RadialGradient) gradient;
323
+ return new RadialGradientPaint(grad.cx, grad.cy, grad.r,
324
+ grad.offset, grad.color, grad.count,
325
+ opacity);
323
326
  }
327
+ return null;
328
+ }
329
+
324
330
 
325
331
  // protected Paint calcGradientPaint(Gradient gradient,
326
332
  // float x1, float y1, float x2, float y2) {
@@ -332,6 +338,8 @@ public class PShapeJava2D extends PShapeSVG {
332
338
  // }
333
339
  // throw new RuntimeException("Not a linear gradient.");
334
340
  // }
341
+
342
+
335
343
  // protected Paint calcGradientPaint(Gradient gradient,
336
344
  // float cx, float cy, float r) {
337
345
  // if (gradient instanceof RadialGradient) {
@@ -342,34 +350,38 @@ public class PShapeJava2D extends PShapeSVG {
342
350
  // }
343
351
  // throw new RuntimeException("Not a radial gradient.");
344
352
  // }
345
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
346
- @Override
347
- protected void styles(PGraphics g) {
348
- super.styles(g);
349
353
 
350
- //if (g instanceof PGraphicsJava2D) {
351
- PGraphicsJava2D p2d = (PGraphicsJava2D) g;
352
354
 
353
- if (strokeGradient != null) {
354
- p2d.strokeGradient = true;
355
- if (strokeGradientPaint == null) {
356
- strokeGradientPaint = calcGradientPaint(strokeGradient);
357
- }
358
- p2d.strokeGradientObject = strokeGradientPaint;
359
- } else {
360
- // need to shut off, in case parent object has a gradient applied
361
- //p2d.strokeGradient = false;
362
- }
363
- if (fillGradient != null) {
364
- p2d.fillGradient = true;
365
- if (fillGradientPaint == null) {
366
- fillGradientPaint = calcGradientPaint(fillGradient);
367
- }
368
- p2d.fillGradientObject = fillGradientPaint;
369
- } else {
370
- // need to shut off, in case parent object has a gradient applied
371
- //p2d.fillGradient = false;
372
- }
373
- //}
355
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
356
+
357
+
358
+ @Override
359
+ protected void styles(PGraphics g) {
360
+ super.styles(g);
361
+
362
+ //if (g instanceof PGraphicsJava2D) {
363
+ PGraphicsJava2D p2d = (PGraphicsJava2D) g;
364
+
365
+ if (strokeGradient != null) {
366
+ p2d.strokeGradient = true;
367
+ if (strokeGradientPaint == null) {
368
+ strokeGradientPaint = calcGradientPaint(strokeGradient);
369
+ }
370
+ p2d.strokeGradientObject = strokeGradientPaint;
371
+ } else {
372
+ // need to shut off, in case parent object has a gradient applied
373
+ //p2d.strokeGradient = false;
374
+ }
375
+ if (fillGradient != null) {
376
+ p2d.fillGradient = true;
377
+ if (fillGradientPaint == null) {
378
+ fillGradientPaint = calcGradientPaint(fillGradient);
379
+ }
380
+ p2d.fillGradientObject = fillGradientPaint;
381
+ } else {
382
+ // need to shut off, in case parent object has a gradient applied
383
+ //p2d.fillGradient = false;
374
384
  }
375
- }
385
+ //}
386
+ }
387
+ }