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