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