propane 3.10.0-java → 3.11.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  3. data/CHANGELOG.md +2 -0
  4. data/README.md +7 -7
  5. data/lib/propane/app.rb +2 -5
  6. data/lib/propane/helper_methods.rb +6 -6
  7. data/lib/propane/version.rb +1 -1
  8. data/lib/{propane-3.10.0.jar → propane-3.11.0.jar} +0 -0
  9. data/pom.rb +6 -6
  10. data/pom.xml +6 -6
  11. data/propane.gemspec +3 -3
  12. data/src/main/java/monkstone/noise/OpenSimplex2F.java +838 -737
  13. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +8 -13
  14. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +14 -28
  15. data/src/main/java/processing/awt/PImageAWT.java +6 -4
  16. data/src/main/java/processing/core/PApplet.java +71 -59
  17. data/src/main/java/processing/core/PImage.java +14 -14
  18. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13 -13
  19. data/src/main/java/processing/opengl/PShader.java +1 -6
  20. data/src/main/java/processing/opengl/PSurfaceJOGL.java +6 -6
  21. data/{lib/java/processing/opengl → src/main/resources}/cursors/arrow.png +0 -0
  22. data/{lib/java/processing/opengl → src/main/resources}/cursors/cross.png +0 -0
  23. data/{lib/java/processing/opengl → src/main/resources}/cursors/hand.png +0 -0
  24. data/{lib/java/processing/opengl → src/main/resources}/cursors/license.txt +0 -0
  25. data/{lib/java/processing/opengl → src/main/resources}/cursors/move.png +0 -0
  26. data/{lib/java/processing/opengl → src/main/resources}/cursors/text.png +0 -0
  27. data/{lib/java/processing/opengl → src/main/resources}/cursors/wait.png +0 -0
  28. data/{lib/java/processing/opengl → src/main/resources}/shaders/ColorFrag.glsl +0 -0
  29. data/{lib/java/processing/opengl → src/main/resources}/shaders/ColorVert.glsl +0 -0
  30. data/{lib/java/processing/opengl → src/main/resources}/shaders/LightFrag.glsl +0 -0
  31. data/{lib/java/processing/opengl → src/main/resources}/shaders/LightVert.glsl +0 -0
  32. data/{lib/java/processing/opengl → src/main/resources}/shaders/LineFrag.glsl +0 -0
  33. data/{lib/java/processing/opengl → src/main/resources}/shaders/LineVert.glsl +0 -0
  34. data/{lib/java/processing/opengl → src/main/resources}/shaders/MaskFrag.glsl +0 -0
  35. data/{lib/java/processing/opengl → src/main/resources}/shaders/PointFrag.glsl +0 -0
  36. data/{lib/java/processing/opengl → src/main/resources}/shaders/PointVert.glsl +0 -0
  37. data/{lib/java/processing/opengl → src/main/resources}/shaders/TexFrag.glsl +0 -0
  38. data/{lib/java/processing/opengl → src/main/resources}/shaders/TexLightFrag.glsl +0 -0
  39. data/{lib/java/processing/opengl → src/main/resources}/shaders/TexLightVert.glsl +0 -0
  40. data/{lib/java/processing/opengl → src/main/resources}/shaders/TexVert.glsl +0 -0
  41. data/test/test_helper.rb +1 -0
  42. data/vendors/Rakefile +1 -1
  43. metadata +29 -155
  44. data/lib/java/japplemenubar/JAppleMenuBar.java +0 -88
  45. data/lib/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  46. data/lib/java/monkstone/ColorUtil.java +0 -127
  47. data/lib/java/monkstone/MathToolModule.java +0 -287
  48. data/lib/java/monkstone/PropaneLibrary.java +0 -46
  49. data/lib/java/monkstone/core/LibraryProxy.java +0 -136
  50. data/lib/java/monkstone/fastmath/DegLutTables.java +0 -111
  51. data/lib/java/monkstone/fastmath/Deglut.java +0 -71
  52. data/lib/java/monkstone/fastmath/package-info.java +0 -6
  53. data/lib/java/monkstone/filechooser/Chooser.java +0 -39
  54. data/lib/java/monkstone/noise/FastTerrain.java +0 -874
  55. data/lib/java/monkstone/noise/Noise.java +0 -90
  56. data/lib/java/monkstone/noise/NoiseGenerator.java +0 -75
  57. data/lib/java/monkstone/noise/NoiseMode.java +0 -28
  58. data/lib/java/monkstone/noise/OpenSimplex2F.java +0 -881
  59. data/lib/java/monkstone/noise/OpenSimplex2S.java +0 -1106
  60. data/lib/java/monkstone/noise/SmoothTerrain.java +0 -1099
  61. data/lib/java/monkstone/slider/CustomHorizontalSlider.java +0 -164
  62. data/lib/java/monkstone/slider/CustomVerticalSlider.java +0 -178
  63. data/lib/java/monkstone/slider/SimpleHorizontalSlider.java +0 -145
  64. data/lib/java/monkstone/slider/SimpleSlider.java +0 -166
  65. data/lib/java/monkstone/slider/SimpleVerticalSlider.java +0 -157
  66. data/lib/java/monkstone/slider/Slider.java +0 -61
  67. data/lib/java/monkstone/slider/SliderBar.java +0 -245
  68. data/lib/java/monkstone/slider/SliderGroup.java +0 -56
  69. data/lib/java/monkstone/slider/WheelHandler.java +0 -35
  70. data/lib/java/monkstone/vecmath/GfxRender.java +0 -86
  71. data/lib/java/monkstone/vecmath/JRender.java +0 -56
  72. data/lib/java/monkstone/vecmath/ShapeRender.java +0 -87
  73. data/lib/java/monkstone/vecmath/package-info.java +0 -20
  74. data/lib/java/monkstone/vecmath/vec2/Vec2.java +0 -802
  75. data/lib/java/monkstone/vecmath/vec2/package-info.java +0 -6
  76. data/lib/java/monkstone/vecmath/vec3/Vec3.java +0 -727
  77. data/lib/java/monkstone/vecmath/vec3/package-info.java +0 -6
  78. data/lib/java/monkstone/videoevent/CaptureEvent.java +0 -27
  79. data/lib/java/monkstone/videoevent/MovieEvent.java +0 -32
  80. data/lib/java/monkstone/videoevent/package-info.java +0 -20
  81. data/lib/java/processing/awt/PGraphicsJava2D.java +0 -3040
  82. data/lib/java/processing/awt/PImageAWT.java +0 -377
  83. data/lib/java/processing/awt/PShapeJava2D.java +0 -387
  84. data/lib/java/processing/awt/PSurfaceAWT.java +0 -1581
  85. data/lib/java/processing/awt/ShimAWT.java +0 -581
  86. data/lib/java/processing/core/PApplet.java +0 -15156
  87. data/lib/java/processing/core/PConstants.java +0 -523
  88. data/lib/java/processing/core/PFont.java +0 -1126
  89. data/lib/java/processing/core/PGraphics.java +0 -8600
  90. data/lib/java/processing/core/PImage.java +0 -3377
  91. data/lib/java/processing/core/PMatrix.java +0 -208
  92. data/lib/java/processing/core/PMatrix2D.java +0 -562
  93. data/lib/java/processing/core/PMatrix3D.java +0 -890
  94. data/lib/java/processing/core/PShape.java +0 -3561
  95. data/lib/java/processing/core/PShapeOBJ.java +0 -483
  96. data/lib/java/processing/core/PShapeSVG.java +0 -2016
  97. data/lib/java/processing/core/PStyle.java +0 -63
  98. data/lib/java/processing/core/PSurface.java +0 -198
  99. data/lib/java/processing/core/PSurfaceNone.java +0 -431
  100. data/lib/java/processing/core/PVector.java +0 -1066
  101. data/lib/java/processing/core/ThinkDifferent.java +0 -115
  102. data/lib/java/processing/data/DoubleDict.java +0 -850
  103. data/lib/java/processing/data/DoubleList.java +0 -928
  104. data/lib/java/processing/data/FloatDict.java +0 -847
  105. data/lib/java/processing/data/FloatList.java +0 -936
  106. data/lib/java/processing/data/IntDict.java +0 -807
  107. data/lib/java/processing/data/IntList.java +0 -936
  108. data/lib/java/processing/data/JSONArray.java +0 -1260
  109. data/lib/java/processing/data/JSONObject.java +0 -2282
  110. data/lib/java/processing/data/JSONTokener.java +0 -435
  111. data/lib/java/processing/data/LongDict.java +0 -802
  112. data/lib/java/processing/data/LongList.java +0 -937
  113. data/lib/java/processing/data/Sort.java +0 -46
  114. data/lib/java/processing/data/StringDict.java +0 -613
  115. data/lib/java/processing/data/StringList.java +0 -800
  116. data/lib/java/processing/data/Table.java +0 -4936
  117. data/lib/java/processing/data/TableRow.java +0 -198
  118. data/lib/java/processing/data/XML.java +0 -1156
  119. data/lib/java/processing/dxf/RawDXF.java +0 -404
  120. data/lib/java/processing/event/Event.java +0 -125
  121. data/lib/java/processing/event/KeyEvent.java +0 -70
  122. data/lib/java/processing/event/MouseEvent.java +0 -114
  123. data/lib/java/processing/event/TouchEvent.java +0 -57
  124. data/lib/java/processing/javafx/PGraphicsFX2D.java +0 -32
  125. data/lib/java/processing/javafx/PSurfaceFX.java +0 -173
  126. data/lib/java/processing/net/Client.java +0 -744
  127. data/lib/java/processing/net/Server.java +0 -388
  128. data/lib/java/processing/opengl/FontTexture.java +0 -378
  129. data/lib/java/processing/opengl/FrameBuffer.java +0 -513
  130. data/lib/java/processing/opengl/LinePath.java +0 -627
  131. data/lib/java/processing/opengl/LineStroker.java +0 -681
  132. data/lib/java/processing/opengl/PGL.java +0 -3483
  133. data/lib/java/processing/opengl/PGraphics2D.java +0 -615
  134. data/lib/java/processing/opengl/PGraphics3D.java +0 -281
  135. data/lib/java/processing/opengl/PGraphicsOpenGL.java +0 -13753
  136. data/lib/java/processing/opengl/PJOGL.java +0 -2008
  137. data/lib/java/processing/opengl/PShader.java +0 -1484
  138. data/lib/java/processing/opengl/PShapeOpenGL.java +0 -5269
  139. data/lib/java/processing/opengl/PSurfaceJOGL.java +0 -1385
  140. data/lib/java/processing/opengl/Texture.java +0 -1696
  141. data/lib/java/processing/opengl/VertexBuffer.java +0 -88
  142. data/lib/java/processing/pdf/PGraphicsPDF.java +0 -581
  143. data/lib/java/processing/svg/PGraphicsSVG.java +0 -378
  144. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  145. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  146. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  147. data/src/main/java/processing/opengl/cursors/license.txt +0 -27
  148. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  149. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  150. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  151. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +0 -32
  152. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +0 -34
  153. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +0 -33
  154. data/src/main/java/processing/opengl/shaders/LightVert.glsl +0 -151
  155. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +0 -32
  156. data/src/main/java/processing/opengl/shaders/LineVert.glsl +0 -100
  157. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +0 -40
  158. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +0 -32
  159. data/src/main/java/processing/opengl/shaders/PointVert.glsl +0 -56
  160. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +0 -37
  161. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +0 -37
  162. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +0 -157
  163. data/src/main/java/processing/opengl/shaders/TexVert.glsl +0 -38
@@ -1,3040 +0,0 @@
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) 2013-15 The Processing Foundation
7
- Copyright (c) 2005-13 Ben Fry and Casey Reas
8
-
9
- This library is free software; you can redistribute it and/or
10
- modify it under the terms of the GNU Lesser General Public
11
- License as published by the Free Software Foundation; either
12
- version 2.1 of the License, or (at your option) any later version.
13
-
14
- This library is distributed in the hope that it will be useful,
15
- but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
- Lesser General Public License for more details.
18
-
19
- You should have received a copy of the GNU Lesser General
20
- Public License along with this library; if not, write to the
21
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
- Boston, MA 02111-1307 USA
23
- */
24
-
25
- package processing.awt;
26
-
27
- import java.awt.*;
28
- import java.awt.font.TextAttribute;
29
- import java.awt.geom.*;
30
- import java.awt.image.*;
31
- import java.util.Arrays;
32
- import java.util.HashMap;
33
- import java.util.Map;
34
-
35
- import processing.core.*;
36
-
37
-
38
- /**
39
- * Subclass for PGraphics that implements the graphics API using Java2D.
40
- * <p>
41
- * To get access to the Java 2D "Graphics2D" object for the default
42
- * renderer, use:
43
- * <PRE>
44
- * Graphics2D g2 = (Graphics2D) g.getNative();
45
- * </PRE>
46
- * This will let you do Graphics2D calls directly, but is not supported
47
- * in any way shape or form. Which just means "have fun, but don't complain
48
- * if it breaks."
49
- * <p>
50
- * Advanced <a href="http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html">debugging notes</a> for Java2D.
51
- */
52
- public class PGraphicsJava2D extends PGraphics {
53
- //// BufferStrategy strategy;
54
- //// BufferedImage bimage;
55
- //// VolatileImage vimage;
56
- // Canvas canvas;
57
- //// boolean useCanvas = true;
58
- // boolean useCanvas = false;
59
- //// boolean useRetina = true;
60
- //// boolean useOffscreen = true; // ~40fps
61
- // boolean useOffscreen = false;
62
-
63
- public Graphics2D g2;
64
- // protected BufferedImage offscreen;
65
-
66
- Composite defaultComposite;
67
-
68
- GeneralPath gpath;
69
-
70
- // path for contours so gpath can be closed
71
- GeneralPath auxPath;
72
-
73
- boolean openContour;
74
-
75
- /// break the shape at the next vertex (next vertex() call is a moveto())
76
- boolean breakShape;
77
-
78
- /// coordinates for internal curve calculation
79
- float[] curveCoordX;
80
- float[] curveCoordY;
81
- float[] curveDrawX;
82
- float[] curveDrawY;
83
-
84
- int transformCount;
85
- AffineTransform[] transformStack =
86
- new AffineTransform[MATRIX_STACK_DEPTH];
87
- double[] transform = new double[6];
88
-
89
- Line2D.Float line = new Line2D.Float();
90
- Ellipse2D.Float ellipse = new Ellipse2D.Float();
91
- Rectangle2D.Float rect = new Rectangle2D.Float();
92
- Arc2D.Float arc = new Arc2D.Float();
93
-
94
- protected Color tintColorObject;
95
-
96
- protected Color fillColorObject;
97
- public boolean fillGradient;
98
- public Paint fillGradientObject;
99
-
100
- protected Stroke strokeObject;
101
- protected Color strokeColorObject;
102
- public boolean strokeGradient;
103
- public Paint strokeGradientObject;
104
-
105
- Font fontObject;
106
-
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)
124
-
125
-
126
- // /**
127
- // * Called in response to a resize event, handles setting the
128
- // * new width and height internally, as well as re-allocating
129
- // * the pixel buffer for the new size.
130
- // *
131
- // * Note that this will nuke any cameraMode() settings.
132
- // */
133
- // @Override
134
- // public void setSize(int iwidth, int iheight) { // ignore
135
- // width = iwidth;
136
- // height = iheight;
137
- //
138
- // allocate();
139
- // reapplySettings();
140
- // }
141
-
142
-
143
- // @Override
144
- // protected void allocate() {
145
- // //surface.initImage(this, width, height);
146
- // surface.initImage(this);
147
- // }
148
-
149
-
150
- /*
151
- @Override
152
- protected void allocate() {
153
- // Tried this with RGB instead of ARGB for the primarySurface version,
154
- // but didn't see any performance difference (OS X 10.6, Java 6u24).
155
- // For 0196, also attempted RGB instead of ARGB, but that causes
156
- // strange things to happen with blending.
157
- // image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
158
- if (primarySurface) {
159
- if (useCanvas) {
160
- if (canvas != null) {
161
- parent.removeListeners(canvas);
162
- parent.remove(canvas);
163
- }
164
- canvas = new Canvas();
165
- canvas.setIgnoreRepaint(true);
166
-
167
- // parent.setLayout(new BorderLayout());
168
- // parent.add(canvas, BorderLayout.CENTER);
169
- parent.add(canvas);
170
- // canvas.validate();
171
- // parent.doLayout();
172
-
173
- if (canvas.getWidth() != width || canvas.getHeight() != height) {
174
- PApplet.debug("PGraphicsJava2D comp size being set to " + width + "x" + height);
175
- canvas.setSize(width, height);
176
- } else {
177
- PApplet.debug("PGraphicsJava2D comp size already " + width + "x" + height);
178
- }
179
-
180
- parent.addListeners(canvas);
181
- // canvas.createBufferStrategy(1);
182
- // g2 = (Graphics2D) canvas.getGraphics();
183
-
184
- } else {
185
- parent.updateListeners(parent); // in case they're already there
186
-
187
- // using a compatible image here doesn't seem to provide any performance boost
188
-
189
- if (useOffscreen) {
190
- // Needs to be RGB otherwise there's a major performance hit [0204]
191
- // http://code.google.com/p/processing/issues/detail?id=729
192
- image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
193
- // GraphicsConfiguration gc = parent.getGraphicsConfiguration();
194
- // image = gc.createCompatibleImage(width, height);
195
- offscreen = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
196
- // offscreen = gc.createCompatibleImage(width, height);
197
- g2 = (Graphics2D) offscreen.getGraphics();
198
-
199
- } else {
200
- // System.out.println("hopefully faster " + width + " " + height);
201
- // new Exception().printStackTrace(System.out);
202
-
203
- GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
204
- // If not realized (off-screen, i.e the Color Selector Tool),
205
- // gc will be null.
206
- if (gc == null) {
207
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
208
- gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
209
- }
210
-
211
- image = gc.createCompatibleImage(width, height);
212
- g2 = (Graphics2D) image.getGraphics();
213
- }
214
- }
215
- } else { // not the primary surface
216
- // Since this buffer's offscreen anyway, no need for the extra offscreen
217
- // buffer. However, unlike the primary surface, this feller needs to be
218
- // ARGB so that blending ("alpha" compositing) will work properly.
219
- image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
220
- g2 = (Graphics2D) image.getGraphics();
221
- }
222
- */
223
-
224
- /*
225
- if (primarySurface) {
226
- Canvas canvas = ((PSurfaceAWT) surface).canvas;
227
-
228
- GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
229
- // If not realized (off-screen, i.e the Color Selector Tool),
230
- // gc will be null.
231
- if (gc == null) {
232
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
233
- gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
234
- }
235
-
236
- image = gc.createCompatibleImage(width, height);
237
- g2 = (Graphics2D) image.getGraphics();
238
-
239
- } else {
240
-
241
- }
242
- g2 = (Graphics2D) image.getGraphics();
243
- }
244
- */
245
-
246
-
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
-
278
-
279
- // @Override
280
- // public boolean canDraw() {
281
- // return true;
282
- // }
283
-
284
-
285
- // @Override
286
- // public void requestDraw() {
287
- //// EventQueue.invokeLater(new Runnable() {
288
- //// public void run() {
289
- // parent.handleDraw();
290
- //// }
291
- //// });
292
- // }
293
-
294
-
295
- // Graphics2D g2old;
296
-
297
- public Graphics2D checkImage() {
298
- if (image == null ||
299
- ((BufferedImage) image).getWidth() != width*pixelDensity ||
300
- ((BufferedImage) image).getHeight() != height*pixelDensity) {
301
- // ((VolatileImage) image).getWidth() != width ||
302
- // ((VolatileImage) image).getHeight() != height) {
303
- // image = new BufferedImage(width * pixelFactor, height * pixelFactor
304
- // format == RGB ? BufferedImage.TYPE_INT_ARGB);
305
-
306
- // Commenting this out, because we are not drawing directly to the screen [jv 2018-06-01]
307
- //
308
- // GraphicsConfiguration gc = null;
309
- // if (surface != null) {
310
- // Component comp = null; //surface.getComponent();
311
- // if (comp == null) {
312
- //// System.out.println("component null, but parent.frame is " + parent.frame);
313
- // comp = parent.frame;
314
- // }
315
- // if (comp != null) {
316
- // gc = comp.getGraphicsConfiguration();
317
- // }
318
- // }
319
- // // If not realized (off-screen, i.e the Color Selector Tool), gc will be null.
320
- // if (gc == null) {
321
- // //System.err.println("GraphicsConfiguration null in initImage()");
322
- // GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
323
- // gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
324
- // }
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;
331
- // System.out.println("re-creating image");
332
-
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);
341
- }
342
- return (Graphics2D) image.getGraphics();
343
- }
344
-
345
-
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
- /*
367
- // NOTE: Calling image.getGraphics() will create a new Graphics context,
368
- // even if it's for the same image that's already had a context created.
369
- // Seems like a speed/memory issue, and also requires that all smoothing,
370
- // stroke, font and other props be reset. Can't find a good answer about
371
- // whether getGraphics() and dispose() on each frame is 1) better practice
372
- // and 2) minimal overhead, however. Instinct suggests #1 may be true,
373
- // but #2 seems a problem.
374
- if (primarySurface && !useOffscreen) {
375
- GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
376
- if (false) {
377
- if (image == null || ((VolatileImage) image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
378
- image = gc.createCompatibleVolatileImage(width, height);
379
- g2 = (Graphics2D) image.getGraphics();
380
- reapplySettings = true;
381
- }
382
- } else {
383
- if (image == null) {
384
- image = gc.createCompatibleImage(width, height);
385
- PApplet.debug("created new image, type is " + image);
386
- g2 = (Graphics2D) image.getGraphics();
387
- reapplySettings = true;
388
- }
389
- }
390
- }
391
-
392
- if (useCanvas && primarySurface) {
393
- if (parent.frameCount == 0) {
394
- canvas.createBufferStrategy(2);
395
- strategy = canvas.getBufferStrategy();
396
- PApplet.debug("PGraphicsJava2D.beginDraw() strategy is " + strategy);
397
- BufferCapabilities caps = strategy.getCapabilities();
398
- caps = strategy.getCapabilities();
399
- PApplet.debug("PGraphicsJava2D.beginDraw() caps are " +
400
- " flipping: " + caps.isPageFlipping() +
401
- " front/back accel: " + caps.getFrontBufferCapabilities().isAccelerated() + " " +
402
- "/" + caps.getBackBufferCapabilities().isAccelerated());
403
- }
404
- GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
405
-
406
- if (bimage == null ||
407
- bimage.getWidth() != width ||
408
- bimage.getHeight() != height) {
409
- PApplet.debug("PGraphicsJava2D creating new image");
410
- bimage = gc.createCompatibleImage(width, height);
411
- // image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
412
- g2 = bimage.createGraphics();
413
- defaultComposite = g2.getComposite();
414
- reapplySettings = true;
415
- }
416
- }
417
- */
418
-
419
- checkSettings();
420
- resetMatrix(); // reset model matrix
421
- vertexCount = 0;
422
- }
423
-
424
-
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);
459
- // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
460
- // RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
461
- // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
462
- // RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
463
-
464
- // g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
465
- // RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
466
- }
467
- }
468
-
469
-
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
- /*
478
- //if (canvas != null) {
479
- if (useCanvas) {
480
- //System.out.println(canvas);
481
-
482
- // alternate version
483
- //canvas.repaint(); // ?? what to do for swapping buffers
484
-
485
- // System.out.println("endDraw() frameCount is " + parent.frameCount);
486
- // if (parent.frameCount != 0) {
487
- redraw();
488
- // }
489
-
490
- } else if (useOffscreen) {
491
- // don't copy the pixels/data elements of the buffered image directly,
492
- // since it'll disable the nice speedy pipeline stuff, sending all drawing
493
- // into a world of suck that's rough 6 trillion times slower.
494
- synchronized (image) {
495
- //System.out.println("inside j2d sync");
496
- image.getGraphics().drawImage(offscreen, 0, 0, null);
497
- }
498
-
499
- } else {
500
- // changed to not dispose and get on each frame,
501
- // otherwise a new Graphics context is used on each frame
502
- // g2.dispose();
503
- // System.out.println("not doing anything special in endDraw()");
504
- }
505
- */
506
- } else {
507
- // TODO this is probably overkill for most tasks...
508
- loadPixels();
509
- }
510
-
511
- // // Marking as modified, and then calling updatePixels() in
512
- // // the super class, which just sets the mx1, my1, mx2, my2
513
- // // coordinates of the modified area. This avoids doing the
514
- // // full copy of the pixels to the surface in this.updatePixels().
515
- // setModified();
516
- // super.updatePixels();
517
-
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();
521
-
522
- g2.dispose();
523
- }
524
-
525
-
526
- /*
527
- private void redraw() {
528
- // only need this check if the validate() call will use redraw()
529
- // if (strategy == null) return;
530
- do {
531
- PApplet.debug("PGraphicsJava2D.redraw() top of outer do { } block");
532
- do {
533
- PApplet.debug("PGraphicsJava2D.redraw() top of inner do { } block");
534
- PApplet.debug("strategy is " + strategy);
535
- Graphics bsg = strategy.getDrawGraphics();
536
- // if (vimage != null) {
537
- // bsg.drawImage(vimage, 0, 0, null);
538
- // } else {
539
- bsg.drawImage(bimage, 0, 0, null);
540
- // if (parent.frameCount == 0) {
541
- // try {
542
- // ImageIO.write(image, "jpg", new java.io.File("/Users/fry/Desktop/buff.jpg"));
543
- // } catch (IOException e) {
544
- // e.printStackTrace();
545
- // }
546
- // }
547
- // }
548
- bsg.dispose();
549
-
550
- // the strategy version
551
- // g2.dispose();
552
- // if (!strategy.contentsLost()) {
553
- // if (parent.frameCount != 0) {
554
- // Toolkit.getDefaultToolkit().sync();
555
- // }
556
- // } else {
557
- // System.out.println("XXXXX strategy contents lost");
558
- // }
559
- // }
560
- // }
561
- } while (strategy.contentsRestored());
562
-
563
- PApplet.debug("PGraphicsJava2D.redraw() showing strategy");
564
- strategy.show();
565
-
566
- } while (strategy.contentsLost());
567
- PApplet.debug("PGraphicsJava2D.redraw() out of do { } block");
568
- }
569
- */
570
-
571
-
572
-
573
- //////////////////////////////////////////////////////////////
574
-
575
- // SETTINGS
576
-
577
-
578
- //protected void checkSettings()
579
-
580
-
581
- @Override
582
- protected void defaultSettings() {
583
- // if (!useCanvas) {
584
- // // Papered over another threading issue...
585
- // // See if this comes back now that the other issue is fixed.
586
- //// while (g2 == null) {
587
- //// try {
588
- //// System.out.println("sleeping until g2 is available");
589
- //// Thread.sleep(5);
590
- //// } catch (InterruptedException e) { }
591
- //// }
592
- defaultComposite = g2.getComposite();
593
- // }
594
- super.defaultSettings();
595
- }
596
-
597
-
598
- //protected void reapplySettings()
599
-
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);
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
-
643
-
644
- // @Override
645
- // public PShape createShape(PShape source) {
646
- // return PShapeOpenGL.createShape2D(this, source);
647
- // }
648
-
649
-
650
- /*
651
- protected PShape createShapeImpl(PGraphicsJava2D pg, int type) {
652
- PShape shape = null;
653
- if (type == PConstants.GROUP) {
654
- shape = new PShape(pg, PConstants.GROUP);
655
- } else if (type == PShape.PATH) {
656
- shape = new PShape(pg, PShape.PATH);
657
- } else if (type == PShape.GEOMETRY) {
658
- shape = new PShape(pg, PShape.GEOMETRY);
659
- }
660
- // defaults to false, don't assign it and make complexity for overrides
661
- //shape.set3D(false);
662
- return shape;
663
- }
664
- */
665
-
666
-
667
- /*
668
- static protected PShape createShapeImpl(PGraphicsJava2D pg,
669
- int kind, float... p) {
670
- PShape shape = null;
671
- int len = p.length;
672
-
673
- if (kind == POINT) {
674
- if (len != 2) {
675
- showWarning("Wrong number of parameters");
676
- return null;
677
- }
678
- shape = new PShape(pg, PShape.PRIMITIVE);
679
- shape.setKind(POINT);
680
- } else if (kind == LINE) {
681
- if (len != 4) {
682
- showWarning("Wrong number of parameters");
683
- return null;
684
- }
685
- shape = new PShape(pg, PShape.PRIMITIVE);
686
- shape.setKind(LINE);
687
- } else if (kind == TRIANGLE) {
688
- if (len != 6) {
689
- showWarning("Wrong number of parameters");
690
- return null;
691
- }
692
- shape = new PShape(pg, PShape.PRIMITIVE);
693
- shape.setKind(TRIANGLE);
694
- } else if (kind == QUAD) {
695
- if (len != 8) {
696
- showWarning("Wrong number of parameters");
697
- return null;
698
- }
699
- shape = new PShape(pg, PShape.PRIMITIVE);
700
- shape.setKind(QUAD);
701
- } else if (kind == RECT) {
702
- if (len != 4 && len != 5 && len != 8 && len != 9) {
703
- showWarning("Wrong number of parameters");
704
- return null;
705
- }
706
- shape = new PShape(pg, PShape.PRIMITIVE);
707
- shape.setKind(RECT);
708
- } else if (kind == ELLIPSE) {
709
- if (len != 4 && len != 5) {
710
- showWarning("Wrong number of parameters");
711
- return null;
712
- }
713
- shape = new PShape(pg, PShape.PRIMITIVE);
714
- shape.setKind(ELLIPSE);
715
- } else if (kind == ARC) {
716
- if (len != 6 && len != 7) {
717
- showWarning("Wrong number of parameters");
718
- return null;
719
- }
720
- shape = new PShape(pg, PShape.PRIMITIVE);
721
- shape.setKind(ARC);
722
- } else if (kind == BOX) {
723
- showWarning("Primitive not supported in 2D");
724
- } else if (kind == SPHERE) {
725
- showWarning("Primitive not supported in 2D");
726
- } else {
727
- showWarning("Unrecognized primitive type");
728
- }
729
-
730
- if (shape != null) {
731
- shape.setParams(p);
732
- }
733
-
734
- // defaults to false, don't assign it and make complexity for overrides
735
- //shape.set3D(false);
736
-
737
- return shape;
738
- }
739
- */
740
-
741
-
742
-
743
- //////////////////////////////////////////////////////////////
744
-
745
- // SHAPES
746
-
747
-
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
- }
763
-
764
-
765
- //public boolean edge(boolean e)
766
-
767
-
768
- //public void normal(float nx, float ny, float nz) {
769
-
770
-
771
- //public void textureMode(int mode)
772
-
773
-
774
- @Override
775
- public void texture(PImage image) {
776
- showMethodWarning("texture");
777
- }
778
-
779
-
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;
876
-
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;
888
- }
889
- }
890
-
891
-
892
- @Override
893
- public void vertex(float x, float y, float z) {
894
- showDepthWarningXYZ("vertex");
895
- }
896
-
897
- @Override
898
- public void vertex(float[] v) {
899
- vertex(v[X], v[Y]);
900
- }
901
-
902
-
903
- @Override
904
- public void vertex(float x, float y, float u, float v) {
905
- showVariationWarning("vertex(x, y, u, v)");
906
- }
907
-
908
-
909
- @Override
910
- public void vertex(float x, float y, float z, float u, float v) {
911
- showDepthWarningXYZ("vertex");
912
- }
913
-
914
-
915
- @Override
916
- public void beginContour() {
917
- if (openContour) {
918
- PGraphics.showWarning("Already called beginContour()");
919
- return;
920
- }
921
-
922
- // draw contours to auxiliary path so main path can be closed later
923
- GeneralPath contourPath = auxPath;
924
- auxPath = gpath;
925
- gpath = contourPath;
926
-
927
- if (contourPath != null) { // first contour does not break
928
- breakShape = true;
929
- }
930
-
931
- openContour = true;
932
- }
933
-
934
-
935
- @Override
936
- public void endContour() {
937
- if (!openContour) {
938
- PGraphics.showWarning("Need to call beginContour() first");
939
- return;
940
- }
941
-
942
- // close this contour
943
- if (gpath != null) gpath.closePath();
944
-
945
- // switch back to main path
946
- GeneralPath contourPath = gpath;
947
- gpath = auxPath;
948
- auxPath = contourPath;
949
-
950
- openContour = false;
951
- }
952
-
953
-
954
- @Override
955
- public void endShape(int mode) {
956
- if (openContour) { // correct automagically, notify user
957
- endContour();
958
- PGraphics.showWarning("Missing endContour() before endShape()");
959
- }
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);
967
- }
968
- drawShape(gpath);
969
- }
970
- }
971
- shape = 0;
972
- }
973
-
974
- //////////////////////////////////////////////////////////////
975
-
976
- // CLIPPING
977
-
978
-
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
- }
983
-
984
-
985
- @Override
986
- public void noClip() {
987
- g2.setClip(null);
988
- }
989
-
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) {
1281
- // start += 360;
1282
- // stop += 360;
1283
- // }
1284
- // if (start > stop) {
1285
- // float temp = start;
1286
- // start = stop;
1287
- // stop = temp;
1288
- // }
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
- }
1324
-
1325
-
1326
-
1327
- //////////////////////////////////////////////////////////////
1328
-
1329
- // JAVA2D SHAPE/PATH HANDLING
1330
-
1331
-
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);
1339
- }
1340
- }
1341
-
1342
-
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);
1350
- }
1351
- }
1352
-
1353
-
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);
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
-
1479
-
1480
- // //////////////////////////////////////////////////////////////
1481
- //
1482
- // // SMOOTH
1483
- //
1484
- //
1485
- // @Override
1486
- // public void smooth() {
1487
- // smooth = true;
1488
- //
1489
- // if (quality == 0) {
1490
- // quality = 4; // change back to bicubic
1491
- // }
1492
- //
1493
- // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1494
- // RenderingHints.VALUE_ANTIALIAS_ON);
1495
- //
1496
- // g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
1497
- // quality == 4 ?
1498
- // RenderingHints.VALUE_INTERPOLATION_BICUBIC :
1499
- // RenderingHints.VALUE_INTERPOLATION_BILINEAR);
1500
- //
1501
- // // http://docs.oracle.com/javase/tutorial/2d/text/renderinghints.html
1502
- // // Oracle Java text anti-aliasing on OS X looks like s*t compared to the
1503
- // // text rendering with Apple's old Java 6. Below, several attempts to fix:
1504
- // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1505
- // RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
1506
- // // Turns out this is the one that actually makes things work.
1507
- // // Kerning is still screwed up, however.
1508
- // g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
1509
- // RenderingHints.VALUE_FRACTIONALMETRICS_ON);
1510
- //// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1511
- //// RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
1512
- //// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1513
- //// RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
1514
- //
1515
- //// g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
1516
- //// RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
1517
- //
1518
- // }
1519
- //
1520
- //
1521
- // @Override
1522
- // public void smooth(int quality) {
1523
- // this.quality = quality;
1524
- // if (quality == 0) {
1525
- // noSmooth();
1526
- // } else {
1527
- // smooth();
1528
- // }
1529
- // }
1530
- //
1531
- //
1532
- // @Override
1533
- // public void noSmooth() {
1534
- // smooth = false;
1535
- // quality = 0; // https://github.com/processing/processing/issues/3113
1536
- // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1537
- // RenderingHints.VALUE_ANTIALIAS_OFF);
1538
- // g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
1539
- // RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
1540
- // g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1541
- // RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
1542
- // }
1543
-
1544
-
1545
-
1546
- //////////////////////////////////////////////////////////////
1547
-
1548
- // IMAGE
1549
-
1550
-
1551
- //public void imageMode(int mode)
1552
-
1553
-
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);
1638
- // System.out.println(System.currentTimeMillis() - t);
1639
- //
1640
- // if (oldComp != null) {
1641
- // g2.setComposite(oldComp);
1642
- // }
1643
- }
1644
-
1645
-
1646
- static class ImageCache {
1647
- boolean tinted;
1648
- int tintedColor;
1649
- int[] tintedTemp; // one row of tinted pixels
1650
- BufferedImage image;
1651
- // BufferedImage compat;
1652
-
1653
- // public ImageCache(PImage source) {
1654
- //// this.source = source;
1655
- // // even if RGB, set the image type to ARGB, because the
1656
- // // image may have an alpha value for its tint().
1657
- //// int type = BufferedImage.TYPE_INT_ARGB;
1658
- // //System.out.println("making new buffered image");
1659
- //// image = new BufferedImage(source.width, source.height, type);
1660
- // }
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
- }
1677
- // boolean wrongType = (image != null) && (image.getType() != bufferType);
1678
- // if ((image == null) || wrongType) {
1679
- // image = new BufferedImage(source.width, source.height, bufferType);
1680
- // }
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
- }
1688
-
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;
1695
- // System.out.println("tint color is " + a2);
1696
- // System.out.println("source.pixels[0] alpha is " + (source.pixels[0] >>> 24));
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?
1724
- // float[] scales = { tintR, tintG, tintB };
1725
- // float[] offsets = new float[3];
1726
- // RescaleOp op = new RescaleOp(scales, offsets, null);
1727
- // op.filter(image, image);
1728
-
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...
1784
- // float[] scales = { tintR, tintG, tintB, tintA };
1785
- // float[] offsets = new float[4];
1786
- // RescaleOp op = new RescaleOp(scales, offsets, null);
1787
- // op.filter(image, image);
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;
1804
-
1805
- // GraphicsConfiguration gc = parent.getGraphicsConfiguration();
1806
- // compat = gc.createCompatibleImage(image.getWidth(),
1807
- // image.getHeight(),
1808
- // Transparency.TRANSLUCENT);
1809
- //
1810
- // Graphics2D g = compat.createGraphics();
1811
- // g.drawImage(image, 0, 0, null);
1812
- // g.dispose();
1813
- }
1814
- }
1815
-
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));
1848
- }
1849
- PGraphics.showWarning("Unsupported format: " + filename);
1850
- return null;
1851
- }
1852
-
1853
-
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");
1870
- }
1871
-
1872
- Font font = (Font) textFont.getNative();
1873
- if (font != null) {
1874
- //return getFontMetrics(font).getAscent();
1875
- return g2.getFontMetrics(font).getAscent();
1876
- }
1877
- return super.textAscent();
1878
- }
1879
-
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();
1890
- }
1891
- return super.textDescent();
1892
- }
1893
-
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);
1931
- // map.put(TextAttribute.TRACKING,
1932
- // TextAttribute.TRACKING_TIGHT);
1933
- font = font.deriveFont(map);
1934
- }
1935
- g2.setFont(font);
1936
- textFont.setNative(font);
1937
- fontObject = font;
1938
-
1939
- /*
1940
- Map<TextAttribute, ?> attrs = font.getAttributes();
1941
- for (TextAttribute ta : attrs.keySet()) {
1942
- System.out.println(ta + " -> " + attrs.get(ta));
1943
- }
1944
- */
1945
- }
1946
-
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)
1958
-
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();
1971
- // System.out.println(font);
1972
- //if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
1973
- if (font != null) {
1974
- // System.out.println("using charswidth for " + new String(buffer, start, stop-start));
1975
- // maybe should use one of the newer/fancier functions for this?
1976
- // int length = stop - start;
1977
- // FontMetrics metrics = getFontMetrics(font);
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().
1982
- // System.err.println("using native");
1983
- // g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
1984
- // RenderingHints.VALUE_FRACTIONALMETRICS_ON);
1985
- // float m1 = metrics.charsWidth(buffer, start, length);
1986
- // float m2 = (float) metrics.getStringBounds(buffer, start, stop, g2).getWidth();
1987
- // TextLayout tl = new TextLayout(new String(buffer, start, length), font, g2.getFontRenderContext());
1988
- // float m3 = (float) tl.getBounds().getWidth();
1989
- // System.err.println(m1 + " " + m2 + " " + m3);
1990
- ////// return m1;
1991
- //// return m2;
1992
- //// return metrics.charsWidth(buffer, start, length);
1993
- // return m2;
1994
- return (float)
1995
- metrics.getStringBounds(buffer, start, stop, g2).getWidth();
1996
- }
1997
- // System.err.println("not native");
1998
- return super.textWidthImpl(buffer, start, stop);
1999
- }
2000
-
2001
-
2002
- // protected void beginTextScreenMode() {
2003
- // loadPixels();
2004
- // }
2005
-
2006
-
2007
- // protected void endTextScreenMode() {
2008
- // updatePixels();
2009
- // }
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();
2033
- // if (font != null && (textFont.isStream() || hints[ENABLE_NATIVE_FONTS])) {
2034
- if (font != null) {
2035
- /*
2036
- // save the current setting for text smoothing. note that this is
2037
- // different from the smooth() function, because the font smoothing
2038
- // is controlled when the font is created, not now as it's drawn.
2039
- // fixed a bug in 0116 that handled this incorrectly.
2040
- Object textAntialias =
2041
- g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
2042
-
2043
- // override the current text smoothing setting based on the font
2044
- // (don't change the global smoothing settings)
2045
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
2046
- textFont.smooth ?
2047
- RenderingHints.VALUE_ANTIALIAS_ON :
2048
- RenderingHints.VALUE_ANTIALIAS_OFF);
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
- }
2056
-
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);
2064
-
2065
- g2.setColor(fillColorObject);
2066
-
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
2071
- // g2.drawString(new String(buffer, start, stop - start), Math.round(x), Math.round(y));
2072
-
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
2078
- // java.awt.font.GlyphVector gv =
2079
- // font.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop - start));
2080
- // g2.drawGlyphVector(gv, x, y);
2081
- }
2082
-
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);
2086
-
2087
- } else { // otherwise just do the default
2088
- super.textLineImpl(buffer, start, stop, x, y);
2089
- }
2090
- }
2091
-
2092
-
2093
- // /**
2094
- // * Convenience method to get a legit FontMetrics object. Where possible,
2095
- // * override this any renderer subclass so that you're not using what's
2096
- // * returned by getDefaultToolkit() to get your metrics.
2097
- // */
2098
- // @SuppressWarnings("deprecation")
2099
- // public FontMetrics getFontMetrics(Font font) { // ignore
2100
- // Frame frame = parent.frame;
2101
- // if (frame != null) {
2102
- // return frame.getToolkit().getFontMetrics(font);
2103
- // }
2104
- // return Toolkit.getDefaultToolkit().getFontMetrics(font);
2105
- // }
2106
- //
2107
- //
2108
- // /**
2109
- // * Convenience method to jump through some Java2D hoops and get an FRC.
2110
- // */
2111
- // public FontRenderContext getFontRenderContext(Font font) { // ignore
2112
- // return getFontMetrics(font).getFontRenderContext();
2113
- // }
2114
-
2115
- /*
2116
- Toolkit toolkit;
2117
-
2118
- @SuppressWarnings("deprecation")
2119
- protected FontMetrics getFontMetrics(Font font) {
2120
- if (toolkit == null) {
2121
- try {
2122
- Canvas canvas = (Canvas) surface.getNative();
2123
- toolkit = canvas.getToolkit();
2124
- } catch (Exception e) {
2125
- // May error out if it's a PSurfaceNone or similar
2126
- toolkit = Toolkit.getDefaultToolkit();
2127
- }
2128
- }
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
- }
2628
- }
2629
-
2630
-
2631
-
2632
- //////////////////////////////////////////////////////////////
2633
-
2634
- // COLOR MODE
2635
-
2636
- // All colorMode() variations are inherited from PGraphics.
2637
-
2638
-
2639
-
2640
- //////////////////////////////////////////////////////////////
2641
-
2642
- // COLOR CALC
2643
-
2644
- // colorCalc() and colorCalcARGB() inherited from PGraphics.
2645
-
2646
-
2647
-
2648
- //////////////////////////////////////////////////////////////
2649
-
2650
- // COLOR DATATYPE STUFFING
2651
-
2652
- // final color() variations inherited.
2653
-
2654
-
2655
-
2656
- //////////////////////////////////////////////////////////////
2657
-
2658
- // COLOR DATATYPE EXTRACTION
2659
-
2660
- // final methods alpha, red, green, blue,
2661
- // hue, saturation, and brightness all inherited.
2662
-
2663
-
2664
-
2665
- //////////////////////////////////////////////////////////////
2666
-
2667
- // COLOR DATATYPE INTERPOLATION
2668
-
2669
- // both lerpColor variants inherited.
2670
-
2671
-
2672
-
2673
- //////////////////////////////////////////////////////////////
2674
-
2675
- // BEGIN/END RAW
2676
-
2677
-
2678
- @Override
2679
- public void beginRaw(PGraphics recorderRaw) {
2680
- showMethodWarning("beginRaw");
2681
- }
2682
-
2683
-
2684
- @Override
2685
- public void endRaw() {
2686
- showMethodWarning("endRaw");
2687
- }
2688
-
2689
-
2690
-
2691
- //////////////////////////////////////////////////////////////
2692
-
2693
- // WARNINGS and EXCEPTIONS
2694
-
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
- /*
2726
- // 'offscreen' will probably be removed in the next release
2727
- if (useOffscreen) {
2728
- raster = offscreen.getRaster();
2729
- } else*/ if (image instanceof VolatileImage) {
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
- }
2737
-
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.");
2748
- }
2749
- return raster;
2750
- }
2751
-
2752
-
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);
2769
- // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2770
- // WritableRaster raster = image.getRaster();
2771
- }
2772
-
2773
-
2774
- // /**
2775
- // * Update the pixels[] buffer to the PGraphics image.
2776
- // * <P>
2777
- // * Unlike in PImage, where updatePixels() only requests that the
2778
- // * update happens, in PGraphicsJava2D, this will happen immediately.
2779
- // */
2780
- // @Override
2781
- // public void updatePixels() {
2782
- // //updatePixels(0, 0, width, height);
2783
- //// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2784
- //// WritableRaster raster = image.getRaster();
2785
- // updatePixels(0, 0, width, height);
2786
- // }
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)) {
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);
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)");
2804
- // new Exception().printStackTrace(System.out);
2805
- }
2806
- // updatePixels();
2807
- if (pixels != null) {
2808
- getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels);
2809
- }
2810
- modified = true;
2811
- }
2812
-
2813
-
2814
- // @Override
2815
- // protected void updatePixelsImpl(int x, int y, int w, int h) {
2816
- // super.updatePixelsImpl(x, y, w, h);
2817
- //
2818
- // if ((x != 0) || (y != 0) || (w != width) || (h != height)) {
2819
- // // Show a warning message, but continue anyway.
2820
- // showVariationWarning("updatePixels(x, y, w, h)");
2821
- // }
2822
- // getRaster().setDataElements(0, 0, width, height, pixels);
2823
- // }
2824
-
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);
2839
- // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
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;
2845
- }
2846
- return getset[0];
2847
- }
2848
-
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);
2859
- // WritableRaster raster =
2860
- // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2861
- WritableRaster raster = getRaster();
2862
-
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
- }
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
- }
2885
- } else {
2886
- System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth);
2887
- }
2888
- sourceOffset += sourceWidth;
2889
- targetOffset += target.pixelWidth;
2890
- }
2891
- }
2892
- }
2893
-
2894
-
2895
- @Override
2896
- public void set(int x, int y, int argb) {
2897
- if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) return;
2898
- // ((BufferedImage) image).setRGB(x, y, argb);
2899
- getset[0] = argb;
2900
- // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2901
- // WritableRaster raster = image.getRaster();
2902
- getRaster().setDataElements(x, y, getset);
2903
- }
2904
-
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();
2915
- // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
2916
-
2917
- if ((sourceX == 0) && (sourceY == 0) &&
2918
- (sourceWidth == sourceImage.pixelWidth) &&
2919
- (sourceHeight == sourceImage.pixelHeight)) {
2920
- // System.out.format("%d %d %dx%d %d%n", targetX, targetY,
2921
- // sourceImage.width, sourceImage.height,
2922
- // sourceImage.pixels.length);
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);
2930
- }
2931
- }
2932
-
2933
-
2934
-
2935
- //////////////////////////////////////////////////////////////
2936
-
2937
- // MASK
2938
-
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);
2951
- }
2952
- }
2953
-
2954
-
2955
- @Override
2956
- public void mask(PImage alpha) {
2957
- if (primaryGraphics) {
2958
- showWarning(MASK_WARNING);
2959
-
2960
- } else {
2961
- super.mask(alpha);
2962
- }
2963
- }
2964
-
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);
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
-
3016
-
3017
- // static public int blendColor(int c1, int c2, int mode)
3018
-
3019
-
3020
- // public void blend(int sx, int sy, int sw, int sh,
3021
- // int dx, int dy, int dw, int dh, int mode)
3022
-
3023
-
3024
- // public void blend(PImage src,
3025
- // int sx, int sy, int sw, int sh,
3026
- // int dx, int dy, int dw, int dh, int mode)
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
- }
3040
- }