propane 2.9.3-java → 3.0.0.pre-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +1 -3
- data/README.md +5 -5
- data/Rakefile +4 -13
- data/lib/propane/version.rb +1 -1
- data/library/boids/boids.rb +1 -1
- data/pom.xml +16 -17
- data/propane.gemspec +2 -2
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +56 -4
- data/src/main/java/processing/core/PApplet.java +3 -0
- data/src/main/java/processing/core/PConstants.java +4 -4
- data/src/main/java/processing/core/PGraphics.java +6 -6
- data/src/main/java/processing/core/PSurface.java +1 -1
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +248 -2157
- data/src/main/java/processing/javafx/PSurfaceFX.java +68 -987
- data/test/vecmath_spec_test.rb +6 -0
- metadata +7 -12
- data/.mvn/extensions.xml +0 -8
- data/.mvn/wrapper/maven-wrapper.properties +0 -1
- data/mvnw +0 -234
- data/mvnw.cmd +0 -145
- data/pom.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3baeb56ebe6e3e83283fd79269e0ab9b0bf2dff9bb8a99f6c54c3d4aad8b349b
|
4
|
+
data.tar.gz: e69cd56be1ce3491dfe2e586b2337e3aace70426444be6c9443773330f39e67a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e877d5693ab58fb881e9cb32d4454ae8f925c1db5514c97098c322f80a2200959a08cc2297f2ff00074b3455cfbbf38b5189b0c59856f23b387e0484803aa43b
|
7
|
+
data.tar.gz: 9d162476e1da3dfbd8d08b762821d1761511811fb1dcc0de44a23e6f64cfbad27a4c218401914c0b221ba1e56acd4faacdcb429ceb13d2fa38e1fcac368eda0f
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
**
|
2
|
-
|
3
|
-
**v2.9.2** Bump for jruby-9.2.3.0.
|
1
|
+
**v3.0.0.pre** Compiled for java 11, works on linux, requires testing on MacOS and Windows
|
4
2
|
|
5
3
|
**v2.9.1** Attempt to bring 64 bit Windows users to party. Use non versioned jogl/opengl jars from processing distro, including processing.org apple.jar in case it's needed, MacOS users are being very opaque on this.
|
6
4
|
|
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Propane
|
2
2
|
To build custom core see [processing-core][processing-core]
|
3
3
|
|
4
|
-
A slim layer to communicate with Processing from JRuby, features a polyglot maven build. We have created a configuration free version of ruby processing, for processing-3.4, where we include a modified processing core (`public runPropane()` to replace `protected runSketch()
|
4
|
+
A slim layer to communicate with Processing from JRuby, features a polyglot maven build. We have created a configuration free version of ruby processing, for processing-3.4, where we include a modified processing core (`public runPropane()` to replace `protected runSketch()`. These jars are small enough to include in a gem distribution, and hence we do not require configuration. This has created a scriptable version, ie files get run direct from jruby, but you could use jruby-complete if you used the propane script (avoids need to give the absolute data path for the data folder, but would also be needed for a watch mode). See guide to [building ruby-processing projects][building]. NB: this is a far from perfect solution and javafx sketches and possibly a few others will not run with jdk11, but a least I get to diagnose those errors too.
|
5
5
|
|
6
6
|
adjust above for your OS/distro setup.
|
7
7
|
|
8
8
|
## Requirements
|
9
9
|
|
10
|
-
- `
|
11
|
-
- `jruby-9.2.
|
12
|
-
- `mvn-3.5.
|
10
|
+
- `jdk-11.0.1`
|
11
|
+
- `jruby-9.2.0.0`
|
12
|
+
- `mvn-3.5.4+`
|
13
13
|
- `apple.jar` (_build only_) see (or may'be runtime as well a MacOS user needed to test) [vanilla-processing](https://github.com/processing/processing/blob/master/core/apple.jar)
|
14
14
|
|
15
15
|
## Building and testing
|
@@ -23,7 +23,7 @@ rake javadoc
|
|
23
23
|
## Installation
|
24
24
|
```bash
|
25
25
|
jgem install propane # from rubygems
|
26
|
-
jgem install propane-
|
26
|
+
jgem install propane-3.0.0.pre-java.gem # local install requires a custom processing-core
|
27
27
|
```
|
28
28
|
|
29
29
|
## Usage
|
data/Rakefile
CHANGED
@@ -13,23 +13,14 @@ end
|
|
13
13
|
|
14
14
|
task default: [:init, :compile, :install, :test, :gem]
|
15
15
|
|
16
|
-
|
17
|
-
desc 'Create Manifest and Copy Jars'
|
16
|
+
desc 'Create Manifest'
|
18
17
|
task :init do
|
19
18
|
create_manifest
|
20
|
-
processing_root = File.dirname(`readlink -f $(which processing)`) # for Archlinux etc
|
21
|
-
# processing_root = File.join(ENV['HOME'], 'processing-3.4') # alternative for debian linux etc
|
22
|
-
jar_dir = File.join(processing_root, 'core', 'library')
|
23
|
-
opengl = Dir.entries(jar_dir).grep(/amd64|macosx-universal/)
|
24
|
-
opengl.concat %w[jogl-all.jar gluegen-rt.jar]
|
25
|
-
opengl.each do |gl|
|
26
|
-
FileUtils.cp(File.join(jar_dir, gl), File.join('.', 'lib'))
|
27
|
-
end
|
28
19
|
end
|
29
20
|
|
30
21
|
desc 'Install'
|
31
22
|
task :install do
|
32
|
-
sh
|
23
|
+
sh 'mv target/propane-3.0.0.jar lib'
|
33
24
|
end
|
34
25
|
|
35
26
|
desc 'Gem'
|
@@ -64,8 +55,8 @@ end
|
|
64
55
|
|
65
56
|
desc 'clean'
|
66
57
|
task :clean do
|
67
|
-
Dir[
|
68
|
-
puts
|
58
|
+
Dir['./**/*.%w{jar gem}'].each do |path|
|
59
|
+
puts 'Deleting #{path} ...'
|
69
60
|
File.delete(path)
|
70
61
|
end
|
71
62
|
FileUtils.rm_rf('./target')
|
data/lib/propane/version.rb
CHANGED
data/library/boids/boids.rb
CHANGED
data/pom.xml
CHANGED
@@ -1,17 +1,10 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<!--
|
3
|
-
|
4
|
-
|
5
|
-
DO NOT MODIFIY - GENERATED CODE
|
6
|
-
|
7
|
-
|
8
|
-
-->
|
9
2
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
10
|
-
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
11
4
|
<modelVersion>4.0.0</modelVersion>
|
12
5
|
<groupId>propane</groupId>
|
13
6
|
<artifactId>propane</artifactId>
|
14
|
-
<version>
|
7
|
+
<version>3.0.0</version>
|
15
8
|
<name>propane</name>
|
16
9
|
<description>An integrated processing-core (somewhat hacked), with additional java code for a jruby version of processing.</description>
|
17
10
|
<url>https://github.com/monkstone/propane</url>
|
@@ -71,8 +64,6 @@ DO NOT MODIFIY - GENERATED CODE
|
|
71
64
|
<properties>
|
72
65
|
<jogl.version>2.3.2</jogl.version>
|
73
66
|
<jruby.api>http://jruby.org/apidocs/</jruby.api>
|
74
|
-
<maven.compiler.source>1.8</maven.compiler.source>
|
75
|
-
<maven.compiler.target>1.8</maven.compiler.target>
|
76
67
|
<polyglot.dump.pom>pom.xml</polyglot.dump.pom>
|
77
68
|
<processing.api>http://processing.github.io/processing-javadocs/core/</processing.api>
|
78
69
|
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
|
@@ -83,7 +74,7 @@ DO NOT MODIFIY - GENERATED CODE
|
|
83
74
|
<dependency>
|
84
75
|
<groupId>org.jruby</groupId>
|
85
76
|
<artifactId>jruby</artifactId>
|
86
|
-
<version>9.2.
|
77
|
+
<version>9.2.0.0</version>
|
87
78
|
<type>pom</type>
|
88
79
|
</dependency>
|
89
80
|
<dependency>
|
@@ -94,7 +85,7 @@ DO NOT MODIFIY - GENERATED CODE
|
|
94
85
|
<dependency>
|
95
86
|
<groupId>org.processing</groupId>
|
96
87
|
<artifactId>video</artifactId>
|
97
|
-
<version>3.
|
88
|
+
<version>3.2.3</version>
|
98
89
|
</dependency>
|
99
90
|
<dependency>
|
100
91
|
<groupId>org.jogamp.jogl</groupId>
|
@@ -130,16 +121,24 @@ DO NOT MODIFIY - GENERATED CODE
|
|
130
121
|
<pluginManagement>
|
131
122
|
<plugins>
|
132
123
|
<plugin>
|
124
|
+
<groupId>org.codehaus.mojo</groupId>
|
125
|
+
<artifactId>versions-maven-plugin</artifactId>
|
126
|
+
<version>2.7</version>
|
127
|
+
<configuration>
|
128
|
+
<generateBackupPoms>false</generateBackupPoms>
|
129
|
+
</configuration>
|
130
|
+
</plugin>
|
131
|
+
<plugin>
|
132
|
+
<groupId>org.apache.maven.plugins</groupId>
|
133
133
|
<artifactId>maven-compiler-plugin</artifactId>
|
134
134
|
<version>3.8.0</version>
|
135
135
|
<configuration>
|
136
|
-
<
|
137
|
-
<target>${maven.compiler.target}</target>
|
136
|
+
<release>11</release>
|
138
137
|
</configuration>
|
139
138
|
</plugin>
|
140
139
|
<plugin>
|
141
140
|
<artifactId>maven-javadoc-plugin</artifactId>
|
142
|
-
<version>
|
141
|
+
<version>3.0.1</version>
|
143
142
|
<configuration>
|
144
143
|
<detectOfflineLinks>false</detectOfflineLinks>
|
145
144
|
<links>
|
@@ -150,7 +149,7 @@ DO NOT MODIFIY - GENERATED CODE
|
|
150
149
|
</plugin>
|
151
150
|
<plugin>
|
152
151
|
<artifactId>maven-jar-plugin</artifactId>
|
153
|
-
<version>3.0
|
152
|
+
<version>3.1.0</version>
|
154
153
|
<configuration>
|
155
154
|
<archive>
|
156
155
|
<manifestFile>MANIFEST.MF</manifestFile>
|
data/propane.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.summary = %q{ruby wrapper for processing-3.4 on MacOS, linux and windows (64bit only)}
|
16
16
|
gem.homepage = 'https://ruby-processing.github.io/propane/'
|
17
17
|
gem.files = `git ls-files`.split($/)
|
18
|
-
gem.files << 'lib/propane-
|
18
|
+
gem.files << 'lib/propane-3.0.0.jar'
|
19
19
|
gem.files << 'lib/apple.jar'
|
20
20
|
gem.files << 'lib/gluegen-rt.jar'
|
21
21
|
gem.files << 'lib/jogl-all.jar'
|
@@ -32,5 +32,5 @@ Gem::Specification.new do |gem|
|
|
32
32
|
gem.add_runtime_dependency 'arcball', '~> 1.0', '>= 1.0.0'
|
33
33
|
gem.require_paths = ['lib']
|
34
34
|
gem.platform = 'java'
|
35
|
-
gem.requirements << 'java runtime >=
|
35
|
+
gem.requirements << 'java runtime >= 11.0.1+'
|
36
36
|
end
|
@@ -18,7 +18,9 @@ package monkstone.vecmath.vec2;
|
|
18
18
|
* You should have received a copy of the GNU Lesser General Public
|
19
19
|
* License along with this library; if not, write to the Free Software
|
20
20
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
-
|
21
|
+
*
|
22
|
+
* fastAtan2 algorithm from https://github.com/libgdx/libgdx (Apache 2.0 license)
|
23
|
+
*/
|
22
24
|
import org.jruby.Ruby;
|
23
25
|
import org.jruby.RubyArray;
|
24
26
|
import org.jruby.RubyClass;
|
@@ -28,7 +30,6 @@ import org.jruby.RubyObject;
|
|
28
30
|
import org.jruby.RubySymbol;
|
29
31
|
import org.jruby.anno.JRubyClass;
|
30
32
|
import org.jruby.anno.JRubyMethod;
|
31
|
-
import org.jruby.runtime.Arity;
|
32
33
|
import org.jruby.runtime.Block;
|
33
34
|
import org.jruby.runtime.ThreadContext;
|
34
35
|
import org.jruby.runtime.builtin.IRubyObject;
|
@@ -354,6 +355,16 @@ public class Vec2 extends RubyObject {
|
|
354
355
|
return context.runtime.newFloat(Math.atan2(jy, jx));
|
355
356
|
}
|
356
357
|
|
358
|
+
/**
|
359
|
+
*
|
360
|
+
* @param context ThreadContext
|
361
|
+
* @return heading IRubyObject radians
|
362
|
+
*/
|
363
|
+
@JRubyMethod(name = "fast_heading")
|
364
|
+
public IRubyObject fastHeading(ThreadContext context) {
|
365
|
+
return context.runtime.newFloat(fastAtan2(jy, jx));
|
366
|
+
}
|
367
|
+
|
357
368
|
/**
|
358
369
|
*
|
359
370
|
* @param context ThreadContext
|
@@ -441,7 +452,7 @@ public class Vec2 extends RubyObject {
|
|
441
452
|
/**
|
442
453
|
*
|
443
454
|
* @param context ThreadContext
|
444
|
-
* @return new normalized
|
455
|
+
* @return new normalized Vec2D object (ruby)
|
445
456
|
*/
|
446
457
|
@JRubyMethod(name = "normalize")
|
447
458
|
|
@@ -582,7 +593,7 @@ public class Vec2 extends RubyObject {
|
|
582
593
|
/**
|
583
594
|
*
|
584
595
|
* @param context ThreadContext
|
585
|
-
* @param other IRubyObject another
|
596
|
+
* @param other IRubyObject another Vec2D
|
586
597
|
* @return angle IRubyObject in radians
|
587
598
|
*/
|
588
599
|
@JRubyMethod(name = "angle_between")
|
@@ -598,6 +609,25 @@ public class Vec2 extends RubyObject {
|
|
598
609
|
return runtime.newFloat(Math.atan2(jx - vec.jx, jy - vec.jy));
|
599
610
|
}
|
600
611
|
|
612
|
+
/**
|
613
|
+
*
|
614
|
+
* @param context ThreadContext
|
615
|
+
* @param other IRubyObject another Vec2D
|
616
|
+
* @return angle IRubyObject in radians
|
617
|
+
*/
|
618
|
+
@JRubyMethod(name = "fast_angle_between")
|
619
|
+
|
620
|
+
public IRubyObject fastAngleBetween(ThreadContext context, IRubyObject other) {
|
621
|
+
Vec2 vec = null;
|
622
|
+
Ruby runtime = context.runtime;
|
623
|
+
if (other instanceof Vec2) {
|
624
|
+
vec = (Vec2) other.toJava(Vec2.class);
|
625
|
+
} else {
|
626
|
+
throw runtime.newTypeError("argument should be Vec2D");
|
627
|
+
}
|
628
|
+
return runtime.newFloat(fastAtan2(jx - vec.jx, jy - vec.jy));
|
629
|
+
}
|
630
|
+
|
601
631
|
/**
|
602
632
|
*
|
603
633
|
* @param context ThreadContext
|
@@ -666,6 +696,28 @@ public class Vec2 extends RubyObject {
|
|
666
696
|
return context.runtime.newString(String.format("Vec2D(x = %4.4f, y = %4.4f)", jx, jy));
|
667
697
|
}
|
668
698
|
|
699
|
+
private double fastAtan2(double y, double x) {
|
700
|
+
if (x == 0) {
|
701
|
+
if (y > 0) {
|
702
|
+
return Math.PI / 2;
|
703
|
+
}
|
704
|
+
if (y == 0) {
|
705
|
+
return 0;
|
706
|
+
}
|
707
|
+
return -Math.PI / 2;
|
708
|
+
}
|
709
|
+
final double atan, z = y / x;
|
710
|
+
if (Math.abs(z) < 1) {
|
711
|
+
atan = z / (1 + 0.28 * z * z);
|
712
|
+
if (x < 0) {
|
713
|
+
return atan + (y < 0 ? -Math.PI : Math.PI);
|
714
|
+
}
|
715
|
+
return atan;
|
716
|
+
}
|
717
|
+
atan = Math.PI / 2 - z / (z * z + 0.28);
|
718
|
+
return y < 0 ? atan - Math.PI : atan;
|
719
|
+
}
|
720
|
+
|
669
721
|
/**
|
670
722
|
*
|
671
723
|
* @return hash int
|
@@ -8263,6 +8263,7 @@ static public void arrayCopy(Object src, Object dst) {
|
|
8263
8263
|
/**
|
8264
8264
|
* @deprecated Use arrayCopy() instead.
|
8265
8265
|
*/
|
8266
|
+
@Deprecated
|
8266
8267
|
static public void arraycopy(Object src, int srcPosition,
|
8267
8268
|
Object dst, int dstPosition,
|
8268
8269
|
int length) {
|
@@ -8272,6 +8273,7 @@ int length) {
|
|
8272
8273
|
/**
|
8273
8274
|
* @deprecated Use arrayCopy() instead.
|
8274
8275
|
*/
|
8276
|
+
@Deprecated
|
8275
8277
|
static public void arraycopy(Object src, Object dst, int length) {
|
8276
8278
|
System.arraycopy(src, 0, dst, 0, length);
|
8277
8279
|
}
|
@@ -8279,6 +8281,7 @@ static public void arraycopy(Object src, Object dst, int length) {
|
|
8279
8281
|
/**
|
8280
8282
|
* @deprecated Use arrayCopy() instead.
|
8281
8283
|
*/
|
8284
|
+
@Deprecated
|
8282
8285
|
static public void arraycopy(Object src, Object dst) {
|
8283
8286
|
System.arraycopy(src, 0, dst, 0, Array.getLength(src));
|
8284
8287
|
}
|
@@ -255,7 +255,7 @@ public interface PConstants {
|
|
255
255
|
// @see processing.core.PImage#blendColor(int,int,int)
|
256
256
|
|
257
257
|
public final static int REPLACE = 0;
|
258
|
-
public final static int BLEND = 1
|
258
|
+
public final static int BLEND = 1;
|
259
259
|
public final static int ADD = 1 << 1;
|
260
260
|
public final static int SUBTRACT = 1 << 2;
|
261
261
|
public final static int LIGHTEST = 1 << 3;
|
@@ -392,7 +392,7 @@ public interface PConstants {
|
|
392
392
|
/**
|
393
393
|
* textMode(MODEL) is the default, meaning that characters
|
394
394
|
* will be affected by transformations like any other shapes.
|
395
|
-
*
|
395
|
+
*
|
396
396
|
* Changed value in 0093 to not interfere with LEFT, CENTER, and RIGHT.
|
397
397
|
*/
|
398
398
|
static final int MODEL = 4;
|
@@ -403,7 +403,7 @@ public interface PConstants {
|
|
403
403
|
* not available, then textMode(SHAPE) will be ignored and textMode(MODEL)
|
404
404
|
* will be used instead. For this reason, be sure to call textMode()
|
405
405
|
* <EM>after</EM> calling textFont().
|
406
|
-
*
|
406
|
+
*
|
407
407
|
* Currently, textMode(SHAPE) is only supported by OPENGL mode.
|
408
408
|
* It also requires Java 1.2 or higher (OPENGL requires 1.4 anyway)
|
409
409
|
*/
|
@@ -415,7 +415,7 @@ public interface PConstants {
|
|
415
415
|
|
416
416
|
// stroke modes
|
417
417
|
|
418
|
-
static final int SQUARE = 1
|
418
|
+
static final int SQUARE = 1; // called 'butt' in the svg spec
|
419
419
|
static final int ROUND = 1 << 1;
|
420
420
|
static final int PROJECT = 1 << 2; // called 'square' in the svg spec
|
421
421
|
static final int MITER = 1 << 3;
|
@@ -207,12 +207,12 @@ public class PGraphics extends PImage implements PConstants {
|
|
207
207
|
/**
|
208
208
|
* Array of hint[] items. These are hacks to get around various
|
209
209
|
* temporary workarounds inside the environment.
|
210
|
-
*
|
210
|
+
*
|
211
211
|
* Note that this array cannot be static, as a hint() may result in a
|
212
212
|
* runtime change specific to a renderer. For instance, calling
|
213
213
|
* hint(DISABLE_DEPTH_TEST) has to call glDisable() right away on an
|
214
214
|
* instance of PGraphicsOpenGL.
|
215
|
-
*
|
215
|
+
*
|
216
216
|
* The hints[] array is allocated early on because it might
|
217
217
|
* be used inside beginDraw(), allocate(), etc.
|
218
218
|
*/
|
@@ -910,7 +910,7 @@ public class PGraphics extends PImage implements PConstants {
|
|
910
910
|
*
|
911
911
|
* ( end auto-generated )
|
912
912
|
* <h3>Advanced</h3>
|
913
|
-
*
|
913
|
+
*
|
914
914
|
* When creating your own PGraphics, you should call this when
|
915
915
|
* you're finished drawing.
|
916
916
|
*
|
@@ -1652,12 +1652,12 @@ public class PGraphics extends PImage implements PConstants {
|
|
1652
1652
|
* coincident with a call to vertex. As of beta, this was moved to
|
1653
1653
|
* the protected method you see here, and called from an optional
|
1654
1654
|
* param of and overloaded vertex().
|
1655
|
-
*
|
1655
|
+
*
|
1656
1656
|
* The parameters depend on the current textureMode. When using
|
1657
1657
|
* textureMode(IMAGE), the coordinates will be relative to the size
|
1658
1658
|
* of the image texture, when used with textureMode(NORMAL),
|
1659
1659
|
* they'll be in the range 0..1.
|
1660
|
-
*
|
1660
|
+
*
|
1661
1661
|
* Used by both PGraphics2D (for images) and PGraphics3D.
|
1662
1662
|
*/
|
1663
1663
|
protected void vertexTexture(float u, float v) {
|
@@ -3848,7 +3848,7 @@ public class PGraphics extends PImage implements PConstants {
|
|
3848
3848
|
/**
|
3849
3849
|
* Expects x1, y1, x2, y2 coordinates where (x2 >= x1) and (y2 >= y1).
|
3850
3850
|
* If tint() has been called, the image will be colored.
|
3851
|
-
*
|
3851
|
+
*
|
3852
3852
|
* The default implementation draws an image as a textured quad.
|
3853
3853
|
* The (u, v) coordinates are in image space (they're ints, after all..)
|
3854
3854
|
*/
|
@@ -38,7 +38,7 @@ public interface PSurface {
|
|
38
38
|
public void initOffscreen(PApplet sketch);
|
39
39
|
|
40
40
|
// considering removal in favor of separate Component classes for appropriate renderers
|
41
|
-
// (i.e. for Java2D or a generic Image surface, but not PDF, debatable for GL or
|
41
|
+
// (i.e. for Java2D or a generic Image surface, but not PDF, debatable for GL or )
|
42
42
|
//public Component initComponent(PApplet sketch);
|
43
43
|
|
44
44
|
//public Frame initFrame(PApplet sketch, Color backgroundColor,
|
@@ -1,2330 +1,421 @@
|
|
1
|
-
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
2
|
-
|
3
|
-
/*
|
4
|
-
Part of the Processing project - http://processing.org
|
5
|
-
|
6
|
-
Copyright (c) 2015 The Processing Foundation
|
7
|
-
|
8
|
-
This library is free software; you can redistribute it and/or
|
9
|
-
modify it under the terms of the GNU Lesser General Public
|
10
|
-
License as published by the Free Software Foundation, version 2.1.
|
11
|
-
|
12
|
-
This library is distributed in the hope that it will be useful,
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
-
Lesser General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU Lesser General
|
18
|
-
Public License along with this library; if not, write to the
|
19
|
-
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
20
|
-
Boston, MA 02111-1307 USA
|
21
|
-
*/
|
22
|
-
|
23
1
|
package processing.javafx;
|
24
2
|
|
25
|
-
import
|
26
|
-
import
|
27
|
-
import
|
28
|
-
|
29
|
-
import
|
30
|
-
import
|
31
|
-
import
|
32
|
-
import java.util.LinkedHashMap;
|
33
|
-
import java.util.Map;
|
34
|
-
|
35
|
-
import javafx.scene.SnapshotParameters;
|
36
|
-
import javafx.scene.canvas.GraphicsContext;
|
37
|
-
import javafx.scene.effect.BlendMode;
|
38
|
-
import javafx.scene.image.PixelFormat;
|
39
|
-
import javafx.scene.image.PixelReader;
|
40
|
-
import javafx.scene.image.PixelWriter;
|
41
|
-
import javafx.scene.image.WritableImage;
|
42
|
-
import javafx.scene.image.WritablePixelFormat;
|
43
|
-
import javafx.scene.paint.Color;
|
44
|
-
import javafx.scene.shape.ArcType;
|
45
|
-
import javafx.scene.shape.StrokeLineCap;
|
46
|
-
import javafx.scene.shape.StrokeLineJoin;
|
47
|
-
import javafx.scene.text.Font;
|
48
|
-
import javafx.scene.text.Text;
|
49
|
-
import javafx.scene.transform.Affine;
|
50
|
-
import javafx.scene.transform.Transform;
|
51
|
-
|
52
|
-
import processing.core.*;
|
53
|
-
|
54
|
-
|
55
|
-
public class PGraphicsFX2D extends PGraphics {
|
56
|
-
GraphicsContext context;
|
57
|
-
|
58
|
-
static final WritablePixelFormat<IntBuffer> argbFormat =
|
59
|
-
PixelFormat.getIntArgbInstance();
|
60
|
-
|
61
|
-
WritableImage snapshotImage;
|
62
|
-
|
63
|
-
Path2D workPath = new Path2D();
|
64
|
-
Path2D auxPath = new Path2D();
|
65
|
-
boolean openContour;
|
66
|
-
boolean adjustedForThinLines;
|
67
|
-
/// break the shape at the next vertex (next vertex() call is a moveto())
|
68
|
-
boolean breakShape;
|
69
|
-
|
70
|
-
private float pathCoordsBuffer[] = new float[6];
|
71
|
-
|
72
|
-
/// coordinates for internal curve calculation
|
73
|
-
float[] curveCoordX;
|
74
|
-
float[] curveCoordY;
|
75
|
-
float[] curveDrawX;
|
76
|
-
float[] curveDrawY;
|
77
|
-
|
78
|
-
int transformCount;
|
79
|
-
Affine transformStack[] = new Affine[MATRIX_STACK_DEPTH];
|
80
|
-
|
81
|
-
// Line2D.Float line = new Line2D.Float();
|
82
|
-
// Ellipse2D.Float ellipse = new Ellipse2D.Float();
|
83
|
-
// Rectangle2D.Float rect = new Rectangle2D.Float();
|
84
|
-
// Arc2D.Float arc = new Arc2D.Float();
|
85
|
-
//
|
86
|
-
// protected Color tintColorObject;
|
87
|
-
//
|
88
|
-
// protected Color fillColorObject;
|
89
|
-
// public boolean fillGradient;
|
90
|
-
// public Paint fillGradientObject;
|
91
|
-
//
|
92
|
-
// protected Color strokeColorObject;
|
93
|
-
// public boolean strokeGradient;
|
94
|
-
// public Paint strokeGradientObject;
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
//////////////////////////////////////////////////////////////
|
99
|
-
|
100
|
-
// INTERNAL
|
101
|
-
|
102
|
-
|
103
|
-
public PGraphicsFX2D() { }
|
104
|
-
|
105
|
-
|
106
|
-
//public void setParent(PApplet parent)
|
107
|
-
|
3
|
+
import processing.core.PGraphics;
|
4
|
+
import processing.core.PImage;
|
5
|
+
import processing.core.PMatrix;
|
6
|
+
import processing.core.PMatrix2D;
|
7
|
+
import processing.core.PMatrix3D;
|
8
|
+
import processing.core.PShape;
|
9
|
+
import processing.core.PSurface;
|
108
10
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
//public void setPath(String path)
|
113
|
-
|
114
|
-
|
115
|
-
//public void setSize(int width, int height)
|
116
|
-
|
117
|
-
|
118
|
-
//public void dispose()
|
119
|
-
|
120
|
-
|
121
|
-
@Override
|
122
|
-
public PSurface createSurface() {
|
123
|
-
return surface = new PSurfaceFX(this);
|
124
|
-
}
|
125
|
-
|
126
|
-
|
127
|
-
/** Returns the javafx.scene.canvas.GraphicsContext used by this renderer. */
|
128
|
-
@Override
|
129
|
-
public Object getNative() {
|
130
|
-
return context;
|
131
|
-
}
|
132
|
-
|
133
|
-
|
134
|
-
//////////////////////////////////////////////////////////////
|
135
|
-
|
136
|
-
// FRAME
|
137
|
-
|
138
|
-
|
139
|
-
// @Override
|
140
|
-
// public boolean canDraw() {
|
141
|
-
// return true;
|
142
|
-
// }
|
143
|
-
|
144
|
-
|
145
|
-
@Override
|
146
|
-
public void beginDraw() {
|
147
|
-
checkSettings();
|
148
|
-
resetMatrix(); // reset model matrix
|
149
|
-
vertexCount = 0;
|
150
|
-
}
|
151
|
-
|
152
|
-
|
153
|
-
@Override
|
154
|
-
public void endDraw() {
|
155
|
-
flush();
|
156
|
-
|
157
|
-
if (!primaryGraphics) {
|
158
|
-
// TODO this is probably overkill for most tasks...
|
159
|
-
loadPixels();
|
11
|
+
public class PGraphicsFX2D extends PGraphics{
|
12
|
+
final String message = "FX2D renderer not supported in this version of propane";
|
13
|
+
public PGraphicsFX2D(){
|
160
14
|
}
|
161
|
-
}
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
//////////////////////////////////////////////////////////////
|
166
|
-
|
167
|
-
// SETTINGS
|
168
|
-
|
169
|
-
|
170
|
-
//protected void checkSettings()
|
171
|
-
|
172
15
|
|
173
|
-
//protected void defaultSettings()
|
174
16
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
//////////////////////////////////////////////////////////////
|
181
|
-
|
182
|
-
// HINT
|
183
|
-
|
184
|
-
|
185
|
-
//public void hint(int which)
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
//////////////////////////////////////////////////////////////
|
190
|
-
|
191
|
-
// SHAPE CREATION
|
192
|
-
|
193
|
-
|
194
|
-
//protected PShape createShapeFamily(int type)
|
195
|
-
|
196
|
-
|
197
|
-
//protected PShape createShapePrimitive(int kind, float... p)
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
//////////////////////////////////////////////////////////////
|
202
|
-
|
203
|
-
// SHAPE
|
204
|
-
|
205
|
-
|
206
|
-
@Override
|
207
|
-
public void beginShape(int kind) {
|
208
|
-
shape = kind;
|
209
|
-
vertexCount = 0;
|
210
|
-
curveVertexCount = 0;
|
211
|
-
|
212
|
-
workPath.reset();
|
213
|
-
auxPath.reset();
|
214
|
-
|
215
|
-
flushPixels();
|
216
|
-
|
217
|
-
if (drawingThinLines()) {
|
218
|
-
adjustedForThinLines = true;
|
219
|
-
translate(0.5f, 0.5f);
|
17
|
+
@Override
|
18
|
+
public void applyMatrix(float n00, float n01, float n02, float n10, float n11, float n12) {
|
19
|
+
throw new UnsupportedOperationException(message);
|
220
20
|
}
|
221
|
-
}
|
222
|
-
|
223
|
-
|
224
|
-
//public boolean edge(boolean e)
|
225
|
-
|
226
21
|
|
227
|
-
//public void normal(float nx, float ny, float nz) {
|
228
22
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
@Override
|
234
|
-
public void texture(PImage image) {
|
235
|
-
showMethodWarning("texture");
|
236
|
-
}
|
237
|
-
|
238
|
-
|
239
|
-
@Override
|
240
|
-
public void vertex(float x, float y) {
|
241
|
-
if (vertexCount == vertices.length) {
|
242
|
-
float temp[][] = new float[vertexCount<<1][VERTEX_FIELD_COUNT];
|
243
|
-
System.arraycopy(vertices, 0, temp, 0, vertexCount);
|
244
|
-
vertices = temp;
|
245
|
-
//message(CHATTER, "allocating more vertices " + vertices.length);
|
23
|
+
@Override
|
24
|
+
public void applyMatrix(float n00, float n01, float n02, float n03, float n10, float n11, float n12, float n13, float n20, float n21, float n22, float n23, float n30, float n31, float n32, float n33) {
|
25
|
+
throw new UnsupportedOperationException(message);
|
246
26
|
}
|
247
|
-
// not everyone needs this, but just easier to store rather
|
248
|
-
// than adding another moving part to the code...
|
249
|
-
vertices[vertexCount][X] = x;
|
250
|
-
vertices[vertexCount][Y] = y;
|
251
|
-
vertexCount++;
|
252
|
-
|
253
|
-
switch (shape) {
|
254
|
-
|
255
|
-
case POINTS:
|
256
|
-
point(x, y);
|
257
|
-
break;
|
258
27
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
vertices[vertexCount-2][Y], x, y);
|
263
|
-
}
|
264
|
-
break;
|
265
|
-
|
266
|
-
case TRIANGLES:
|
267
|
-
if ((vertexCount % 3) == 0) {
|
268
|
-
triangle(vertices[vertexCount - 3][X],
|
269
|
-
vertices[vertexCount - 3][Y],
|
270
|
-
vertices[vertexCount - 2][X],
|
271
|
-
vertices[vertexCount - 2][Y],
|
272
|
-
x, y);
|
273
|
-
}
|
274
|
-
break;
|
275
|
-
|
276
|
-
case TRIANGLE_STRIP:
|
277
|
-
if (vertexCount >= 3) {
|
278
|
-
triangle(vertices[vertexCount - 2][X],
|
279
|
-
vertices[vertexCount - 2][Y],
|
280
|
-
vertices[vertexCount - 1][X],
|
281
|
-
vertices[vertexCount - 1][Y],
|
282
|
-
vertices[vertexCount - 3][X],
|
283
|
-
vertices[vertexCount - 3][Y]);
|
284
|
-
}
|
285
|
-
break;
|
286
|
-
|
287
|
-
case TRIANGLE_FAN:
|
288
|
-
if (vertexCount >= 3) {
|
289
|
-
// This is an unfortunate implementation because the stroke for an
|
290
|
-
// adjacent triangle will be repeated. However, if the stroke is not
|
291
|
-
// redrawn, it will replace the adjacent line (when it lines up
|
292
|
-
// perfectly) or show a faint line (when off by a small amount).
|
293
|
-
// The alternative would be to wait, then draw the shape as a
|
294
|
-
// polygon fill, followed by a series of vertices. But that's a
|
295
|
-
// poor method when used with PDF, DXF, or other recording objects,
|
296
|
-
// since discrete triangles would likely be preferred.
|
297
|
-
triangle(vertices[0][X],
|
298
|
-
vertices[0][Y],
|
299
|
-
vertices[vertexCount - 2][X],
|
300
|
-
vertices[vertexCount - 2][Y],
|
301
|
-
x, y);
|
302
|
-
}
|
303
|
-
break;
|
304
|
-
|
305
|
-
case QUAD:
|
306
|
-
case QUADS:
|
307
|
-
if ((vertexCount % 4) == 0) {
|
308
|
-
quad(vertices[vertexCount - 4][X],
|
309
|
-
vertices[vertexCount - 4][Y],
|
310
|
-
vertices[vertexCount - 3][X],
|
311
|
-
vertices[vertexCount - 3][Y],
|
312
|
-
vertices[vertexCount - 2][X],
|
313
|
-
vertices[vertexCount - 2][Y],
|
314
|
-
x, y);
|
315
|
-
}
|
316
|
-
break;
|
317
|
-
|
318
|
-
case QUAD_STRIP:
|
319
|
-
// 0---2---4
|
320
|
-
// | | |
|
321
|
-
// 1---3---5
|
322
|
-
if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) {
|
323
|
-
quad(vertices[vertexCount - 4][X],
|
324
|
-
vertices[vertexCount - 4][Y],
|
325
|
-
vertices[vertexCount - 2][X],
|
326
|
-
vertices[vertexCount - 2][Y],
|
327
|
-
x, y,
|
328
|
-
vertices[vertexCount - 3][X],
|
329
|
-
vertices[vertexCount - 3][Y]);
|
330
|
-
}
|
331
|
-
break;
|
332
|
-
|
333
|
-
case POLYGON:
|
334
|
-
if (workPath.getNumCommands() == 0 || breakShape) {
|
335
|
-
workPath.moveTo(x, y);
|
336
|
-
breakShape = false;
|
337
|
-
} else {
|
338
|
-
workPath.lineTo(x, y);
|
339
|
-
}
|
340
|
-
break;
|
341
|
-
}
|
342
|
-
}
|
343
|
-
|
344
|
-
|
345
|
-
@Override
|
346
|
-
public void vertex(float x, float y, float z) {
|
347
|
-
showDepthWarningXYZ("vertex");
|
348
|
-
}
|
349
|
-
|
350
|
-
|
351
|
-
@Override
|
352
|
-
public void vertex(float[] v) {
|
353
|
-
vertex(v[X], v[Y]);
|
354
|
-
}
|
355
|
-
|
356
|
-
|
357
|
-
@Override
|
358
|
-
public void vertex(float x, float y, float u, float v) {
|
359
|
-
showVariationWarning("vertex(x, y, u, v)");
|
360
|
-
}
|
361
|
-
|
362
|
-
|
363
|
-
@Override
|
364
|
-
public void vertex(float x, float y, float z, float u, float v) {
|
365
|
-
showDepthWarningXYZ("vertex");
|
366
|
-
}
|
367
|
-
|
368
|
-
|
369
|
-
@Override
|
370
|
-
public void beginContour() {
|
371
|
-
if (openContour) {
|
372
|
-
PGraphics.showWarning("Already called beginContour()");
|
373
|
-
return;
|
374
|
-
}
|
375
|
-
|
376
|
-
// draw contours to auxiliary path so main path can be closed later
|
377
|
-
Path2D contourPath = auxPath;
|
378
|
-
auxPath = workPath;
|
379
|
-
workPath = contourPath;
|
380
|
-
|
381
|
-
if (contourPath.getNumCommands() > 0) { // first contour does not break
|
382
|
-
breakShape = true;
|
383
|
-
}
|
384
|
-
|
385
|
-
openContour = true;
|
386
|
-
}
|
387
|
-
|
388
|
-
|
389
|
-
@Override
|
390
|
-
public void endContour() {
|
391
|
-
if (!openContour) {
|
392
|
-
PGraphics.showWarning("Need to call beginContour() first");
|
393
|
-
return;
|
394
|
-
}
|
395
|
-
|
396
|
-
if (workPath.getNumCommands() > 0) workPath.closePath();
|
397
|
-
|
398
|
-
Path2D temp = workPath;
|
399
|
-
workPath = auxPath;
|
400
|
-
auxPath = temp;
|
401
|
-
|
402
|
-
openContour = false;
|
403
|
-
}
|
404
|
-
|
405
|
-
|
406
|
-
@Override
|
407
|
-
public void endShape(int mode) {
|
408
|
-
if (openContour) { // correct automagically, notify user
|
409
|
-
endContour();
|
410
|
-
PGraphics.showWarning("Missing endContour() before endShape()");
|
411
|
-
}
|
412
|
-
if (workPath.getNumCommands() > 0) {
|
413
|
-
if (shape == POLYGON) {
|
414
|
-
if (mode == CLOSE) {
|
415
|
-
workPath.closePath();
|
416
|
-
}
|
417
|
-
if (auxPath.getNumCommands() > 0) {
|
418
|
-
workPath.append(auxPath, false);
|
419
|
-
}
|
420
|
-
drawShape(workPath);
|
421
|
-
}
|
422
|
-
}
|
423
|
-
shape = 0;
|
424
|
-
if (adjustedForThinLines) {
|
425
|
-
adjustedForThinLines = false;
|
426
|
-
translate(-0.5f, -0.5f);
|
28
|
+
@Override
|
29
|
+
protected void backgroundImpl(){
|
30
|
+
throw new UnsupportedOperationException(message);
|
427
31
|
}
|
428
|
-
loaded = false;
|
429
|
-
}
|
430
32
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
PathIterator pi = s.getPathIterator(null);
|
435
|
-
while (!pi.isDone()) {
|
436
|
-
int pitype = pi.currentSegment(pathCoordsBuffer);
|
437
|
-
switch (pitype) {
|
438
|
-
case PathIterator.SEG_MOVETO:
|
439
|
-
context.moveTo(pathCoordsBuffer[0], pathCoordsBuffer[1]);
|
440
|
-
break;
|
441
|
-
case PathIterator.SEG_LINETO:
|
442
|
-
context.lineTo(pathCoordsBuffer[0], pathCoordsBuffer[1]);
|
443
|
-
break;
|
444
|
-
case PathIterator.SEG_QUADTO:
|
445
|
-
context.quadraticCurveTo(pathCoordsBuffer[0], pathCoordsBuffer[1],
|
446
|
-
pathCoordsBuffer[2], pathCoordsBuffer[3]);
|
447
|
-
break;
|
448
|
-
case PathIterator.SEG_CUBICTO:
|
449
|
-
context.bezierCurveTo(pathCoordsBuffer[0], pathCoordsBuffer[1],
|
450
|
-
pathCoordsBuffer[2], pathCoordsBuffer[3],
|
451
|
-
pathCoordsBuffer[4], pathCoordsBuffer[5]);
|
452
|
-
break;
|
453
|
-
case PathIterator.SEG_CLOSE:
|
454
|
-
context.closePath();
|
455
|
-
break;
|
456
|
-
default:
|
457
|
-
showWarning("Unknown segment type " + pitype);
|
458
|
-
}
|
459
|
-
pi.next();
|
33
|
+
@Override
|
34
|
+
public void beginContour() {
|
35
|
+
throw new UnsupportedOperationException(message);
|
460
36
|
}
|
461
|
-
if (fill) context.fill();
|
462
|
-
if (stroke) context.stroke();
|
463
|
-
}
|
464
|
-
|
465
|
-
|
466
37
|
|
467
|
-
//////////////////////////////////////////////////////////////
|
468
38
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
@Override
|
473
|
-
protected void clipImpl(float x1, float y1, float x2, float y2) {
|
474
|
-
//g2.setClip(new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
|
475
|
-
showTodoWarning("clip()", 3274);
|
476
|
-
}
|
477
|
-
|
478
|
-
|
479
|
-
@Override
|
480
|
-
public void noClip() {
|
481
|
-
//g2.setClip(null);
|
482
|
-
showTodoWarning("noClip()", 3274);
|
483
|
-
}
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
//////////////////////////////////////////////////////////////
|
488
|
-
|
489
|
-
// BLEND
|
490
|
-
|
491
|
-
|
492
|
-
@Override
|
493
|
-
protected void blendModeImpl() {
|
494
|
-
BlendMode mode = BlendMode.SRC_OVER;
|
495
|
-
switch (blendMode) {
|
496
|
-
case REPLACE: showWarning("blendMode(REPLACE) is not supported"); break;
|
497
|
-
case BLEND: break; // this is SRC_OVER, the default
|
498
|
-
case ADD: mode = BlendMode.ADD; break; // everyone's favorite
|
499
|
-
case SUBTRACT: showWarning("blendMode(SUBTRACT) is not supported"); break;
|
500
|
-
case LIGHTEST: mode = BlendMode.LIGHTEN; break;
|
501
|
-
case DARKEST: mode = BlendMode.DARKEN; break;
|
502
|
-
case DIFFERENCE: mode = BlendMode.DIFFERENCE; break;
|
503
|
-
case EXCLUSION: mode = BlendMode.EXCLUSION; break;
|
504
|
-
case MULTIPLY: mode = BlendMode.MULTIPLY; break;
|
505
|
-
case SCREEN: mode = BlendMode.SCREEN; break;
|
506
|
-
case OVERLAY: mode = BlendMode.OVERLAY; break;
|
507
|
-
case HARD_LIGHT: mode = BlendMode.HARD_LIGHT; break;
|
508
|
-
case SOFT_LIGHT: mode = BlendMode.SOFT_LIGHT; break;
|
509
|
-
case DODGE: mode = BlendMode.COLOR_DODGE; break;
|
510
|
-
case BURN: mode = BlendMode.COLOR_BURN; break;
|
39
|
+
@Override
|
40
|
+
public void beginDraw() {
|
41
|
+
throw new UnsupportedOperationException(message);
|
511
42
|
}
|
512
|
-
context.setGlobalBlendMode(mode);
|
513
|
-
}
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
//////////////////////////////////////////////////////////////
|
518
43
|
|
519
|
-
// BEZIER VERTICES
|
520
44
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
if (shape == 0 || shape != POLYGON) {
|
525
|
-
throw new RuntimeException("beginShape() or beginShape(POLYGON) " +
|
526
|
-
"must be used before bezierVertex() or quadraticVertex()");
|
527
|
-
}
|
528
|
-
if (workPath.getNumCommands() == 0) {
|
529
|
-
throw new RuntimeException("vertex() must be used at least once " +
|
530
|
-
"before bezierVertex() or quadraticVertex()");
|
45
|
+
@Override
|
46
|
+
public void beginShape(int kind) {
|
47
|
+
throw new UnsupportedOperationException(message);
|
531
48
|
}
|
532
|
-
}
|
533
|
-
|
534
|
-
@Override
|
535
|
-
public void bezierVertex(float x1, float y1,
|
536
|
-
float x2, float y2,
|
537
|
-
float x3, float y3) {
|
538
|
-
bezierVertexCheck();
|
539
|
-
workPath.curveTo(x1, y1, x2, y2, x3, y3);
|
540
|
-
}
|
541
|
-
|
542
|
-
|
543
|
-
@Override
|
544
|
-
public void bezierVertex(float x2, float y2, float z2,
|
545
|
-
float x3, float y3, float z3,
|
546
|
-
float x4, float y4, float z4) {
|
547
|
-
showDepthWarningXYZ("bezierVertex");
|
548
|
-
}
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
//////////////////////////////////////////////////////////////
|
553
|
-
|
554
|
-
// QUADRATIC BEZIER VERTICES
|
555
|
-
|
556
|
-
|
557
|
-
@Override
|
558
|
-
public void quadraticVertex(float ctrlX, float ctrlY,
|
559
|
-
float endX, float endY) {
|
560
|
-
bezierVertexCheck();
|
561
|
-
workPath.quadTo(ctrlX, ctrlY, endX, endY);
|
562
|
-
}
|
563
|
-
|
564
|
-
|
565
|
-
@Override
|
566
|
-
public void quadraticVertex(float x2, float y2, float z2,
|
567
|
-
float x4, float y4, float z4) {
|
568
|
-
showDepthWarningXYZ("quadVertex");
|
569
|
-
}
|
570
|
-
|
571
49
|
|
572
50
|
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
@Override
|
579
|
-
protected void curveVertexSegment(float x1, float y1,
|
580
|
-
float x2, float y2,
|
581
|
-
float x3, float y3,
|
582
|
-
float x4, float y4) {
|
583
|
-
if (curveCoordX == null) {
|
584
|
-
curveCoordX = new float[4];
|
585
|
-
curveCoordY = new float[4];
|
586
|
-
curveDrawX = new float[4];
|
587
|
-
curveDrawY = new float[4];
|
51
|
+
@Override
|
52
|
+
public void bezierDetail(int detail) {
|
53
|
+
throw new UnsupportedOperationException(message);
|
588
54
|
}
|
589
55
|
|
590
|
-
curveCoordX[0] = x1;
|
591
|
-
curveCoordY[0] = y1;
|
592
|
-
|
593
|
-
curveCoordX[1] = x2;
|
594
|
-
curveCoordY[1] = y2;
|
595
|
-
|
596
|
-
curveCoordX[2] = x3;
|
597
|
-
curveCoordY[2] = y3;
|
598
|
-
|
599
|
-
curveCoordX[3] = x4;
|
600
|
-
curveCoordY[3] = y4;
|
601
|
-
|
602
|
-
curveToBezierMatrix.mult(curveCoordX, curveDrawX);
|
603
|
-
curveToBezierMatrix.mult(curveCoordY, curveDrawY);
|
604
56
|
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
workPath.moveTo(curveDrawX[0], curveDrawY[0]);
|
609
|
-
breakShape = false;
|
57
|
+
@Override
|
58
|
+
public void bezierVertex(float x1, float y1, float x2, float y2, float x3, float y3) {
|
59
|
+
throw new UnsupportedOperationException(message);
|
610
60
|
}
|
611
61
|
|
612
|
-
workPath.curveTo(curveDrawX[1], curveDrawY[1],
|
613
|
-
curveDrawX[2], curveDrawY[2],
|
614
|
-
curveDrawX[3], curveDrawY[3]);
|
615
|
-
}
|
616
|
-
|
617
|
-
|
618
|
-
@Override
|
619
|
-
public void curveVertex(float x, float y, float z) {
|
620
|
-
showDepthWarningXYZ("curveVertex");
|
621
|
-
}
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
//////////////////////////////////////////////////////////////
|
626
|
-
|
627
|
-
// RENDERER
|
628
62
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
}
|
633
|
-
|
634
|
-
|
635
|
-
protected void flushPixels() {
|
636
|
-
boolean hasPixels = modified && pixels != null;
|
637
|
-
if (hasPixels) {
|
638
|
-
// If the user has been manipulating individual pixels,
|
639
|
-
// the changes need to be copied to the screen before
|
640
|
-
// drawing any new geometry.
|
641
|
-
int mx1 = getModifiedX1();
|
642
|
-
int mx2 = getModifiedX2();
|
643
|
-
int my1 = getModifiedY1();
|
644
|
-
int my2 = getModifiedY2();
|
645
|
-
int mw = mx2 - mx1;
|
646
|
-
int mh = my2 - my1;
|
647
|
-
|
648
|
-
if (pixelDensity == 1) {
|
649
|
-
PixelWriter pw = context.getPixelWriter();
|
650
|
-
pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels,
|
651
|
-
mx1 + my1 * pixelWidth, pixelWidth);
|
652
|
-
} else {
|
653
|
-
// The only way to push all the pixels is to draw a scaled-down image
|
654
|
-
if (snapshotImage == null ||
|
655
|
-
snapshotImage.getWidth() != pixelWidth ||
|
656
|
-
snapshotImage.getHeight() != pixelHeight) {
|
657
|
-
snapshotImage = new WritableImage(pixelWidth, pixelHeight);
|
658
|
-
}
|
659
|
-
|
660
|
-
PixelWriter pw = snapshotImage.getPixelWriter();
|
661
|
-
pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels,
|
662
|
-
mx1 + my1 * pixelWidth, pixelWidth);
|
663
|
-
context.save();
|
664
|
-
resetMatrix();
|
665
|
-
context.scale(1d / pixelDensity, 1d / pixelDensity);
|
666
|
-
context.drawImage(snapshotImage, mx1, my1, mw, mh, mx1, my1, mw, mh);
|
667
|
-
context.restore();
|
668
|
-
}
|
63
|
+
@Override
|
64
|
+
public void bezierVertex(float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4) {
|
65
|
+
throw new UnsupportedOperationException(message);
|
669
66
|
}
|
670
67
|
|
671
|
-
modified = false;
|
672
|
-
}
|
673
|
-
|
674
|
-
|
675
|
-
protected void beforeContextDraw() {
|
676
|
-
flushPixels();
|
677
|
-
loaded = false;
|
678
|
-
}
|
679
|
-
|
680
68
|
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
@Override
|
687
|
-
public void point(float x, float y) {
|
688
|
-
if (stroke) {
|
689
|
-
// if (strokeWeight > 1) {
|
690
|
-
line(x, y, x + EPSILON, y + EPSILON);
|
691
|
-
// } else {
|
692
|
-
// set((int) screenX(x, y), (int) screenY(x, y), strokeColor);
|
693
|
-
// }
|
69
|
+
@Override
|
70
|
+
public void box(float w, float h, float d) {
|
71
|
+
throw new UnsupportedOperationException(message);
|
694
72
|
}
|
695
|
-
}
|
696
73
|
|
697
74
|
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
if (drawingThinLines()) {
|
702
|
-
x1 += 0.5f;
|
703
|
-
x2 += 0.5f;
|
704
|
-
y1 += 0.5f;
|
705
|
-
y2 += 0.5f;
|
75
|
+
@Override
|
76
|
+
public PSurface createSurface() {
|
77
|
+
throw new UnsupportedOperationException(message);
|
706
78
|
}
|
707
|
-
context.strokeLine(x1, y1, x2, y2);
|
708
|
-
}
|
709
79
|
|
710
80
|
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
beforeContextDraw();
|
715
|
-
if (drawingThinLines()) {
|
716
|
-
x1 += 0.5f;
|
717
|
-
x2 += 0.5f;
|
718
|
-
x3 += 0.5f;
|
719
|
-
y1 += 0.5f;
|
720
|
-
y2 += 0.5f;
|
721
|
-
y3 += 0.5f;
|
81
|
+
@Override
|
82
|
+
public void curveDetail(int detail) {
|
83
|
+
throw new UnsupportedOperationException(message);
|
722
84
|
}
|
723
|
-
context.beginPath();
|
724
|
-
context.moveTo(x1, y1);
|
725
|
-
context.lineTo(x2, y2);
|
726
|
-
context.lineTo(x3, y3);
|
727
|
-
context.closePath();
|
728
|
-
if (fill) context.fill();
|
729
|
-
if (stroke) context.stroke();
|
730
|
-
}
|
731
85
|
|
732
86
|
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
beforeContextDraw();
|
737
|
-
if (drawingThinLines()) {
|
738
|
-
x1 += 0.5f;
|
739
|
-
x2 += 0.5f;
|
740
|
-
x3 += 0.5f;
|
741
|
-
x4 += 0.5f;
|
742
|
-
y1 += 0.5f;
|
743
|
-
y2 += 0.5f;
|
744
|
-
y3 += 0.5f;
|
745
|
-
y4 += 0.5f;
|
87
|
+
@Override
|
88
|
+
public void curveVertex(float x, float y, float z) {
|
89
|
+
throw new UnsupportedOperationException(message);
|
746
90
|
}
|
747
|
-
context.beginPath();
|
748
|
-
context.moveTo(x1, y1);
|
749
|
-
context.lineTo(x2, y2);
|
750
|
-
context.lineTo(x3, y3);
|
751
|
-
context.lineTo(x4, y4);
|
752
|
-
context.closePath();
|
753
|
-
if (fill) context.fill();
|
754
|
-
if (stroke) context.stroke();
|
755
|
-
}
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
//////////////////////////////////////////////////////////////
|
760
|
-
|
761
|
-
// RECT
|
762
91
|
|
763
92
|
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
//public void rect(float a, float b, float c, float d)
|
768
|
-
|
769
|
-
|
770
|
-
@Override
|
771
|
-
protected void rectImpl(float x1, float y1, float x2, float y2) {
|
772
|
-
beforeContextDraw();
|
773
|
-
if (drawingThinLines()) {
|
774
|
-
x1 += 0.5f;
|
775
|
-
x2 += 0.5f;
|
776
|
-
y1 += 0.5f;
|
777
|
-
y2 += 0.5f;
|
93
|
+
@Override
|
94
|
+
public void endContour() {
|
95
|
+
throw new UnsupportedOperationException(message);
|
778
96
|
}
|
779
|
-
if (fill) context.fillRect(x1, y1, x2 - x1, y2 - y1);
|
780
|
-
if (stroke) context.strokeRect(x1, y1, x2 - x1, y2 - y1);
|
781
|
-
}
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
//////////////////////////////////////////////////////////////
|
786
97
|
|
787
|
-
// ELLIPSE
|
788
98
|
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
//public void ellipse(float a, float b, float c, float d)
|
794
|
-
|
795
|
-
|
796
|
-
@Override
|
797
|
-
protected void ellipseImpl(float x, float y, float w, float h) {
|
798
|
-
beforeContextDraw();
|
799
|
-
if (drawingThinLines()) {
|
800
|
-
x += 0.5f;
|
801
|
-
y += 0.5f;
|
99
|
+
@Override
|
100
|
+
public void endDraw() {
|
101
|
+
throw new UnsupportedOperationException(message);
|
802
102
|
}
|
803
|
-
if (fill) context.fillOval(x, y, w, h);
|
804
|
-
if (stroke) context.strokeOval(x, y, w, h);
|
805
|
-
}
|
806
|
-
|
807
103
|
|
808
104
|
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
//public void arc(float a, float b, float c, float d,
|
815
|
-
// float start, float stop)
|
816
|
-
|
817
|
-
|
818
|
-
@Override
|
819
|
-
protected void arcImpl(float x, float y, float w, float h,
|
820
|
-
float start, float stop, int mode) {
|
821
|
-
beforeContextDraw();
|
822
|
-
|
823
|
-
if (drawingThinLines()) {
|
824
|
-
x += 0.5f;
|
825
|
-
y += 0.5f;
|
105
|
+
@Override
|
106
|
+
public void endShape(int mode) {
|
107
|
+
throw new UnsupportedOperationException(message);
|
826
108
|
}
|
827
109
|
|
828
|
-
// 0 to 90 in java would be 0 to -90 for p5 renderer
|
829
|
-
// but that won't work, so -90 to 0?
|
830
|
-
start = -start;
|
831
|
-
stop = -stop;
|
832
|
-
|
833
|
-
float sweep = stop - start;
|
834
110
|
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
ArcType strokeMode = ArcType.OPEN;
|
839
|
-
|
840
|
-
if (mode == OPEN) {
|
841
|
-
fillMode = ArcType.OPEN;
|
842
|
-
|
843
|
-
} else if (mode == PIE) {
|
844
|
-
strokeMode = ArcType.ROUND; // PIE
|
845
|
-
|
846
|
-
} else if (mode == CHORD) {
|
847
|
-
fillMode = ArcType.CHORD;
|
848
|
-
strokeMode = ArcType.CHORD;
|
111
|
+
@Override
|
112
|
+
public void flush() {
|
113
|
+
throw new UnsupportedOperationException(message);
|
849
114
|
}
|
850
115
|
|
851
|
-
if (fill) {
|
852
|
-
context.fillArc(x, y, w, h, PApplet.degrees(start), PApplet.degrees(sweep), fillMode);
|
853
|
-
}
|
854
|
-
if (stroke) {
|
855
|
-
context.strokeArc(x, y, w, h, PApplet.degrees(start), PApplet.degrees(sweep), strokeMode);
|
856
|
-
}
|
857
|
-
}
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
//////////////////////////////////////////////////////////////
|
862
|
-
|
863
|
-
// BOX
|
864
|
-
|
865
|
-
|
866
|
-
//public void box(float size)
|
867
|
-
|
868
|
-
|
869
|
-
@Override
|
870
|
-
public void box(float w, float h, float d) {
|
871
|
-
showMethodWarning("box");
|
872
|
-
}
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
//////////////////////////////////////////////////////////////
|
877
|
-
|
878
|
-
// SPHERE
|
879
|
-
|
880
|
-
|
881
|
-
//public void sphereDetail(int res)
|
882
|
-
|
883
|
-
|
884
|
-
//public void sphereDetail(int ures, int vres)
|
885
|
-
|
886
|
-
|
887
|
-
@Override
|
888
|
-
public void sphere(float r) {
|
889
|
-
showMethodWarning("sphere");
|
890
|
-
}
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
//////////////////////////////////////////////////////////////
|
895
|
-
|
896
|
-
// BEZIER
|
897
|
-
|
898
|
-
|
899
|
-
//public float bezierPoint(float a, float b, float c, float d, float t)
|
900
|
-
|
901
|
-
|
902
|
-
//public float bezierTangent(float a, float b, float c, float d, float t)
|
903
|
-
|
904
|
-
|
905
|
-
//protected void bezierInitCheck()
|
906
|
-
|
907
|
-
|
908
|
-
//protected void bezierInit()
|
909
|
-
|
910
|
-
|
911
|
-
/** Ignored (not needed) by this renderer. */
|
912
|
-
@Override
|
913
|
-
public void bezierDetail(int detail) { }
|
914
|
-
|
915
|
-
|
916
|
-
//public void bezier(float x1, float y1,
|
917
|
-
// float x2, float y2,
|
918
|
-
// float x3, float y3,
|
919
|
-
// float x4, float y4)
|
920
|
-
|
921
|
-
|
922
|
-
//public void bezier(float x1, float y1, float z1,
|
923
|
-
// float x2, float y2, float z2,
|
924
|
-
// float x3, float y3, float z3,
|
925
|
-
// float x4, float y4, float z4)
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
//////////////////////////////////////////////////////////////
|
930
|
-
|
931
|
-
// CURVE
|
932
|
-
|
933
116
|
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
//public float curveTangent(float a, float b, float c, float d, float t)
|
938
|
-
|
939
|
-
|
940
|
-
/** Ignored (not needed) by this renderer. */
|
941
|
-
@Override
|
942
|
-
public void curveDetail(int detail) { }
|
943
|
-
|
944
|
-
|
945
|
-
//public void curveTightness(float tightness)
|
946
|
-
|
947
|
-
|
948
|
-
//protected void curveInitCheck()
|
949
|
-
|
950
|
-
|
951
|
-
//protected void curveInit()
|
952
|
-
|
953
|
-
|
954
|
-
//public void curve(float x1, float y1,
|
955
|
-
// float x2, float y2,
|
956
|
-
// float x3, float y3,
|
957
|
-
// float x4, float y4)
|
958
|
-
|
959
|
-
|
960
|
-
//public void curve(float x1, float y1, float z1,
|
961
|
-
// float x2, float y2, float z2,
|
962
|
-
// float x3, float y3, float z3,
|
963
|
-
// float x4, float y4, float z4)
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
//////////////////////////////////////////////////////////////
|
968
|
-
|
969
|
-
// SMOOTH
|
970
|
-
|
971
|
-
|
972
|
-
// @Override
|
973
|
-
// public void smooth() {
|
974
|
-
// smooth = true;
|
975
|
-
//
|
976
|
-
// if (quality == 0) {
|
977
|
-
// quality = 4; // change back to bicubic
|
978
|
-
// }
|
979
|
-
// }
|
980
|
-
|
981
|
-
|
982
|
-
// @Override
|
983
|
-
// public void smooth(int quality) {
|
984
|
-
//// this.quality = quality;
|
985
|
-
//// if (quality == 0) {
|
986
|
-
//// noSmooth();
|
987
|
-
//// } else {
|
988
|
-
//// smooth();
|
989
|
-
//// }
|
990
|
-
// showMissingWarning("smooth");
|
991
|
-
// }
|
992
|
-
//
|
993
|
-
//
|
994
|
-
// @Override
|
995
|
-
// public void noSmooth() {
|
996
|
-
// showMissingWarning("noSmooth");
|
997
|
-
// }
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
//////////////////////////////////////////////////////////////
|
1002
|
-
|
1003
|
-
// IMAGE
|
1004
|
-
|
1005
|
-
|
1006
|
-
//public void imageMode(int mode)
|
1007
|
-
|
1008
|
-
|
1009
|
-
//public void image(PImage image, float x, float y)
|
1010
|
-
|
1011
|
-
|
1012
|
-
//public void image(PImage image, float x, float y, float c, float d)
|
1013
|
-
|
1014
|
-
|
1015
|
-
//public void image(PImage image,
|
1016
|
-
// float a, float b, float c, float d,
|
1017
|
-
// int u1, int v1, int u2, int v2)
|
1018
|
-
|
1019
|
-
|
1020
|
-
/**
|
1021
|
-
* Handle renderer-specific image drawing.
|
1022
|
-
*/
|
1023
|
-
@Override
|
1024
|
-
protected void imageImpl(PImage who,
|
1025
|
-
float x1, float y1, float x2, float y2,
|
1026
|
-
int u1, int v1, int u2, int v2) {
|
1027
|
-
// Image not ready yet, or an error
|
1028
|
-
if (who.width <= 0 || who.height <= 0) return;
|
1029
|
-
|
1030
|
-
ImageCache cash = (ImageCache) getCache(who);
|
1031
|
-
|
1032
|
-
// Nuke the cache if the image was resized
|
1033
|
-
if (cash != null) {
|
1034
|
-
if (who.pixelWidth != cash.image.getWidth() ||
|
1035
|
-
who.pixelHeight != cash.image.getHeight()) {
|
1036
|
-
cash = null;
|
1037
|
-
}
|
117
|
+
@Override
|
118
|
+
public int get(int x, int y) {
|
119
|
+
throw new UnsupportedOperationException(message);
|
1038
120
|
}
|
1039
121
|
|
1040
|
-
if (cash == null) {
|
1041
|
-
//System.out.println("making new image cache");
|
1042
|
-
cash = new ImageCache(); //who);
|
1043
|
-
setCache(who, cash);
|
1044
|
-
who.updatePixels(); // mark the whole thing for update
|
1045
|
-
who.setModified();
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
// If image previously was tinted, or the color changed
|
1049
|
-
// or the image was tinted, and tint is now disabled
|
1050
|
-
if ((tint && !cash.tinted) ||
|
1051
|
-
(tint && (cash.tintedColor != tintColor)) ||
|
1052
|
-
(!tint && cash.tinted)) {
|
1053
|
-
// For tint change, mark all pixels as needing update.
|
1054
|
-
who.updatePixels();
|
1055
|
-
}
|
1056
|
-
|
1057
|
-
if (who.isModified()) {
|
1058
|
-
if (who.pixels == null) {
|
1059
|
-
// This might be a PGraphics that hasn't been drawn to yet.
|
1060
|
-
// Can't just bail because the cache has been created above.
|
1061
|
-
// https://github.com/processing/processing/issues/2208
|
1062
|
-
who.pixels = new int[who.pixelWidth * who.pixelHeight];
|
1063
|
-
}
|
1064
|
-
cash.update(who, tint, tintColor);
|
1065
|
-
who.setModified(false);
|
1066
|
-
}
|
1067
|
-
|
1068
|
-
u1 *= who.pixelDensity;
|
1069
|
-
v1 *= who.pixelDensity;
|
1070
|
-
u2 *= who.pixelDensity;
|
1071
|
-
v2 *= who.pixelDensity;
|
1072
|
-
|
1073
|
-
context.drawImage(((ImageCache) getCache(who)).image,
|
1074
|
-
u1, v1, u2-u1, v2-v1,
|
1075
|
-
x1, y1, x2-x1, y2-y1);
|
1076
|
-
}
|
1077
|
-
|
1078
|
-
|
1079
|
-
static class ImageCache {
|
1080
|
-
boolean tinted;
|
1081
|
-
int tintedColor;
|
1082
|
-
int[] tintedTemp; // one row of tinted pixels
|
1083
|
-
//BufferedImage image;
|
1084
|
-
WritableImage image;
|
1085
|
-
|
1086
|
-
/**
|
1087
|
-
* Update the pixels of the cache image. Already determined that the tint
|
1088
|
-
* has changed, or the pixels have changed, so should just go through
|
1089
|
-
* with the update without further checks.
|
1090
|
-
*/
|
1091
|
-
public void update(PImage source, boolean tint, int tintColor) {
|
1092
|
-
//int bufferType = BufferedImage.TYPE_INT_ARGB;
|
1093
|
-
int targetType = ARGB;
|
1094
|
-
boolean opaque = (tintColor & 0xFF000000) == 0xFF000000;
|
1095
|
-
if (source.format == RGB) {
|
1096
|
-
if (!tint || (tint && opaque)) {
|
1097
|
-
//bufferType = BufferedImage.TYPE_INT_RGB;
|
1098
|
-
targetType = RGB;
|
1099
|
-
}
|
1100
|
-
}
|
1101
|
-
// boolean wrongType = (image != null) && (image.getType() != bufferType);
|
1102
|
-
// if ((image == null) || wrongType) {
|
1103
|
-
// image = new BufferedImage(source.width, source.height, bufferType);
|
1104
|
-
// }
|
1105
|
-
// Must always use an ARGB image, otherwise will write zeros
|
1106
|
-
// in the alpha channel when drawn to the screen.
|
1107
|
-
// https://github.com/processing/processing/issues/2030
|
1108
|
-
// if (image == null) {
|
1109
|
-
// image = new BufferedImage(source.width, source.height,
|
1110
|
-
// BufferedImage.TYPE_INT_ARGB);
|
1111
|
-
// }
|
1112
|
-
if (image == null) {
|
1113
|
-
image = new WritableImage(source.pixelWidth, source.pixelHeight);
|
1114
|
-
}
|
1115
|
-
|
1116
|
-
//WritableRaster wr = image.getRaster();
|
1117
|
-
PixelWriter pw = image.getPixelWriter();
|
1118
|
-
if (tint) {
|
1119
|
-
if (tintedTemp == null || tintedTemp.length != source.pixelWidth) {
|
1120
|
-
tintedTemp = new int[source.pixelWidth];
|
1121
|
-
}
|
1122
|
-
int a2 = (tintColor >> 24) & 0xff;
|
1123
|
-
// System.out.println("tint color is " + a2);
|
1124
|
-
// System.out.println("source.pixels[0] alpha is " + (source.pixels[0] >>> 24));
|
1125
|
-
int r2 = (tintColor >> 16) & 0xff;
|
1126
|
-
int g2 = (tintColor >> 8) & 0xff;
|
1127
|
-
int b2 = (tintColor) & 0xff;
|
1128
|
-
|
1129
|
-
//if (bufferType == BufferedImage.TYPE_INT_RGB) {
|
1130
|
-
if (targetType == RGB) {
|
1131
|
-
// The target image is opaque, meaning that the source image has no
|
1132
|
-
// alpha (is not ARGB), and the tint has no alpha.
|
1133
|
-
int index = 0;
|
1134
|
-
for (int y = 0; y < source.pixelHeight; y++) {
|
1135
|
-
for (int x = 0; x < source.pixelWidth; x++) {
|
1136
|
-
int argb1 = source.pixels[index++];
|
1137
|
-
int r1 = (argb1 >> 16) & 0xff;
|
1138
|
-
int g1 = (argb1 >> 8) & 0xff;
|
1139
|
-
int b1 = (argb1) & 0xff;
|
1140
|
-
|
1141
|
-
// Prior to 2.1, the alpha channel was commented out here,
|
1142
|
-
// but can't remember why (just thought unnecessary b/c of RGB?)
|
1143
|
-
// https://github.com/processing/processing/issues/2030
|
1144
|
-
tintedTemp[x] = 0xFF000000 |
|
1145
|
-
(((r2 * r1) & 0xff00) << 8) |
|
1146
|
-
((g2 * g1) & 0xff00) |
|
1147
|
-
(((b2 * b1) & 0xff00) >> 8);
|
1148
|
-
}
|
1149
|
-
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
|
1150
|
-
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth);
|
1151
|
-
}
|
1152
|
-
// could this be any slower?
|
1153
|
-
// float[] scales = { tintR, tintG, tintB };
|
1154
|
-
// float[] offsets = new float[3];
|
1155
|
-
// RescaleOp op = new RescaleOp(scales, offsets, null);
|
1156
|
-
// op.filter(image, image);
|
1157
|
-
|
1158
|
-
//} else if (bufferType == BufferedImage.TYPE_INT_ARGB) {
|
1159
|
-
} else if (targetType == ARGB) {
|
1160
|
-
if (source.format == RGB &&
|
1161
|
-
(tintColor & 0xffffff) == 0xffffff) {
|
1162
|
-
int hi = tintColor & 0xff000000;
|
1163
|
-
int index = 0;
|
1164
|
-
for (int y = 0; y < source.pixelHeight; y++) {
|
1165
|
-
for (int x = 0; x < source.pixelWidth; x++) {
|
1166
|
-
tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF);
|
1167
|
-
}
|
1168
|
-
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
|
1169
|
-
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth);
|
1170
|
-
}
|
1171
|
-
} else {
|
1172
|
-
int index = 0;
|
1173
|
-
for (int y = 0; y < source.pixelHeight; y++) {
|
1174
|
-
if (source.format == RGB) {
|
1175
|
-
int alpha = tintColor & 0xFF000000;
|
1176
|
-
for (int x = 0; x < source.pixelWidth; x++) {
|
1177
|
-
int argb1 = source.pixels[index++];
|
1178
|
-
int r1 = (argb1 >> 16) & 0xff;
|
1179
|
-
int g1 = (argb1 >> 8) & 0xff;
|
1180
|
-
int b1 = (argb1) & 0xff;
|
1181
|
-
tintedTemp[x] = alpha |
|
1182
|
-
(((r2 * r1) & 0xff00) << 8) |
|
1183
|
-
((g2 * g1) & 0xff00) |
|
1184
|
-
(((b2 * b1) & 0xff00) >> 8);
|
1185
|
-
}
|
1186
|
-
} else if (source.format == ARGB) {
|
1187
|
-
for (int x = 0; x < source.pixelWidth; x++) {
|
1188
|
-
int argb1 = source.pixels[index++];
|
1189
|
-
int a1 = (argb1 >> 24) & 0xff;
|
1190
|
-
int r1 = (argb1 >> 16) & 0xff;
|
1191
|
-
int g1 = (argb1 >> 8) & 0xff;
|
1192
|
-
int b1 = (argb1) & 0xff;
|
1193
|
-
tintedTemp[x] =
|
1194
|
-
(((a2 * a1) & 0xff00) << 16) |
|
1195
|
-
(((r2 * r1) & 0xff00) << 8) |
|
1196
|
-
((g2 * g1) & 0xff00) |
|
1197
|
-
(((b2 * b1) & 0xff00) >> 8);
|
1198
|
-
}
|
1199
|
-
} else if (source.format == ALPHA) {
|
1200
|
-
int lower = tintColor & 0xFFFFFF;
|
1201
|
-
for (int x = 0; x < source.pixelWidth; x++) {
|
1202
|
-
int a1 = source.pixels[index++];
|
1203
|
-
tintedTemp[x] =
|
1204
|
-
(((a2 * a1) & 0xff00) << 16) | lower;
|
1205
|
-
}
|
1206
|
-
}
|
1207
|
-
//wr.setDataElements(0, y, source.width, 1, tintedTemp);
|
1208
|
-
pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth);
|
1209
|
-
}
|
1210
|
-
}
|
1211
|
-
// Not sure why ARGB images take the scales in this order...
|
1212
|
-
// float[] scales = { tintR, tintG, tintB, tintA };
|
1213
|
-
// float[] offsets = new float[4];
|
1214
|
-
// RescaleOp op = new RescaleOp(scales, offsets, null);
|
1215
|
-
// op.filter(image, image);
|
1216
|
-
}
|
1217
|
-
} else { // !tint
|
1218
|
-
if (targetType == RGB && (source.pixels[0] >> 24 == 0)) {
|
1219
|
-
// If it's an RGB image and the high bits aren't set, need to set
|
1220
|
-
// the high bits to opaque because we're drawing ARGB images.
|
1221
|
-
source.filter(OPAQUE);
|
1222
|
-
// Opting to just manipulate the image here, since it shouldn't
|
1223
|
-
// affect anything else (and alpha(get(x, y)) should return 0xff).
|
1224
|
-
// Wel also make no guarantees about the values of the pixels array
|
1225
|
-
// in a PImage and how the high bits will be set.
|
1226
|
-
}
|
1227
|
-
// If no tint, just shove the pixels on in there verbatim
|
1228
|
-
//wr.setDataElements(0, 0, source.width, source.height, source.pixels);
|
1229
|
-
//System.out.println("moving the big one");
|
1230
|
-
pw.setPixels(0, 0, source.pixelWidth, source.pixelHeight,
|
1231
|
-
argbFormat, source.pixels, 0, source.pixelWidth);
|
1232
|
-
}
|
1233
|
-
this.tinted = tint;
|
1234
|
-
this.tintedColor = tintColor;
|
1235
|
-
|
1236
|
-
// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
|
1237
|
-
// compat = gc.createCompatibleImage(image.getWidth(),
|
1238
|
-
// image.getHeight(),
|
1239
|
-
// Transparency.TRANSLUCENT);
|
1240
|
-
//
|
1241
|
-
// Graphics2D g = compat.createGraphics();
|
1242
|
-
// g.drawImage(image, 0, 0, null);
|
1243
|
-
// g.dispose();
|
1244
|
-
}
|
1245
|
-
}
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
//////////////////////////////////////////////////////////////
|
1250
|
-
|
1251
|
-
// SHAPE
|
1252
|
-
|
1253
|
-
|
1254
|
-
//public void shapeMode(int mode)
|
1255
|
-
|
1256
|
-
|
1257
|
-
//public void shape(PShape shape)
|
1258
|
-
|
1259
|
-
|
1260
|
-
//public void shape(PShape shape, float x, float y)
|
1261
|
-
|
1262
|
-
|
1263
|
-
//public void shape(PShape shape, float x, float y, float c, float d)
|
1264
|
-
|
1265
|
-
|
1266
|
-
//////////////////////////////////////////////////////////////
|
1267
|
-
|
1268
|
-
// SHAPE I/O
|
1269
|
-
|
1270
122
|
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
}
|
1275
|
-
|
1276
|
-
|
1277
|
-
@Override
|
1278
|
-
public PShape loadShape(String filename, String options) {
|
1279
|
-
String extension = PApplet.getExtension(filename);
|
1280
|
-
if (extension.equals("svg") || extension.equals("svgz")) {
|
1281
|
-
return new PShapeSVG(parent.loadXML(filename));
|
123
|
+
@Override
|
124
|
+
public PMatrix getMatrix() {
|
125
|
+
throw new UnsupportedOperationException(message);
|
1282
126
|
}
|
1283
|
-
PGraphics.showWarning("Unsupported format: " + filename);
|
1284
|
-
return null;
|
1285
|
-
}
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
//////////////////////////////////////////////////////////////
|
1290
|
-
|
1291
|
-
// TEXT ATTRIBTUES
|
1292
|
-
|
1293
127
|
|
1294
|
-
protected FontCache fontCache = new FontCache();
|
1295
128
|
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
@Override
|
1302
|
-
protected PFont createFont(String name, float size,
|
1303
|
-
boolean smooth, char[] charset) {
|
1304
|
-
PFont font = super.createFont(name, size, smooth, charset);
|
1305
|
-
if (font.isStream()) {
|
1306
|
-
fontCache.nameToFilename.put(font.getName(), name);
|
129
|
+
@Override
|
130
|
+
public PMatrix2D getMatrix(PMatrix2D target) {
|
131
|
+
throw new UnsupportedOperationException(message);
|
1307
132
|
}
|
1308
|
-
return font;
|
1309
|
-
}
|
1310
|
-
|
1311
|
-
|
1312
|
-
@Override
|
1313
|
-
protected void defaultFontOrDeath(String method, float size) {
|
1314
|
-
super.defaultFontOrDeath(method, size);
|
1315
|
-
handleTextFont(textFont, size);
|
1316
|
-
}
|
1317
|
-
|
1318
|
-
|
1319
|
-
@Override
|
1320
|
-
protected boolean textModeCheck(int mode) {
|
1321
|
-
return mode == MODEL;
|
1322
|
-
}
|
1323
133
|
|
1324
134
|
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
defaultFontOrDeath("textAscent");
|
135
|
+
@Override
|
136
|
+
public PMatrix3D getMatrix(PMatrix3D target) {
|
137
|
+
throw new UnsupportedOperationException(message);
|
1329
138
|
}
|
1330
|
-
if (textFontInfo.font == null) {
|
1331
|
-
return super.textAscent();
|
1332
|
-
}
|
1333
|
-
return textFontInfo.ascent;
|
1334
|
-
}
|
1335
139
|
|
1336
140
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
defaultFontOrDeath("textDescent");
|
1341
|
-
}
|
1342
|
-
if (textFontInfo.font == null) {
|
1343
|
-
return super.textDescent();
|
141
|
+
@Override
|
142
|
+
public Object getNative() {
|
143
|
+
throw new UnsupportedOperationException(message);
|
1344
144
|
}
|
1345
|
-
return textFontInfo.descent;
|
1346
|
-
}
|
1347
|
-
|
1348
|
-
|
1349
|
-
static final class FontInfo {
|
1350
|
-
// TODO: this should be based on memory consumption
|
1351
|
-
// this should be enough e.g. for all grays and alpha combos
|
1352
|
-
static final int MAX_CACHED_COLORS_PER_FONT = 1 << 16;
|
1353
|
-
|
1354
|
-
// used only when there is native font
|
1355
|
-
Font font;
|
1356
|
-
float ascent;
|
1357
|
-
float descent;
|
1358
|
-
|
1359
|
-
// used only when there is no native font
|
1360
|
-
// maps 32-bit color to the arrays of tinted glyph images
|
1361
|
-
Map<Integer, PImage[]> tintCache;
|
1362
|
-
}
|
1363
|
-
|
1364
145
|
|
1365
|
-
static final class FontCache {
|
1366
|
-
static final int MAX_CACHE_SIZE = 512;
|
1367
146
|
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
// keeps track of fonts which should be rendered as pictures
|
1372
|
-
// so we don't go through native font search process every time
|
1373
|
-
final HashSet<String> nonNativeNames = new HashSet<>();
|
1374
|
-
|
1375
|
-
// keeps all created fonts for reuse up to MAX_CACHE_SIZE limit
|
1376
|
-
// when the limit is reached, the least recently used font is removed
|
1377
|
-
// TODO: this should be based on memory consumtion
|
1378
|
-
final LinkedHashMap<Key, FontInfo> cache =
|
1379
|
-
new LinkedHashMap<Key, FontInfo>(16, 0.75f, true) {
|
1380
|
-
@Override
|
1381
|
-
protected boolean removeEldestEntry(Map.Entry<Key, FontInfo> eldest) {
|
1382
|
-
return size() > MAX_CACHE_SIZE;
|
1383
|
-
}
|
1384
|
-
};
|
1385
|
-
|
1386
|
-
// key for retrieving fonts from cache; don't use for insertion,
|
1387
|
-
// every font has to have its own new Key instance
|
1388
|
-
final Key retrievingKey = new Key();
|
1389
|
-
|
1390
|
-
// text node used for measuring sizes of text
|
1391
|
-
final Text measuringText = new Text();
|
1392
|
-
|
1393
|
-
FontInfo get(String name, float size) {
|
1394
|
-
if (nonNativeNames.contains(name)) {
|
1395
|
-
// Don't have native font, using glyph images.
|
1396
|
-
// Size is set to zero, because all sizes of this font
|
1397
|
-
// should share one FontInfo with one tintCache.
|
1398
|
-
size = 0;
|
1399
|
-
}
|
1400
|
-
retrievingKey.name = name;
|
1401
|
-
retrievingKey.size = size;
|
1402
|
-
return cache.get(retrievingKey);
|
147
|
+
@Override
|
148
|
+
public void line(float x1, float y1, float x2, float y2) {
|
149
|
+
throw new UnsupportedOperationException(message);
|
1403
150
|
}
|
1404
151
|
|
1405
|
-
void put(String name, float size, FontInfo fontInfo) {
|
1406
|
-
if (fontInfo.font == null) {
|
1407
|
-
// Don't have native font, using glyph images.
|
1408
|
-
// Size is set to zero, because all sizes of this font
|
1409
|
-
// should share one FontInfo with one tintCache.
|
1410
|
-
nonNativeNames.add(name);
|
1411
|
-
size = 0;
|
1412
|
-
}
|
1413
|
-
Key key = new Key();
|
1414
|
-
key.name = name;
|
1415
|
-
key.size = size;
|
1416
|
-
cache.put(key, fontInfo);
|
1417
|
-
}
|
1418
|
-
|
1419
|
-
FontInfo createFontInfo(Font font) {
|
1420
|
-
FontInfo result = new FontInfo();
|
1421
|
-
result.font = font;
|
1422
|
-
if (font != null) {
|
1423
|
-
// measure ascent and descent
|
1424
|
-
measuringText.setFont(result.font);
|
1425
|
-
measuringText.setText(" ");
|
1426
|
-
float lineHeight = (float) measuringText.getLayoutBounds().getHeight();
|
1427
|
-
result.ascent = (float) measuringText.getBaselineOffset();
|
1428
|
-
result.descent = lineHeight - result.ascent;
|
1429
|
-
}
|
1430
|
-
return result;
|
1431
|
-
}
|
1432
152
|
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
@Override
|
1438
|
-
public boolean equals(Object o) {
|
1439
|
-
if (this == o) return true;
|
1440
|
-
if (o == null || getClass() != o.getClass()) return false;
|
1441
|
-
Key that = (Key) o;
|
1442
|
-
if (Float.compare(that.size, size) != 0) return false;
|
1443
|
-
return name.equals(that.name);
|
1444
|
-
}
|
1445
|
-
|
1446
|
-
@Override
|
1447
|
-
public int hashCode() {
|
1448
|
-
int result = name.hashCode();
|
1449
|
-
result = 31 * result + (size != +0.0f ? Float.floatToIntBits(size) : 0);
|
1450
|
-
return result;
|
1451
|
-
}
|
1452
|
-
}
|
1453
|
-
}
|
1454
|
-
|
1455
|
-
|
1456
|
-
///////////////////////////////////////////////////////////////
|
1457
|
-
|
1458
|
-
// TEXT
|
1459
|
-
|
1460
|
-
// None of the variations of text() are overridden from PGraphics.
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
//////////////////////////////////////////////////////////////
|
1465
|
-
|
1466
|
-
// TEXT IMPL
|
1467
|
-
|
1468
|
-
|
1469
|
-
@Override
|
1470
|
-
protected void textFontImpl(PFont which, float size) {
|
1471
|
-
handleTextFont(which, size);
|
1472
|
-
handleTextSize(size);
|
1473
|
-
}
|
1474
|
-
|
1475
|
-
|
1476
|
-
@Override
|
1477
|
-
protected void textSizeImpl(float size) {
|
1478
|
-
handleTextFont(textFont, size);
|
1479
|
-
handleTextSize(size);
|
1480
|
-
}
|
1481
|
-
|
1482
|
-
|
1483
|
-
/**
|
1484
|
-
* FX specific. When setting font or size, new font has to
|
1485
|
-
* be created. Both textFontImpl and textSizeImpl call this one.
|
1486
|
-
* @param which font to be set, not null
|
1487
|
-
* @param size size to be set, greater than zero
|
1488
|
-
*/
|
1489
|
-
protected void handleTextFont(PFont which, float size) {
|
1490
|
-
textFont = which;
|
1491
|
-
|
1492
|
-
String fontName = which.getName();
|
1493
|
-
String fontPsName = which.getPostScriptName();
|
1494
|
-
|
1495
|
-
textFontInfo = fontCache.get(fontName, size);
|
1496
|
-
if (textFontInfo == null) {
|
1497
|
-
Font font = null;
|
1498
|
-
|
1499
|
-
if (which.isStream()) {
|
1500
|
-
// Load from ttf or otf file
|
1501
|
-
String filename = fontCache.nameToFilename.get(fontName);
|
1502
|
-
font = Font.loadFont(parent.createInput(filename), size);
|
1503
|
-
}
|
1504
|
-
|
1505
|
-
if (font == null) {
|
1506
|
-
// Look up font name
|
1507
|
-
font = new Font(fontName, size);
|
1508
|
-
if (!fontName.equalsIgnoreCase(font.getName())) {
|
1509
|
-
// Look up font postscript name
|
1510
|
-
font = new Font(fontPsName, size);
|
1511
|
-
if (!fontPsName.equalsIgnoreCase(font.getName())) {
|
1512
|
-
font = null; // Done with it
|
1513
|
-
}
|
1514
|
-
}
|
1515
|
-
}
|
1516
|
-
|
1517
|
-
if (font == null && which.getNative() != null) {
|
1518
|
-
// Ain't got nothing, but AWT has something, so glyph images are not
|
1519
|
-
// going to be used for this font; go with the default font then
|
1520
|
-
font = new Font(size);
|
1521
|
-
}
|
1522
|
-
|
1523
|
-
textFontInfo = fontCache.createFontInfo(font);
|
1524
|
-
fontCache.put(fontName, size, textFontInfo);
|
153
|
+
@Override
|
154
|
+
public void loadPixels() {
|
155
|
+
throw new UnsupportedOperationException(message);
|
1525
156
|
}
|
1526
157
|
|
1527
|
-
context.setFont(textFontInfo.font);
|
1528
|
-
}
|
1529
158
|
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
if (textFontInfo.font == null) {
|
1534
|
-
super.textLineImpl(buffer, start, stop, x, y);
|
1535
|
-
} else {
|
1536
|
-
context.fillText(new String(buffer, start, stop - start), x, y);
|
159
|
+
@Override
|
160
|
+
public PShape loadShape(String filename) {
|
161
|
+
throw new UnsupportedOperationException(message);
|
1537
162
|
}
|
1538
|
-
}
|
1539
163
|
|
1540
164
|
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
@Override
|
1545
|
-
protected boolean removeEldestEntry(Map.Entry<Integer, PImage[]> eldest) {
|
1546
|
-
return size() > FontInfo.MAX_CACHED_COLORS_PER_FONT;
|
1547
|
-
}
|
1548
|
-
};
|
1549
|
-
}
|
1550
|
-
PImage[] tintedGlyphs = textFontInfo.tintCache.get(tintColor);
|
1551
|
-
int index = glyph.index;
|
1552
|
-
if (tintedGlyphs == null || tintedGlyphs.length <= index) {
|
1553
|
-
PImage[] newArray = new PImage[textFont.getGlyphCount()];
|
1554
|
-
if (tintedGlyphs != null) {
|
1555
|
-
System.arraycopy(tintedGlyphs, 0, newArray, 0, tintedGlyphs.length);
|
1556
|
-
}
|
1557
|
-
tintedGlyphs = newArray;
|
1558
|
-
textFontInfo.tintCache.put(tintColor, tintedGlyphs);
|
165
|
+
@Override
|
166
|
+
public PShape loadShape(String filename, String options) {
|
167
|
+
throw new UnsupportedOperationException(message);
|
1559
168
|
}
|
1560
|
-
PImage tintedGlyph = tintedGlyphs[index];
|
1561
|
-
if (tintedGlyph == null) {
|
1562
|
-
tintedGlyph = glyph.image.copy();
|
1563
|
-
tintedGlyphs[index] = tintedGlyph;
|
1564
|
-
}
|
1565
|
-
return tintedGlyph;
|
1566
|
-
}
|
1567
|
-
|
1568
|
-
|
1569
|
-
@Override
|
1570
|
-
protected void textCharImpl(char ch, float x, float y) { //, float z) {
|
1571
|
-
PFont.Glyph glyph = textFont.getGlyph(ch);
|
1572
|
-
if (glyph != null) {
|
1573
|
-
if (textMode == MODEL) {
|
1574
|
-
float high = glyph.height / (float) textFont.getSize();
|
1575
|
-
float bwidth = glyph.width / (float) textFont.getSize();
|
1576
|
-
float lextent = glyph.leftExtent / (float) textFont.getSize();
|
1577
|
-
float textent = glyph.topExtent / (float) textFont.getSize();
|
1578
169
|
|
1579
|
-
float x1 = x + lextent * textSize;
|
1580
|
-
float y1 = y - textent * textSize;
|
1581
|
-
float x2 = x1 + bwidth * textSize;
|
1582
|
-
float y2 = y1 + high * textSize;
|
1583
170
|
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
textCharModelImpl(glyphImage,
|
1588
|
-
x1, y1, x2, y2,
|
1589
|
-
glyph.width, glyph.height);
|
1590
|
-
}
|
1591
|
-
} else if (ch != ' ' && ch != 127) {
|
1592
|
-
showWarning("No glyph found for the " + ch +
|
1593
|
-
" (\\u" + PApplet.hex(ch, 4) + ") character");
|
171
|
+
@Override
|
172
|
+
public void mask(PImage alpha) {
|
173
|
+
throw new UnsupportedOperationException(message);
|
1594
174
|
}
|
1595
|
-
}
|
1596
|
-
|
1597
175
|
|
1598
|
-
@Override
|
1599
|
-
protected float textWidthImpl(char[] buffer, int start, int stop) {
|
1600
|
-
if (textFont == null) {
|
1601
|
-
defaultFontOrDeath("textWidth");
|
1602
|
-
}
|
1603
176
|
|
1604
|
-
|
1605
|
-
|
177
|
+
@Override
|
178
|
+
public void noClip() {
|
179
|
+
throw new UnsupportedOperationException(message);
|
1606
180
|
}
|
1607
181
|
|
1608
|
-
fontCache.measuringText.setFont(textFontInfo.font);
|
1609
|
-
fontCache.measuringText.setText(new String(buffer, start, stop - start));
|
1610
|
-
return (float) fontCache.measuringText.getLayoutBounds().getWidth();
|
1611
|
-
}
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
//////////////////////////////////////////////////////////////
|
1616
182
|
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
@Override
|
1621
|
-
public void pushMatrix() {
|
1622
|
-
if (transformCount == transformStack.length) {
|
1623
|
-
throw new RuntimeException("pushMatrix() cannot use push more than " +
|
1624
|
-
transformStack.length + " times");
|
183
|
+
@Override
|
184
|
+
public void point(float x, float y) {
|
185
|
+
throw new UnsupportedOperationException(message);
|
1625
186
|
}
|
1626
|
-
transformStack[transformCount] = context.getTransform(transformStack[transformCount]);
|
1627
|
-
transformCount++;
|
1628
|
-
}
|
1629
187
|
|
1630
188
|
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
throw new RuntimeException("missing a pushMatrix() " +
|
1635
|
-
"to go with that popMatrix()");
|
189
|
+
@Override
|
190
|
+
public void popMatrix() {
|
191
|
+
throw new UnsupportedOperationException(message);
|
1636
192
|
}
|
1637
|
-
transformCount--;
|
1638
|
-
context.setTransform(transformStack[transformCount]);
|
1639
|
-
}
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
//////////////////////////////////////////////////////////////
|
1644
|
-
|
1645
|
-
// MATRIX TRANSFORMS
|
1646
|
-
|
1647
|
-
|
1648
|
-
@Override
|
1649
|
-
public void translate(float tx, float ty) {
|
1650
|
-
context.translate(tx, ty);
|
1651
|
-
}
|
1652
|
-
|
1653
|
-
|
1654
|
-
//public void translate(float tx, float ty, float tz)
|
1655
|
-
|
1656
|
-
|
1657
|
-
@Override
|
1658
|
-
public void rotate(float angle) {
|
1659
|
-
context.rotate(PApplet.degrees(angle));
|
1660
|
-
}
|
1661
|
-
|
1662
|
-
|
1663
|
-
@Override
|
1664
|
-
public void rotateX(float angle) {
|
1665
|
-
showDepthWarning("rotateX");
|
1666
|
-
}
|
1667
|
-
|
1668
|
-
|
1669
|
-
@Override
|
1670
|
-
public void rotateY(float angle) {
|
1671
|
-
showDepthWarning("rotateY");
|
1672
|
-
}
|
1673
|
-
|
1674
|
-
|
1675
|
-
@Override
|
1676
|
-
public void rotateZ(float angle) {
|
1677
|
-
showDepthWarning("rotateZ");
|
1678
|
-
}
|
1679
|
-
|
1680
|
-
|
1681
|
-
@Override
|
1682
|
-
public void rotate(float angle, float vx, float vy, float vz) {
|
1683
|
-
showVariationWarning("rotate");
|
1684
|
-
}
|
1685
|
-
|
1686
|
-
|
1687
|
-
@Override
|
1688
|
-
public void scale(float s) {
|
1689
|
-
context.scale(s, s);
|
1690
|
-
}
|
1691
|
-
|
1692
|
-
|
1693
|
-
@Override
|
1694
|
-
public void scale(float sx, float sy) {
|
1695
|
-
context.scale(sx, sy);
|
1696
|
-
}
|
1697
|
-
|
1698
|
-
|
1699
|
-
@Override
|
1700
|
-
public void scale(float sx, float sy, float sz) {
|
1701
|
-
showDepthWarningXYZ("scale");
|
1702
|
-
}
|
1703
193
|
|
1704
194
|
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
temp.appendShear(Math.tan(angle), 0);
|
1709
|
-
context.transform(temp);
|
1710
|
-
}
|
1711
|
-
|
1712
|
-
|
1713
|
-
@Override
|
1714
|
-
public void shearY(float angle) {
|
1715
|
-
Affine temp = new Affine();
|
1716
|
-
temp.appendShear(0, Math.tan(angle));
|
1717
|
-
context.transform(temp);
|
1718
|
-
}
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
//////////////////////////////////////////////////////////////
|
1723
|
-
|
1724
|
-
// MATRIX MORE
|
1725
|
-
|
1726
|
-
|
1727
|
-
@Override
|
1728
|
-
public void resetMatrix() {
|
1729
|
-
context.setTransform(new Affine());
|
1730
|
-
}
|
1731
|
-
|
1732
|
-
|
1733
|
-
//public void applyMatrix(PMatrix2D source)
|
1734
|
-
|
1735
|
-
|
1736
|
-
@Override
|
1737
|
-
public void applyMatrix(float n00, float n01, float n02,
|
1738
|
-
float n10, float n11, float n12) {
|
1739
|
-
context.transform(n00, n10, n01, n11, n02, n12);
|
1740
|
-
}
|
1741
|
-
|
1742
|
-
|
1743
|
-
//public void applyMatrix(PMatrix3D source)
|
1744
|
-
|
1745
|
-
|
1746
|
-
@Override
|
1747
|
-
public void applyMatrix(float n00, float n01, float n02, float n03,
|
1748
|
-
float n10, float n11, float n12, float n13,
|
1749
|
-
float n20, float n21, float n22, float n23,
|
1750
|
-
float n30, float n31, float n32, float n33) {
|
1751
|
-
showVariationWarning("applyMatrix");
|
1752
|
-
}
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
//////////////////////////////////////////////////////////////
|
1757
|
-
|
1758
|
-
// MATRIX GET/SET
|
1759
|
-
|
1760
|
-
|
1761
|
-
@Override
|
1762
|
-
public PMatrix getMatrix() {
|
1763
|
-
return getMatrix((PMatrix2D) null);
|
1764
|
-
}
|
1765
|
-
|
1766
|
-
|
1767
|
-
@Override
|
1768
|
-
public PMatrix2D getMatrix(PMatrix2D target) {
|
1769
|
-
if (target == null) {
|
1770
|
-
target = new PMatrix2D();
|
195
|
+
@Override
|
196
|
+
public void printMatrix() {
|
197
|
+
throw new UnsupportedOperationException(message);
|
1771
198
|
}
|
1772
|
-
//double[] transform = new double[6];
|
1773
|
-
// TODO This is not tested; apparently Affine is a full 3x4
|
1774
|
-
Affine t = context.getTransform(); //.getMatrix(transform);
|
1775
|
-
// target.set((float) transform[0], (float) transform[2], (float) transform[4],
|
1776
|
-
// (float) transform[1], (float) transform[3], (float) transform[5]);
|
1777
|
-
target.set((float) t.getMxx(), (float) t.getMxy(), (float) t.getTx(),
|
1778
|
-
(float) t.getMyx(), (float) t.getMyy(), (float) t.getTy());
|
1779
|
-
return target;
|
1780
|
-
}
|
1781
|
-
|
1782
|
-
|
1783
|
-
@Override
|
1784
|
-
public PMatrix3D getMatrix(PMatrix3D target) {
|
1785
|
-
showVariationWarning("getMatrix");
|
1786
|
-
return target;
|
1787
|
-
}
|
1788
|
-
|
1789
|
-
|
1790
|
-
//public void setMatrix(PMatrix source)
|
1791
|
-
|
1792
|
-
|
1793
|
-
@Override
|
1794
|
-
public void setMatrix(PMatrix2D source) {
|
1795
|
-
context.setTransform(source.m00, source.m10,
|
1796
|
-
source.m01, source.m11,
|
1797
|
-
source.m02, source.m12);
|
1798
|
-
}
|
1799
|
-
|
1800
|
-
|
1801
|
-
@Override
|
1802
|
-
public void setMatrix(PMatrix3D source) {
|
1803
|
-
showVariationWarning("setMatrix");
|
1804
|
-
}
|
1805
|
-
|
1806
|
-
|
1807
|
-
@Override
|
1808
|
-
public void printMatrix() {
|
1809
|
-
getMatrix((PMatrix2D) null).print();
|
1810
|
-
}
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
// //////////////////////////////////////////////////////////////
|
1815
|
-
//
|
1816
|
-
// // CAMERA and PROJECTION
|
1817
|
-
//
|
1818
|
-
// // Inherit the plaintive warnings from PGraphics
|
1819
|
-
//
|
1820
|
-
//
|
1821
|
-
// //public void beginCamera()
|
1822
|
-
// //public void endCamera()
|
1823
|
-
// //public void camera()
|
1824
|
-
// //public void camera(float eyeX, float eyeY, float eyeZ,
|
1825
|
-
// // float centerX, float centerY, float centerZ,
|
1826
|
-
// // float upX, float upY, float upZ)
|
1827
|
-
// //public void printCamera()
|
1828
|
-
//
|
1829
|
-
// //public void ortho()
|
1830
|
-
// //public void ortho(float left, float right,
|
1831
|
-
// // float bottom, float top,
|
1832
|
-
// // float near, float far)
|
1833
|
-
// //public void perspective()
|
1834
|
-
// //public void perspective(float fov, float aspect, float near, float far)
|
1835
|
-
// //public void frustum(float left, float right,
|
1836
|
-
// // float bottom, float top,
|
1837
|
-
// // float near, float far)
|
1838
|
-
// //public void printProjection()
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
//////////////////////////////////////////////////////////////
|
1843
|
-
|
1844
|
-
// SCREEN and MODEL transforms
|
1845
|
-
|
1846
|
-
|
1847
|
-
@Override
|
1848
|
-
public float screenX(float x, float y) {
|
1849
|
-
return (float) context.getTransform().transform(x, y).getX();
|
1850
|
-
}
|
1851
|
-
|
1852
|
-
|
1853
|
-
@Override
|
1854
|
-
public float screenY(float x, float y) {
|
1855
|
-
return (float) context.getTransform().transform(x, y).getY();
|
1856
|
-
}
|
1857
|
-
|
1858
|
-
|
1859
|
-
@Override
|
1860
|
-
public float screenX(float x, float y, float z) {
|
1861
|
-
showDepthWarningXYZ("screenX");
|
1862
|
-
return 0;
|
1863
|
-
}
|
1864
|
-
|
1865
|
-
|
1866
|
-
@Override
|
1867
|
-
public float screenY(float x, float y, float z) {
|
1868
|
-
showDepthWarningXYZ("screenY");
|
1869
|
-
return 0;
|
1870
|
-
}
|
1871
|
-
|
1872
|
-
|
1873
|
-
@Override
|
1874
|
-
public float screenZ(float x, float y, float z) {
|
1875
|
-
showDepthWarningXYZ("screenZ");
|
1876
|
-
return 0;
|
1877
|
-
}
|
1878
|
-
|
1879
|
-
|
1880
|
-
//public float modelX(float x, float y, float z)
|
1881
|
-
|
1882
199
|
|
1883
|
-
//public float modelY(float x, float y, float z)
|
1884
200
|
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
// //////////////////////////////////////////////////////////////
|
1891
|
-
//
|
1892
|
-
// // STYLE
|
1893
|
-
//
|
1894
|
-
// // pushStyle(), popStyle(), style() and getStyle() inherited.
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
//////////////////////////////////////////////////////////////
|
1899
|
-
|
1900
|
-
// STROKE CAP/JOIN/WEIGHT
|
1901
|
-
|
1902
|
-
|
1903
|
-
@Override
|
1904
|
-
public void strokeCap(int cap) {
|
1905
|
-
super.strokeCap(cap);
|
1906
|
-
if (strokeCap == ROUND) {
|
1907
|
-
context.setLineCap(StrokeLineCap.ROUND);
|
1908
|
-
} else if (strokeCap == PROJECT) {
|
1909
|
-
context.setLineCap(StrokeLineCap.SQUARE);
|
1910
|
-
} else {
|
1911
|
-
context.setLineCap(StrokeLineCap.BUTT);
|
201
|
+
@Override
|
202
|
+
public void pushMatrix() {
|
203
|
+
throw new UnsupportedOperationException(message);
|
1912
204
|
}
|
1913
|
-
}
|
1914
205
|
|
1915
206
|
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
if (strokeJoin == MITER) {
|
1920
|
-
context.setLineJoin(StrokeLineJoin.MITER);
|
1921
|
-
} else if (strokeJoin == ROUND) {
|
1922
|
-
context.setLineJoin(StrokeLineJoin.ROUND);
|
1923
|
-
} else {
|
1924
|
-
context.setLineJoin(StrokeLineJoin.BEVEL);
|
207
|
+
@Override
|
208
|
+
public void quad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
|
209
|
+
throw new UnsupportedOperationException(message);
|
1925
210
|
}
|
1926
|
-
}
|
1927
|
-
|
1928
|
-
|
1929
|
-
@Override
|
1930
|
-
public void strokeWeight(float weight) {
|
1931
|
-
super.strokeWeight(weight);
|
1932
|
-
context.setLineWidth(weight);
|
1933
|
-
}
|
1934
|
-
|
1935
|
-
|
1936
211
|
|
1937
|
-
//////////////////////////////////////////////////////////////
|
1938
212
|
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
@Override
|
1945
|
-
protected void strokeFromCalc() {
|
1946
|
-
super.strokeFromCalc();
|
1947
|
-
context.setStroke(new Color(strokeR, strokeG, strokeB, strokeA));
|
1948
|
-
}
|
1949
|
-
|
1950
|
-
|
1951
|
-
protected boolean drawingThinLines() {
|
1952
|
-
// align strokes to pixel centers when drawing thin lines
|
1953
|
-
return stroke && strokeWeight == 1;
|
1954
|
-
}
|
213
|
+
@Override
|
214
|
+
public void quadraticVertex(float ctrlX, float ctrlY, float endX, float endY) {
|
215
|
+
throw new UnsupportedOperationException(message);
|
216
|
+
}
|
1955
217
|
|
1956
218
|
|
219
|
+
@Override
|
220
|
+
public void quadraticVertex(float x2, float y2, float z2, float x4, float y4, float z4) {
|
221
|
+
throw new UnsupportedOperationException(message);
|
222
|
+
}
|
1957
223
|
|
1958
|
-
//////////////////////////////////////////////////////////////
|
1959
224
|
|
1960
|
-
|
225
|
+
@Override
|
226
|
+
public void resetMatrix() {
|
227
|
+
throw new UnsupportedOperationException(message);
|
228
|
+
}
|
1961
229
|
|
1962
|
-
// noTint() and tint() inherited from PGraphics.
|
1963
230
|
|
231
|
+
@Override
|
232
|
+
public void rotate(float angle) {
|
233
|
+
throw new UnsupportedOperationException(message);
|
234
|
+
}
|
1964
235
|
|
1965
236
|
|
1966
|
-
|
237
|
+
@Override
|
238
|
+
public void rotate(float angle, float vx, float vy, float vz) {
|
239
|
+
throw new UnsupportedOperationException(message);
|
240
|
+
}
|
1967
241
|
|
1968
|
-
// FILL
|
1969
242
|
|
1970
|
-
|
243
|
+
@Override
|
244
|
+
public void rotateX(float angle) {
|
245
|
+
throw new UnsupportedOperationException(message);
|
246
|
+
}
|
1971
247
|
|
1972
248
|
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
}
|
249
|
+
@Override
|
250
|
+
public void rotateY(float angle) {
|
251
|
+
throw new UnsupportedOperationException(message);
|
252
|
+
}
|
1978
253
|
|
1979
254
|
|
255
|
+
@Override
|
256
|
+
public void rotateZ(float angle) {
|
257
|
+
throw new UnsupportedOperationException(message);
|
258
|
+
}
|
1980
259
|
|
1981
|
-
// //////////////////////////////////////////////////////////////
|
1982
|
-
//
|
1983
|
-
// // MATERIAL PROPERTIES
|
1984
|
-
//
|
1985
|
-
//
|
1986
|
-
// //public void ambient(int rgb)
|
1987
|
-
// //public void ambient(float gray)
|
1988
|
-
// //public void ambient(float x, float y, float z)
|
1989
|
-
// //protected void ambientFromCalc()
|
1990
|
-
// //public void specular(int rgb)
|
1991
|
-
// //public void specular(float gray)
|
1992
|
-
// //public void specular(float x, float y, float z)
|
1993
|
-
// //protected void specularFromCalc()
|
1994
|
-
// //public void shininess(float shine)
|
1995
|
-
// //public void emissive(int rgb)
|
1996
|
-
// //public void emissive(float gray)
|
1997
|
-
// //public void emissive(float x, float y, float z )
|
1998
|
-
// //protected void emissiveFromCalc()
|
1999
|
-
//
|
2000
|
-
//
|
2001
|
-
//
|
2002
|
-
// //////////////////////////////////////////////////////////////
|
2003
|
-
//
|
2004
|
-
// // LIGHTS
|
2005
|
-
//
|
2006
|
-
//
|
2007
|
-
// //public void lights()
|
2008
|
-
// //public void noLights()
|
2009
|
-
// //public void ambientLight(float red, float green, float blue)
|
2010
|
-
// //public void ambientLight(float red, float green, float blue,
|
2011
|
-
// // float x, float y, float z)
|
2012
|
-
// //public void directionalLight(float red, float green, float blue,
|
2013
|
-
// // float nx, float ny, float nz)
|
2014
|
-
// //public void pointLight(float red, float green, float blue,
|
2015
|
-
// // float x, float y, float z)
|
2016
|
-
// //public void spotLight(float red, float green, float blue,
|
2017
|
-
// // float x, float y, float z,
|
2018
|
-
// // float nx, float ny, float nz,
|
2019
|
-
// // float angle, float concentration)
|
2020
|
-
// //public void lightFalloff(float constant, float linear, float quadratic)
|
2021
|
-
// //public void lightSpecular(float x, float y, float z)
|
2022
|
-
// //protected void lightPosition(int num, float x, float y, float z)
|
2023
|
-
// //protected void lightDirection(int num, float x, float y, float z)
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
//////////////////////////////////////////////////////////////
|
2028
|
-
|
2029
|
-
// BACKGROUND
|
2030
|
-
|
2031
|
-
|
2032
|
-
@Override
|
2033
|
-
public void backgroundImpl() {
|
2034
|
-
|
2035
|
-
// if pixels are modified, we don't flush them (just mark them flushed)
|
2036
|
-
// because they would be immediatelly overwritten by the background anyway
|
2037
|
-
modified = false;
|
2038
|
-
loaded = false;
|
2039
|
-
|
2040
|
-
// Save drawing context (transform, fill, blend mode, etc.)
|
2041
|
-
context.save();
|
2042
|
-
|
2043
|
-
// Reset transform to identity
|
2044
|
-
context.setTransform(new Affine());
|
2045
|
-
|
2046
|
-
// This only takes into account cases where this is the primary surface.
|
2047
|
-
// Not sure what we do with offscreen anyway.
|
2048
|
-
context.setFill(new Color(backgroundR, backgroundG, backgroundB, backgroundA));
|
2049
|
-
context.setGlobalBlendMode(BlendMode.SRC_OVER);
|
2050
|
-
context.fillRect(0, 0, width, height);
|
2051
|
-
|
2052
|
-
// Restore drawing context (transform, fill, blend mode, etc.)
|
2053
|
-
context.restore();
|
2054
|
-
}
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
// //////////////////////////////////////////////////////////////
|
2059
|
-
//
|
2060
|
-
// // COLOR MODE
|
2061
|
-
//
|
2062
|
-
// // All colorMode() variations are inherited from PGraphics.
|
2063
|
-
//
|
2064
|
-
//
|
2065
|
-
//
|
2066
|
-
// //////////////////////////////////////////////////////////////
|
2067
|
-
//
|
2068
|
-
// // COLOR CALC
|
2069
|
-
//
|
2070
|
-
// // colorCalc() and colorCalcARGB() inherited from PGraphics.
|
2071
|
-
//
|
2072
|
-
//
|
2073
|
-
//
|
2074
|
-
// //////////////////////////////////////////////////////////////
|
2075
|
-
//
|
2076
|
-
// // COLOR DATATYPE STUFFING
|
2077
|
-
//
|
2078
|
-
// // final color() variations inherited.
|
2079
|
-
//
|
2080
|
-
//
|
2081
|
-
//
|
2082
|
-
// //////////////////////////////////////////////////////////////
|
2083
|
-
//
|
2084
|
-
// // COLOR DATATYPE EXTRACTION
|
2085
|
-
//
|
2086
|
-
// // final methods alpha, red, green, blue,
|
2087
|
-
// // hue, saturation, and brightness all inherited.
|
2088
|
-
//
|
2089
|
-
//
|
2090
|
-
//
|
2091
|
-
// //////////////////////////////////////////////////////////////
|
2092
|
-
//
|
2093
|
-
// // COLOR DATATYPE INTERPOLATION
|
2094
|
-
//
|
2095
|
-
// // both lerpColor variants inherited.
|
2096
|
-
//
|
2097
|
-
//
|
2098
|
-
//
|
2099
|
-
// //////////////////////////////////////////////////////////////
|
2100
|
-
//
|
2101
|
-
// // BEGIN/END RAW
|
2102
|
-
//
|
2103
|
-
//
|
2104
|
-
// @Override
|
2105
|
-
// public void beginRaw(PGraphics recorderRaw) {
|
2106
|
-
// showMethodWarning("beginRaw");
|
2107
|
-
// }
|
2108
|
-
//
|
2109
|
-
//
|
2110
|
-
// @Override
|
2111
|
-
// public void endRaw() {
|
2112
|
-
// showMethodWarning("endRaw");
|
2113
|
-
// }
|
2114
|
-
//
|
2115
|
-
//
|
2116
|
-
//
|
2117
|
-
// //////////////////////////////////////////////////////////////
|
2118
|
-
//
|
2119
|
-
// // WARNINGS and EXCEPTIONS
|
2120
|
-
//
|
2121
|
-
// // showWarning and showException inherited.
|
2122
|
-
//
|
2123
|
-
//
|
2124
|
-
//
|
2125
|
-
// //////////////////////////////////////////////////////////////
|
2126
|
-
//
|
2127
|
-
// // RENDERER SUPPORT QUERIES
|
2128
|
-
//
|
2129
|
-
//
|
2130
|
-
// //public boolean displayable() // true
|
2131
|
-
//
|
2132
|
-
//
|
2133
|
-
// //public boolean is2D() // true
|
2134
|
-
//
|
2135
|
-
//
|
2136
|
-
// //public boolean is3D() // false
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
//////////////////////////////////////////////////////////////
|
2141
|
-
|
2142
|
-
// PIMAGE METHODS
|
2143
|
-
|
2144
|
-
|
2145
|
-
@Override
|
2146
|
-
public void loadPixels() {
|
2147
|
-
if ((pixels == null) || (pixels.length != pixelWidth * pixelHeight)) {
|
2148
|
-
pixels = new int[pixelWidth * pixelHeight];
|
2149
|
-
loaded = false;
|
2150
|
-
}
|
2151
|
-
|
2152
|
-
if (!loaded) {
|
2153
|
-
if (snapshotImage == null ||
|
2154
|
-
snapshotImage.getWidth() != pixelWidth ||
|
2155
|
-
snapshotImage.getHeight() != pixelHeight) {
|
2156
|
-
snapshotImage = new WritableImage(pixelWidth, pixelHeight);
|
2157
|
-
}
|
2158
|
-
|
2159
|
-
SnapshotParameters sp = null;
|
2160
|
-
if (pixelDensity != 1) {
|
2161
|
-
sp = new SnapshotParameters();
|
2162
|
-
sp.setTransform(Transform.scale(pixelDensity, pixelDensity));
|
2163
|
-
}
|
2164
|
-
snapshotImage = ((PSurfaceFX) surface).canvas.snapshot(sp, snapshotImage);
|
2165
|
-
PixelReader pr = snapshotImage.getPixelReader();
|
2166
|
-
pr.getPixels(0, 0, pixelWidth, pixelHeight, argbFormat, pixels, 0, pixelWidth);
|
2167
|
-
|
2168
|
-
loaded = true;
|
2169
|
-
modified = false;
|
2170
|
-
}
|
2171
|
-
}
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
//////////////////////////////////////////////////////////////
|
2176
|
-
|
2177
|
-
// GET/SET PIXELS
|
2178
|
-
|
2179
|
-
|
2180
|
-
@Override
|
2181
|
-
public int get(int x, int y) {
|
2182
|
-
loadPixels();
|
2183
|
-
return super.get(x, y);
|
2184
|
-
}
|
2185
260
|
|
261
|
+
@Override
|
262
|
+
public void scale(float s) {
|
263
|
+
throw new UnsupportedOperationException(message);
|
264
|
+
}
|
2186
265
|
|
2187
|
-
@Override
|
2188
|
-
protected void getImpl(int sourceX, int sourceY,
|
2189
|
-
int sourceWidth, int sourceHeight,
|
2190
|
-
PImage target, int targetX, int targetY) {
|
2191
|
-
loadPixels();
|
2192
|
-
super.getImpl(sourceX, sourceY, sourceWidth, sourceHeight,
|
2193
|
-
target, targetX, targetY);
|
2194
|
-
}
|
2195
266
|
|
267
|
+
@Override
|
268
|
+
public void scale(float sx, float sy) {
|
269
|
+
throw new UnsupportedOperationException(message);
|
270
|
+
}
|
2196
271
|
|
2197
|
-
@Override
|
2198
|
-
public void set(int x, int y, int argb) {
|
2199
|
-
loadPixels();
|
2200
|
-
super.set(x, y, argb);
|
2201
|
-
}
|
2202
272
|
|
273
|
+
@Override
|
274
|
+
public void scale(float sx, float sy, float sz) {
|
275
|
+
throw new UnsupportedOperationException(message);
|
276
|
+
}
|
2203
277
|
|
2204
|
-
@Override
|
2205
|
-
protected void setImpl(PImage sourceImage,
|
2206
|
-
int sourceX, int sourceY,
|
2207
|
-
int sourceWidth, int sourceHeight,
|
2208
|
-
int targetX, int targetY) {
|
2209
|
-
sourceImage.loadPixels();
|
2210
278
|
|
2211
|
-
|
279
|
+
@Override
|
280
|
+
public float screenX(float x, float y) {
|
281
|
+
throw new UnsupportedOperationException(message);
|
282
|
+
}
|
2212
283
|
|
2213
|
-
PixelWriter pw = context.getPixelWriter();
|
2214
|
-
pw.setPixels(targetX, targetY, sourceWidth, sourceHeight,
|
2215
|
-
argbFormat,
|
2216
|
-
sourceImage.pixels,
|
2217
|
-
sourceOffset,
|
2218
|
-
sourceImage.pixelWidth);
|
2219
284
|
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
int targetStride = pixelWidth;
|
2224
|
-
int targetOffset = targetX + targetY * targetStride;
|
2225
|
-
for (int i = 0; i < sourceHeight; i++) {
|
2226
|
-
System.arraycopy(sourceImage.pixels, sourceOffset + i * sourceStride,
|
2227
|
-
pixels, targetOffset + i * targetStride, sourceWidth);
|
2228
|
-
}
|
285
|
+
@Override
|
286
|
+
public float screenX(float x, float y, float z) {
|
287
|
+
throw new UnsupportedOperationException(message);
|
2229
288
|
}
|
2230
|
-
}
|
2231
289
|
|
2232
290
|
|
2233
|
-
|
291
|
+
@Override
|
292
|
+
public float screenY(float x, float y) {
|
293
|
+
throw new UnsupportedOperationException(message);
|
294
|
+
}
|
2234
295
|
|
2235
|
-
// MASK
|
2236
296
|
|
297
|
+
@Override
|
298
|
+
public float screenY(float x, float y, float z) {
|
299
|
+
throw new UnsupportedOperationException(message);
|
300
|
+
}
|
2237
301
|
|
2238
|
-
static final String MASK_WARNING =
|
2239
|
-
"mask() cannot be used on the main drawing surface";
|
2240
302
|
|
303
|
+
@Override
|
304
|
+
public float screenZ(float x, float y, float z) {
|
305
|
+
throw new UnsupportedOperationException(message);
|
306
|
+
}
|
2241
307
|
|
2242
|
-
@Override
|
2243
|
-
public void mask(PImage alpha) {
|
2244
|
-
showWarning(MASK_WARNING);
|
2245
|
-
}
|
2246
308
|
|
309
|
+
@Override
|
310
|
+
public void set(int x, int y, int argb) {
|
311
|
+
throw new UnsupportedOperationException(message);
|
312
|
+
}
|
2247
313
|
|
2248
314
|
|
2249
|
-
|
315
|
+
@Override
|
316
|
+
public void setMatrix(PMatrix2D source) {
|
317
|
+
throw new UnsupportedOperationException(message);
|
318
|
+
}
|
2250
319
|
|
2251
|
-
// FILTER
|
2252
320
|
|
2253
|
-
|
2254
|
-
|
321
|
+
@Override
|
322
|
+
public void setMatrix(PMatrix3D source) {
|
323
|
+
throw new UnsupportedOperationException(message);
|
324
|
+
}
|
2255
325
|
|
2256
326
|
|
2257
|
-
|
327
|
+
@Override
|
328
|
+
public void shearX(float angle) {
|
329
|
+
throw new UnsupportedOperationException(message);
|
330
|
+
}
|
2258
331
|
|
2259
332
|
|
2260
|
-
|
333
|
+
@Override
|
334
|
+
public void shearY(float angle) {
|
335
|
+
throw new UnsupportedOperationException(message);
|
336
|
+
}
|
2261
337
|
|
2262
338
|
|
339
|
+
@Override
|
340
|
+
public void sphere(float r) {
|
341
|
+
throw new UnsupportedOperationException(message);
|
342
|
+
}
|
2263
343
|
|
2264
|
-
//////////////////////////////////////////////////////////////
|
2265
344
|
|
2266
|
-
|
345
|
+
@Override
|
346
|
+
public void strokeCap(int cap) {
|
347
|
+
throw new UnsupportedOperationException(message);
|
348
|
+
}
|
2267
349
|
|
2268
350
|
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
// g2.drawImage(image, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
|
2274
|
-
//
|
2275
|
-
// } else {
|
2276
|
-
// dx = dx - sx; // java2d's "dx" is the delta, not dest
|
2277
|
-
// dy = dy - sy;
|
2278
|
-
// g2.copyArea(sx, sy, sw, sh, dx, dy);
|
2279
|
-
// }
|
2280
|
-
// }
|
351
|
+
@Override
|
352
|
+
public void strokeJoin(int join) {
|
353
|
+
throw new UnsupportedOperationException(message);
|
354
|
+
}
|
2281
355
|
|
2282
356
|
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
// g2.drawImage((Image) src.getNative(),
|
2288
|
-
// dx, dy, dx + dw, dy + dh,
|
2289
|
-
// sx, sy, sx + sw, sy + sh, null);
|
2290
|
-
// }
|
357
|
+
@Override
|
358
|
+
public void strokeWeight(float weight) {
|
359
|
+
throw new UnsupportedOperationException(message);
|
360
|
+
}
|
2291
361
|
|
2292
362
|
|
363
|
+
@Override
|
364
|
+
public float textAscent() {
|
365
|
+
throw new UnsupportedOperationException(message);
|
366
|
+
}
|
2293
367
|
|
2294
|
-
//////////////////////////////////////////////////////////////
|
2295
368
|
|
2296
|
-
|
369
|
+
@Override
|
370
|
+
public float textDescent() {
|
371
|
+
throw new UnsupportedOperationException(message);
|
372
|
+
}
|
2297
373
|
|
2298
374
|
|
2299
|
-
|
375
|
+
@Override
|
376
|
+
public void texture(PImage image) {
|
377
|
+
throw new UnsupportedOperationException(message);
|
378
|
+
}
|
2300
379
|
|
2301
380
|
|
2302
|
-
|
2303
|
-
|
381
|
+
@Override
|
382
|
+
public void translate(float tx, float ty) {
|
383
|
+
throw new UnsupportedOperationException(message);
|
384
|
+
}
|
2304
385
|
|
2305
386
|
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
387
|
+
@Override
|
388
|
+
public void triangle(float x1, float y1, float x2, float y2, float x3, float y3) {
|
389
|
+
throw new UnsupportedOperationException(message);
|
390
|
+
}
|
2309
391
|
|
2310
392
|
|
393
|
+
@Override
|
394
|
+
public void vertex(float x, float y) {
|
395
|
+
throw new UnsupportedOperationException(message);
|
396
|
+
}
|
2311
397
|
|
2312
|
-
//////////////////////////////////////////////////////////////
|
2313
398
|
|
2314
|
-
|
399
|
+
@Override
|
400
|
+
public void vertex(float x, float y, float z) {
|
401
|
+
throw new UnsupportedOperationException(message);
|
402
|
+
}
|
2315
403
|
|
2316
404
|
|
2317
|
-
|
405
|
+
@Override
|
406
|
+
public void vertex(float[] v) {
|
407
|
+
throw new UnsupportedOperationException(message);
|
408
|
+
}
|
2318
409
|
|
2319
410
|
|
411
|
+
@Override
|
412
|
+
public void vertex(float x, float y, float u, float v) {
|
413
|
+
throw new UnsupportedOperationException(message);
|
414
|
+
}
|
2320
415
|
|
2321
|
-
//////////////////////////////////////////////////////////////
|
2322
416
|
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
showWarning(method + "() is not yet available: " +
|
2328
|
-
"https://github.com/processing/processing/issues/" + issue);
|
2329
|
-
}
|
417
|
+
@Override
|
418
|
+
public void vertex(float x, float y, float z, float u, float v) {
|
419
|
+
throw new UnsupportedOperationException(message);
|
420
|
+
}
|
2330
421
|
}
|