propane 3.4.1-java → 3.7.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mvn/extensions.xml +1 -1
- data/.mvn/wrapper/MavenWrapperDownloader.java +2 -2
- data/.mvn/wrapper/maven-wrapper.properties +2 -2
- data/.travis.yml +1 -1
- data/CHANGELOG.md +9 -1
- data/Gemfile +2 -0
- data/README.md +9 -5
- data/Rakefile +10 -11
- data/bin/propane +3 -1
- data/lib/propane.rb +4 -2
- data/lib/propane/app.rb +2 -1
- data/lib/propane/creators/sketch_class.rb +7 -1
- data/lib/propane/creators/sketch_factory.rb +4 -2
- data/lib/propane/creators/sketch_writer.rb +1 -0
- data/lib/propane/helper_methods.rb +22 -23
- data/lib/propane/helpers/numeric.rb +2 -0
- data/lib/propane/helpers/version_error.rb +1 -0
- data/lib/propane/library.rb +5 -1
- data/lib/propane/library_loader.rb +2 -0
- data/lib/propane/native_folder.rb +10 -9
- data/lib/propane/native_loader.rb +3 -0
- data/lib/propane/runner.rb +20 -14
- data/lib/propane/version.rb +2 -1
- data/library/boids/boids.rb +21 -11
- data/library/color_group/color_group.rb +2 -0
- data/library/control_panel/control_panel.rb +8 -5
- data/library/dxf/dxf.rb +2 -0
- data/library/file_chooser/chooser.rb +10 -9
- data/library/file_chooser/file_chooser.rb +10 -9
- data/library/library_proxy/library_proxy.rb +2 -0
- data/library/net/net.rb +2 -0
- data/library/simplex_noise/simplex_noise.rb +2 -0
- data/library/slider/slider.rb +23 -22
- data/library/vector_utils/vector_utils.rb +4 -0
- data/library/video_event/video_event.rb +2 -0
- data/pom.rb +37 -36
- data/pom.xml +6 -6
- data/propane.gemspec +12 -10
- data/src/main/java/japplemenubar/JAppleMenuBar.java +3 -3
- data/src/main/java/monkstone/ColorUtil.java +1 -3
- data/src/main/java/monkstone/MathToolModule.java +10 -9
- data/src/main/java/monkstone/PropaneLibrary.java +2 -2
- data/src/main/java/monkstone/fastmath/Deglut.java +1 -1
- data/src/main/java/monkstone/filechooser/Chooser.java +1 -1
- data/src/main/java/monkstone/noise/SimplexNoise.java +2 -2
- data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
- data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
- data/src/main/java/monkstone/slider/SliderBar.java +1 -1
- data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
- data/src/main/java/monkstone/slider/WheelHandler.java +1 -1
- data/src/main/java/monkstone/vecmath/package-info.java +1 -1
- data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
- data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -2
- data/src/main/java/monkstone/videoevent/CaptureEvent.java +1 -1
- data/src/main/java/monkstone/videoevent/MovieEvent.java +1 -1
- data/src/main/java/monkstone/videoevent/package-info.java +1 -1
- data/src/main/java/processing/awt/PGraphicsJava2D.java +781 -285
- data/src/main/java/processing/awt/PImageAWT.java +377 -0
- data/src/main/java/processing/awt/PShapeJava2D.java +56 -52
- data/src/main/java/processing/awt/PSurfaceAWT.java +308 -208
- data/src/main/java/processing/awt/ShimAWT.java +581 -0
- data/src/main/java/processing/core/PApplet.java +4225 -4855
- data/src/main/java/processing/core/PConstants.java +477 -447
- data/src/main/java/processing/core/PFont.java +914 -880
- data/src/main/java/processing/core/PGraphics.java +150 -134
- data/src/main/java/processing/core/PImage.java +275 -372
- data/src/main/java/processing/core/PMatrix.java +172 -159
- data/src/main/java/processing/core/PMatrix2D.java +478 -415
- data/src/main/java/processing/core/PMatrix3D.java +762 -735
- data/src/main/java/processing/core/PShape.java +2887 -2651
- data/src/main/java/processing/core/PShapeOBJ.java +97 -92
- data/src/main/java/processing/core/PShapeSVG.java +1705 -1490
- data/src/main/java/processing/core/PStyle.java +40 -37
- data/src/main/java/processing/core/PSurface.java +139 -97
- data/src/main/java/processing/core/PSurfaceNone.java +296 -218
- data/src/main/java/processing/core/PVector.java +995 -963
- data/src/main/java/processing/core/ThinkDifferent.java +12 -8
- data/src/main/java/processing/data/DoubleDict.java +756 -710
- data/src/main/java/processing/data/DoubleList.java +749 -696
- data/src/main/java/processing/data/FloatDict.java +748 -702
- data/src/main/java/processing/data/FloatList.java +751 -697
- data/src/main/java/processing/data/IntDict.java +720 -673
- data/src/main/java/processing/data/IntList.java +699 -633
- data/src/main/java/processing/data/JSONArray.java +931 -873
- data/src/main/java/processing/data/JSONObject.java +1262 -1165
- data/src/main/java/processing/data/JSONTokener.java +351 -341
- data/src/main/java/processing/data/LongDict.java +710 -663
- data/src/main/java/processing/data/LongList.java +701 -635
- data/src/main/java/processing/data/Sort.java +37 -41
- data/src/main/java/processing/data/StringDict.java +525 -486
- data/src/main/java/processing/data/StringList.java +626 -580
- data/src/main/java/processing/data/Table.java +3690 -3510
- data/src/main/java/processing/data/TableRow.java +182 -183
- data/src/main/java/processing/data/XML.java +957 -883
- data/src/main/java/processing/event/Event.java +87 -67
- data/src/main/java/processing/event/KeyEvent.java +48 -41
- data/src/main/java/processing/event/MouseEvent.java +88 -113
- data/src/main/java/processing/event/TouchEvent.java +10 -6
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +20 -345
- data/src/main/java/processing/javafx/PSurfaceFX.java +149 -121
- data/src/main/java/processing/net/Client.java +20 -20
- data/src/main/java/processing/net/Server.java +9 -9
- data/src/main/java/processing/opengl/FontTexture.java +286 -266
- data/src/main/java/processing/opengl/FrameBuffer.java +389 -377
- data/src/main/java/processing/opengl/LinePath.java +132 -89
- data/src/main/java/processing/opengl/LineStroker.java +588 -581
- data/src/main/java/processing/opengl/PGL.java +660 -567
- data/src/main/java/processing/opengl/PGraphics2D.java +408 -315
- data/src/main/java/processing/opengl/PGraphics3D.java +107 -72
- data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12378 -12075
- data/src/main/java/processing/opengl/PJOGL.java +1753 -1670
- data/src/main/java/processing/opengl/PShader.java +369 -461
- data/src/main/java/processing/opengl/PShapeOpenGL.java +4678 -4580
- data/src/main/java/processing/opengl/PSurfaceJOGL.java +1114 -1027
- data/src/main/java/processing/opengl/Texture.java +1492 -1401
- data/src/main/java/processing/opengl/VertexBuffer.java +57 -55
- data/test/create_test.rb +21 -20
- data/test/deglut_spec_test.rb +4 -2
- data/test/helper_methods_test.rb +49 -20
- data/test/math_tool_test.rb +39 -32
- data/test/native_folder.rb +47 -0
- data/test/respond_to_test.rb +3 -2
- data/test/sketches/key_event.rb +2 -2
- data/test/sketches/library/my_library/my_library.rb +3 -0
- data/test/test_helper.rb +2 -0
- data/test/vecmath_spec_test.rb +35 -22
- data/vendors/Rakefile +35 -40
- metadata +42 -22
- data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
- data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
- data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
- data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -1,3 +1,5 @@
|
|
1
|
+
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
2
|
+
|
1
3
|
/*
|
2
4
|
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
3
5
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
@@ -22,653 +24,658 @@
|
|
22
24
|
* or visit www.oracle.com if you need additional information or have any
|
23
25
|
* questions.
|
24
26
|
*/
|
27
|
+
|
25
28
|
package processing.opengl;
|
26
29
|
|
27
30
|
import processing.core.PMatrix2D;
|
28
31
|
|
29
|
-
public class LineStroker
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
32
|
+
public class LineStroker {
|
33
|
+
private LineStroker output;
|
34
|
+
private int capStyle;
|
35
|
+
private int joinStyle;
|
36
|
+
private int m00, m01;
|
37
|
+
private int m10, m11;
|
38
|
+
private int lineWidth2;
|
39
|
+
private long scaledLineWidth2;
|
40
|
+
|
41
|
+
// For any pen offset (pen_dx, pen_dy) that does not depend on
|
42
|
+
// the line orientation, the pen should be transformed so that:
|
43
|
+
//
|
44
|
+
// pen_dx' = m00*pen_dx + m01*pen_dy
|
45
|
+
// pen_dy' = m10*pen_dx + m11*pen_dy
|
46
|
+
//
|
47
|
+
// For a round pen, this means:
|
48
|
+
//
|
49
|
+
// pen_dx(r, theta) = r*cos(theta)
|
50
|
+
// pen_dy(r, theta) = r*sin(theta)
|
51
|
+
//
|
52
|
+
// pen_dx'(r, theta) = r*(m00*cos(theta) + m01*sin(theta))
|
53
|
+
// pen_dy'(r, theta) = r*(m10*cos(theta) + m11*sin(theta))
|
54
|
+
private int numPenSegments;
|
55
|
+
private int[] pen_dx;
|
56
|
+
private int[] pen_dy;
|
57
|
+
|
58
|
+
private boolean[] penIncluded;
|
59
|
+
private int[] join;
|
60
|
+
private int[] offset = new int[2];
|
61
|
+
private int[] reverse = new int[100];
|
62
|
+
private int[] miter = new int[2];
|
63
|
+
private long miterLimitSq;
|
64
|
+
private int prev;
|
65
|
+
private int rindex;
|
66
|
+
private boolean started;
|
67
|
+
private boolean lineToOrigin;
|
68
|
+
private boolean joinToOrigin;
|
69
|
+
private int sx0, sy0, sx1, sy1, x0, y0;
|
70
|
+
private int scolor0, pcolor0, color0;
|
71
|
+
private int mx0, my0, omx, omy;
|
72
|
+
private int px0, py0;
|
73
|
+
private double m00_2_m01_2;
|
74
|
+
private double m10_2_m11_2;
|
75
|
+
private double m00_m10_m01_m11;
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Empty constructor. <code>setOutput</code> and <code>setParameters</code>
|
79
|
+
* must be called prior to calling any other methods.
|
80
|
+
*/
|
81
|
+
public LineStroker() {
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Constructs a <code>LineStroker</code>.
|
86
|
+
*
|
87
|
+
* @param output
|
88
|
+
* an output <code>LineStroker</code>.
|
89
|
+
* @param lineWidth
|
90
|
+
* the desired line width in pixels, in S15.16 format.
|
91
|
+
* @param capStyle
|
92
|
+
* the desired end cap style, one of <code>CAP_BUTT</code>,
|
93
|
+
* <code>CAP_ROUND</code> or <code>CAP_SQUARE</code>.
|
94
|
+
* @param joinStyle
|
95
|
+
* the desired line join style, one of <code>JOIN_MITER</code>,
|
96
|
+
* <code>JOIN_ROUND</code> or <code>JOIN_BEVEL</code>.
|
97
|
+
* @param miterLimit
|
98
|
+
* the desired miter limit, in S15.16 format.
|
99
|
+
* @param transform
|
100
|
+
* a <code>Transform4</code> object indicating the transform that has
|
101
|
+
* been previously applied to all incoming coordinates. This is
|
102
|
+
* required in order to produce consistently shaped end caps and
|
103
|
+
* joins.
|
104
|
+
*/
|
105
|
+
public LineStroker(LineStroker output, int lineWidth, int capStyle, int joinStyle,
|
106
|
+
int miterLimit, PMatrix2D transform) {
|
107
|
+
setOutput(output);
|
108
|
+
setParameters(lineWidth, capStyle, joinStyle, miterLimit, transform);
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Sets the output <code>LineStroker</code> of this <code>LineStroker</code>.
|
113
|
+
*
|
114
|
+
* @param output
|
115
|
+
* an output <code>LineStroker</code>.
|
116
|
+
*/
|
117
|
+
public void setOutput(LineStroker output) {
|
118
|
+
this.output = output;
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Sets the parameters of this <code>LineStroker</code>.
|
123
|
+
*
|
124
|
+
* @param lineWidth
|
125
|
+
* the desired line width in pixels, in S15.16 format.
|
126
|
+
* @param capStyle
|
127
|
+
* the desired end cap style, one of <code>CAP_BUTT</code>,
|
128
|
+
* <code>CAP_ROUND</code> or <code>CAP_SQUARE</code>.
|
129
|
+
* @param joinStyle
|
130
|
+
* the desired line join style, one of <code>JOIN_MITER</code>,
|
131
|
+
* <code>JOIN_ROUND</code> or <code>JOIN_BEVEL</code>.
|
132
|
+
* @param miterLimit
|
133
|
+
* the desired miter limit, in S15.16 format.
|
134
|
+
* @param transform
|
135
|
+
* a <code>Transform4</code> object indicating the transform that has
|
136
|
+
* been previously applied to all incoming coordinates. This is
|
137
|
+
* required in order to produce consistently shaped end caps and
|
138
|
+
* joins.
|
139
|
+
*/
|
140
|
+
public void setParameters(int lineWidth, int capStyle, int joinStyle,
|
141
|
+
int miterLimit, PMatrix2D transform) {
|
142
|
+
this.m00 = LinePath.FloatToS15_16(transform.m00);
|
143
|
+
this.m01 = LinePath.FloatToS15_16(transform.m01);
|
144
|
+
this.m10 = LinePath.FloatToS15_16(transform.m10);
|
145
|
+
this.m11 = LinePath.FloatToS15_16(transform.m11);
|
146
|
+
|
147
|
+
this.lineWidth2 = lineWidth >> 1;
|
148
|
+
this.scaledLineWidth2 = ((long) m00 * lineWidth2) >> 16;
|
149
|
+
this.capStyle = capStyle;
|
150
|
+
this.joinStyle = joinStyle;
|
151
|
+
|
152
|
+
this.m00_2_m01_2 = (double) m00 * m00 + (double) m01 * m01;
|
153
|
+
this.m10_2_m11_2 = (double) m10 * m10 + (double) m11 * m11;
|
154
|
+
this.m00_m10_m01_m11 = (double) m00 * m10 + (double) m01 * m11;
|
155
|
+
|
156
|
+
double dm00 = m00 / 65536.0;
|
157
|
+
double dm01 = m01 / 65536.0;
|
158
|
+
double dm10 = m10 / 65536.0;
|
159
|
+
double dm11 = m11 / 65536.0;
|
160
|
+
double determinant = dm00 * dm11 - dm01 * dm10;
|
161
|
+
|
162
|
+
if (joinStyle == LinePath.JOIN_MITER) {
|
163
|
+
double limit = (miterLimit / 65536.0) * (lineWidth2 / 65536.0)
|
164
|
+
* determinant;
|
165
|
+
double limitSq = limit * limit;
|
166
|
+
this.miterLimitSq = (long) (limitSq * 65536.0 * 65536.0);
|
167
|
+
}
|
150
168
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
169
|
+
this.numPenSegments = (int) (3.14159f * lineWidth / 65536.0f);
|
170
|
+
if (pen_dx == null || pen_dx.length < numPenSegments) {
|
171
|
+
this.pen_dx = new int[numPenSegments];
|
172
|
+
this.pen_dy = new int[numPenSegments];
|
173
|
+
this.penIncluded = new boolean[numPenSegments];
|
174
|
+
this.join = new int[2 * numPenSegments];
|
175
|
+
}
|
157
176
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
this.pen_dy = new int[numPenSegments];
|
162
|
-
this.penIncluded = new boolean[numPenSegments];
|
163
|
-
this.join = new int[2 * numPenSegments];
|
164
|
-
}
|
177
|
+
for (int i = 0; i < numPenSegments; i++) {
|
178
|
+
double r = lineWidth / 2.0;
|
179
|
+
double theta = i * 2 * Math.PI / numPenSegments;
|
165
180
|
|
166
|
-
|
167
|
-
|
168
|
-
|
181
|
+
double cos = Math.cos(theta);
|
182
|
+
double sin = Math.sin(theta);
|
183
|
+
pen_dx[i] = (int) (r * (dm00 * cos + dm01 * sin));
|
184
|
+
pen_dy[i] = (int) (r * (dm10 * cos + dm11 * sin));
|
185
|
+
}
|
169
186
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
187
|
+
prev = LinePath.SEG_CLOSE;
|
188
|
+
rindex = 0;
|
189
|
+
started = false;
|
190
|
+
lineToOrigin = false;
|
191
|
+
}
|
192
|
+
|
193
|
+
private void computeOffset(int x0, int y0, int x1, int y1, int[] m) {
|
194
|
+
long lx = (long) x1 - (long) x0;
|
195
|
+
long ly = (long) y1 - (long) y0;
|
196
|
+
|
197
|
+
int dx, dy;
|
198
|
+
if (m00 > 0 && m00 == m11 && m01 == 0 & m10 == 0) {
|
199
|
+
long ilen = LinePath.hypot(lx, ly);
|
200
|
+
if (ilen == 0) {
|
201
|
+
dx = dy = 0;
|
202
|
+
} else {
|
203
|
+
dx = (int) ((ly * scaledLineWidth2) / ilen);
|
204
|
+
dy = (int) (-(lx * scaledLineWidth2) / ilen);
|
205
|
+
}
|
206
|
+
} else {
|
207
|
+
double dlx = x1 - x0;
|
208
|
+
double dly = y1 - y0;
|
209
|
+
double det = (double) m00 * m11 - (double) m01 * m10;
|
210
|
+
int sdet = (det > 0) ? 1 : -1;
|
211
|
+
double a = dly * m00 - dlx * m10;
|
212
|
+
double b = dly * m01 - dlx * m11;
|
213
|
+
double dh = LinePath.hypot(a, b);
|
214
|
+
double div = sdet * lineWidth2 / (65536.0 * dh);
|
215
|
+
double ddx = dly * m00_2_m01_2 - dlx * m00_m10_m01_m11;
|
216
|
+
double ddy = dly * m00_m10_m01_m11 - dlx * m10_2_m11_2;
|
217
|
+
dx = (int) (ddx * div);
|
218
|
+
dy = (int) (ddy * div);
|
219
|
+
}
|
175
220
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
lineToOrigin = false;
|
180
|
-
}
|
181
|
-
|
182
|
-
private void computeOffset(int x0, int y0, int x1, int y1, int[] m) {
|
183
|
-
long lx = (long) x1 - (long) x0;
|
184
|
-
long ly = (long) y1 - (long) y0;
|
185
|
-
|
186
|
-
int dx, dy;
|
187
|
-
if (m00 > 0 && m00 == m11 && m01 == 0 & m10 == 0) {
|
188
|
-
long ilen = LinePath.hypot(lx, ly);
|
189
|
-
if (ilen == 0) {
|
190
|
-
dx = dy = 0;
|
191
|
-
} else {
|
192
|
-
dx = (int) ((ly * scaledLineWidth2) / ilen);
|
193
|
-
dy = (int) (-(lx * scaledLineWidth2) / ilen);
|
194
|
-
}
|
195
|
-
} else {
|
196
|
-
double dlx = x1 - x0;
|
197
|
-
double dly = y1 - y0;
|
198
|
-
double det = (double) m00 * m11 - (double) m01 * m10;
|
199
|
-
int sdet = (det > 0) ? 1 : -1;
|
200
|
-
double a = dly * m00 - dlx * m10;
|
201
|
-
double b = dly * m01 - dlx * m11;
|
202
|
-
double dh = LinePath.hypot(a, b);
|
203
|
-
double div = sdet * lineWidth2 / (65536.0 * dh);
|
204
|
-
double ddx = dly * m00_2_m01_2 - dlx * m00_m10_m01_m11;
|
205
|
-
double ddy = dly * m00_m10_m01_m11 - dlx * m10_2_m11_2;
|
206
|
-
dx = (int) (ddx * div);
|
207
|
-
dy = (int) (ddy * div);
|
208
|
-
}
|
221
|
+
m[0] = dx;
|
222
|
+
m[1] = dy;
|
223
|
+
}
|
209
224
|
|
210
|
-
|
211
|
-
|
225
|
+
private void ensureCapacity(int newrindex) {
|
226
|
+
if (reverse.length < newrindex) {
|
227
|
+
int[] tmp = new int[Math.max(newrindex, 6 * reverse.length / 5)];
|
228
|
+
System.arraycopy(reverse, 0, tmp, 0, rindex);
|
229
|
+
this.reverse = tmp;
|
212
230
|
}
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
231
|
+
}
|
232
|
+
|
233
|
+
private boolean isCCW(int x0, int y0, int x1, int y1, int x2, int y2) {
|
234
|
+
int dx0 = x1 - x0;
|
235
|
+
int dy0 = y1 - y0;
|
236
|
+
int dx1 = x2 - x1;
|
237
|
+
int dy1 = y2 - y1;
|
238
|
+
return (long) dx0 * dy1 < (long) dy0 * dx1;
|
239
|
+
}
|
240
|
+
|
241
|
+
private boolean side(int x, int y, int x0, int y0, int x1, int y1) {
|
242
|
+
long lx = x;
|
243
|
+
long ly = y;
|
244
|
+
long lx0 = x0;
|
245
|
+
long ly0 = y0;
|
246
|
+
long lx1 = x1;
|
247
|
+
long ly1 = y1;
|
248
|
+
|
249
|
+
return (ly0 - ly1) * lx + (lx1 - lx0) * ly + (lx0 * ly1 - lx1 * ly0) > 0;
|
250
|
+
}
|
251
|
+
|
252
|
+
private int computeRoundJoin(int cx, int cy, int xa, int ya, int xb, int yb,
|
253
|
+
int side, boolean flip, int[] join) {
|
254
|
+
int px, py;
|
255
|
+
int ncoords = 0;
|
256
|
+
|
257
|
+
boolean centerSide;
|
258
|
+
if (side == 0) {
|
259
|
+
centerSide = side(cx, cy, xa, ya, xb, yb);
|
260
|
+
} else {
|
261
|
+
centerSide = (side == 1);
|
220
262
|
}
|
263
|
+
for (int i = 0; i < numPenSegments; i++) {
|
264
|
+
px = cx + pen_dx[i];
|
265
|
+
py = cy + pen_dy[i];
|
221
266
|
|
222
|
-
|
223
|
-
|
224
|
-
int dy0 = y1 - y0;
|
225
|
-
int dx1 = x2 - x1;
|
226
|
-
int dy1 = y2 - y1;
|
227
|
-
return (long) dx0 * dy1 < (long) dy0 * dx1;
|
267
|
+
boolean penSide = side(px, py, xa, ya, xb, yb);
|
268
|
+
penIncluded[i] = penSide != centerSide;
|
228
269
|
}
|
229
270
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
271
|
+
int start = -1, end = -1;
|
272
|
+
for (int i = 0; i < numPenSegments; i++) {
|
273
|
+
if (penIncluded[i]
|
274
|
+
&& !penIncluded[(i + numPenSegments - 1) % numPenSegments]) {
|
275
|
+
start = i;
|
276
|
+
}
|
277
|
+
if (penIncluded[i] && !penIncluded[(i + 1) % numPenSegments]) {
|
278
|
+
end = i;
|
279
|
+
}
|
239
280
|
}
|
240
281
|
|
241
|
-
|
242
|
-
|
243
|
-
int px, py;
|
244
|
-
int ncoords = 0;
|
245
|
-
|
246
|
-
boolean centerSide;
|
247
|
-
if (side == 0) {
|
248
|
-
centerSide = side(cx, cy, xa, ya, xb, yb);
|
249
|
-
} else {
|
250
|
-
centerSide = (side == 1) ? true : false;
|
251
|
-
}
|
252
|
-
for (int i = 0; i < numPenSegments; i++) {
|
253
|
-
px = cx + pen_dx[i];
|
254
|
-
py = cy + pen_dy[i];
|
255
|
-
|
256
|
-
boolean penSide = side(px, py, xa, ya, xb, yb);
|
257
|
-
if (penSide != centerSide) {
|
258
|
-
penIncluded[i] = true;
|
259
|
-
} else {
|
260
|
-
penIncluded[i] = false;
|
261
|
-
}
|
262
|
-
}
|
263
|
-
|
264
|
-
int start = -1, end = -1;
|
265
|
-
for (int i = 0; i < numPenSegments; i++) {
|
266
|
-
if (penIncluded[i]
|
267
|
-
&& !penIncluded[(i + numPenSegments - 1) % numPenSegments]) {
|
268
|
-
start = i;
|
269
|
-
}
|
270
|
-
if (penIncluded[i] && !penIncluded[(i + 1) % numPenSegments]) {
|
271
|
-
end = i;
|
272
|
-
}
|
273
|
-
}
|
274
|
-
|
275
|
-
if (end < start) {
|
276
|
-
end += numPenSegments;
|
277
|
-
}
|
278
|
-
|
279
|
-
if (start != -1 && end != -1) {
|
280
|
-
long dxa = cx + pen_dx[start] - xa;
|
281
|
-
long dya = cy + pen_dy[start] - ya;
|
282
|
-
long dxb = cx + pen_dx[start] - xb;
|
283
|
-
long dyb = cy + pen_dy[start] - yb;
|
284
|
-
|
285
|
-
boolean rev = (dxa * dxa + dya * dya > dxb * dxb + dyb * dyb);
|
286
|
-
int i = rev ? end : start;
|
287
|
-
int incr = rev ? -1 : 1;
|
288
|
-
while (true) {
|
289
|
-
int idx = i % numPenSegments;
|
290
|
-
px = cx + pen_dx[idx];
|
291
|
-
py = cy + pen_dy[idx];
|
292
|
-
join[ncoords++] = px;
|
293
|
-
join[ncoords++] = py;
|
294
|
-
if (i == (rev ? start : end)) {
|
295
|
-
break;
|
296
|
-
}
|
297
|
-
i += incr;
|
298
|
-
}
|
299
|
-
}
|
300
|
-
|
301
|
-
return ncoords / 2;
|
282
|
+
if (end < start) {
|
283
|
+
end += numPenSegments;
|
302
284
|
}
|
303
285
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
286
|
+
if (start != -1 && end != -1) {
|
287
|
+
long dxa = cx + pen_dx[start] - xa;
|
288
|
+
long dya = cy + pen_dy[start] - ya;
|
289
|
+
long dxb = cx + pen_dx[start] - xb;
|
290
|
+
long dyb = cy + pen_dy[start] - yb;
|
291
|
+
|
292
|
+
boolean rev = (dxa * dxa + dya * dya > dxb * dxb + dyb * dyb);
|
293
|
+
int i = rev ? end : start;
|
294
|
+
int incr = rev ? -1 : 1;
|
295
|
+
while (true) {
|
296
|
+
int idx = i % numPenSegments;
|
297
|
+
px = cx + pen_dx[idx];
|
298
|
+
py = cy + pen_dy[idx];
|
299
|
+
join[ncoords++] = px;
|
300
|
+
join[ncoords++] = py;
|
301
|
+
if (i == (rev ? start : end)) {
|
302
|
+
break;
|
303
|
+
}
|
304
|
+
i += incr;
|
305
|
+
}
|
306
|
+
}
|
315
307
|
|
316
|
-
|
317
|
-
|
318
|
-
long len = domx * domx + domy * domy;
|
319
|
-
if (len < threshold) {
|
320
|
-
return;
|
321
|
-
}
|
308
|
+
return ncoords / 2;
|
309
|
+
}
|
322
310
|
|
323
|
-
|
324
|
-
|
325
|
-
omy = -omy;
|
326
|
-
mx = -mx;
|
327
|
-
my = -my;
|
328
|
-
}
|
311
|
+
//private static final long ROUND_JOIN_THRESHOLD = 1000L;
|
312
|
+
private static final long ROUND_JOIN_THRESHOLD = 100000000L;
|
329
313
|
|
330
|
-
|
331
|
-
int by0 = y + omy;
|
332
|
-
int bx1 = x + mx;
|
333
|
-
int by1 = y + my;
|
314
|
+
private static final long ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000L;
|
334
315
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
316
|
+
private void drawRoundJoin(int x, int y, int omx, int omy, int mx, int my,
|
317
|
+
int side, int color,
|
318
|
+
boolean flip, boolean rev, long threshold) {
|
319
|
+
if ((omx == 0 && omy == 0) || (mx == 0 && my == 0)) {
|
320
|
+
return;
|
339
321
|
}
|
340
322
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
long y0 = iy0;
|
347
|
-
long x1 = ix1;
|
348
|
-
long y1 = iy1;
|
349
|
-
|
350
|
-
long x0p = ix0p;
|
351
|
-
long y0p = iy0p;
|
352
|
-
long x1p = ix1p;
|
353
|
-
long y1p = iy1p;
|
354
|
-
|
355
|
-
long x10 = x1 - x0;
|
356
|
-
long y10 = y1 - y0;
|
357
|
-
long x10p = x1p - x0p;
|
358
|
-
long y10p = y1p - y0p;
|
359
|
-
|
360
|
-
long den = (x10 * y10p - x10p * y10) >> 16;
|
361
|
-
if (den == 0) {
|
362
|
-
m[0] = ix0;
|
363
|
-
m[1] = iy0;
|
364
|
-
return;
|
365
|
-
}
|
366
|
-
|
367
|
-
long t = (x1p * (y0 - y0p) - x0 * y10p + x0p * (y1p - y0)) >> 16;
|
368
|
-
m[0] = (int) (x0 + (t * x10) / den);
|
369
|
-
m[1] = (int) (y0 + (t * y10) / den);
|
323
|
+
long domx = (long) omx - mx;
|
324
|
+
long domy = (long) omy - my;
|
325
|
+
long len = domx * domx + domy * domy;
|
326
|
+
if (len < threshold) {
|
327
|
+
return;
|
370
328
|
}
|
371
329
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
if (px0 == x0 && py0 == y0) {
|
379
|
-
return;
|
380
|
-
}
|
381
|
-
if (x0 == x1 && y0 == y1) {
|
382
|
-
return;
|
383
|
-
}
|
384
|
-
|
385
|
-
if (rev) {
|
386
|
-
omx = -omx;
|
387
|
-
omy = -omy;
|
388
|
-
mx = -mx;
|
389
|
-
my = -my;
|
390
|
-
}
|
391
|
-
|
392
|
-
computeMiter(px0 + omx, py0 + omy, x0 + omx, y0 + omy, x0 + mx, y0 + my, x1
|
393
|
-
+ mx, y1 + my, miter);
|
330
|
+
if (rev) {
|
331
|
+
omx = -omx;
|
332
|
+
omy = -omy;
|
333
|
+
mx = -mx;
|
334
|
+
my = -my;
|
335
|
+
}
|
394
336
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
long b = (dy * m01 - dx * m11) >> 16;
|
400
|
-
long lenSq = a * a + b * b;
|
337
|
+
int bx0 = x + omx;
|
338
|
+
int by0 = y + omy;
|
339
|
+
int bx1 = x + mx;
|
340
|
+
int by1 = y + my;
|
401
341
|
|
402
|
-
|
403
|
-
|
404
|
-
|
342
|
+
int npoints = computeRoundJoin(x, y, bx0, by0, bx1, by1, side, flip, join);
|
343
|
+
for (int i = 0; i < npoints; i++) {
|
344
|
+
emitLineTo(join[2 * i], join[2 * i + 1], color, rev);
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
// Return the intersection point of the lines (ix0, iy0) -> (ix1, iy1)
|
349
|
+
// and (ix0p, iy0p) -> (ix1p, iy1p) in m[0] and m[1]
|
350
|
+
private void computeMiter(int ix0, int iy0, int ix1, int iy1, int ix0p,
|
351
|
+
int iy0p, int ix1p, int iy1p, int[] m) {
|
352
|
+
long x0 = ix0;
|
353
|
+
long y0 = iy0;
|
354
|
+
long x1 = ix1;
|
355
|
+
long y1 = iy1;
|
356
|
+
|
357
|
+
long x0p = ix0p;
|
358
|
+
long y0p = iy0p;
|
359
|
+
long x1p = ix1p;
|
360
|
+
long y1p = iy1p;
|
361
|
+
|
362
|
+
long x10 = x1 - x0;
|
363
|
+
long y10 = y1 - y0;
|
364
|
+
long x10p = x1p - x0p;
|
365
|
+
long y10p = y1p - y0p;
|
366
|
+
|
367
|
+
long den = (x10 * y10p - x10p * y10) >> 16;
|
368
|
+
if (den == 0) {
|
369
|
+
m[0] = ix0;
|
370
|
+
m[1] = iy0;
|
371
|
+
return;
|
405
372
|
}
|
406
373
|
|
407
|
-
|
408
|
-
|
374
|
+
long t = (x1p * (y0 - y0p) - x0 * y10p + x0p * (y1p - y0)) >> 16;
|
375
|
+
m[0] = (int) (x0 + (t * x10) / den);
|
376
|
+
m[1] = (int) (y0 + (t * y10) / den);
|
377
|
+
}
|
409
378
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
379
|
+
private void drawMiter(int px0, int py0, int x0, int y0, int x1, int y1,
|
380
|
+
int omx, int omy, int mx, int my, int color,
|
381
|
+
boolean rev) {
|
382
|
+
if (mx == omx && my == omy) {
|
383
|
+
return;
|
384
|
+
}
|
385
|
+
if (px0 == x0 && py0 == y0) {
|
386
|
+
return;
|
387
|
+
}
|
388
|
+
if (x0 == x1 && y0 == y1) {
|
389
|
+
return;
|
390
|
+
}
|
415
391
|
|
416
|
-
|
417
|
-
|
418
|
-
|
392
|
+
if (rev) {
|
393
|
+
omx = -omx;
|
394
|
+
omy = -omy;
|
395
|
+
mx = -mx;
|
396
|
+
my = -my;
|
397
|
+
}
|
419
398
|
|
420
|
-
|
421
|
-
|
422
|
-
this.scolor0 = this.color0 = c0;
|
423
|
-
this.rindex = 0;
|
424
|
-
this.started = false;
|
425
|
-
this.joinSegment = false;
|
426
|
-
this.prev = LinePath.SEG_MOVETO;
|
427
|
-
}
|
428
|
-
|
429
|
-
boolean joinSegment = false;
|
430
|
-
|
431
|
-
public void lineJoin() {
|
432
|
-
// System.out.println("LineStroker.lineJoin()");
|
433
|
-
this.joinSegment = true;
|
434
|
-
}
|
435
|
-
|
436
|
-
public void lineTo(int x1, int y1, int c1) {
|
437
|
-
// System.out.println("LineStroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")");
|
438
|
-
|
439
|
-
if (lineToOrigin) {
|
440
|
-
if (x1 == sx0 && y1 == sy0) {
|
441
|
-
// staying in the starting point
|
442
|
-
return;
|
443
|
-
}
|
444
|
-
|
445
|
-
// not closing the path, do the previous lineTo
|
446
|
-
lineToImpl(sx0, sy0, scolor0, joinToOrigin);
|
447
|
-
lineToOrigin = false;
|
448
|
-
} else if (x1 == x0 && y1 == y0) {
|
449
|
-
return;
|
450
|
-
} else if (x1 == sx0 && y1 == sy0) {
|
451
|
-
lineToOrigin = true;
|
452
|
-
joinToOrigin = joinSegment;
|
453
|
-
joinSegment = false;
|
454
|
-
return;
|
455
|
-
}
|
399
|
+
computeMiter(px0 + omx, py0 + omy, x0 + omx, y0 + omy, x0 + mx, y0 + my, x1
|
400
|
+
+ mx, y1 + my, miter);
|
456
401
|
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
int mx = offset[0];
|
464
|
-
int my = offset[1];
|
465
|
-
|
466
|
-
if (!started) {
|
467
|
-
emitMoveTo(x0 + mx, y0 + my, color0);
|
468
|
-
this.sx1 = x1;
|
469
|
-
this.sy1 = y1;
|
470
|
-
this.mx0 = mx;
|
471
|
-
this.my0 = my;
|
472
|
-
started = true;
|
473
|
-
} else {
|
474
|
-
boolean ccw = isCCW(px0, py0, x0, y0, x1, y1);
|
475
|
-
if (joinSegment) {
|
476
|
-
if (joinStyle == LinePath.JOIN_MITER) {
|
477
|
-
drawMiter(px0, py0, x0, y0, x1, y1, omx, omy, mx, my, color0, ccw);
|
478
|
-
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
479
|
-
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
480
|
-
ROUND_JOIN_THRESHOLD);
|
481
|
-
}
|
482
|
-
} else {
|
483
|
-
// Draw internal joins as round
|
484
|
-
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
485
|
-
ROUND_JOIN_INTERNAL_THRESHOLD);
|
486
|
-
}
|
487
|
-
|
488
|
-
emitLineTo(x0, y0, color0, !ccw);
|
489
|
-
}
|
402
|
+
// Compute miter length in untransformed coordinates
|
403
|
+
long dx = (long) miter[0] - x0;
|
404
|
+
long dy = (long) miter[1] - y0;
|
405
|
+
long a = (dy * m00 - dx * m10) >> 16;
|
406
|
+
long b = (dy * m01 - dx * m11) >> 16;
|
407
|
+
long lenSq = a * a + b * b;
|
490
408
|
|
491
|
-
|
492
|
-
|
409
|
+
if (lenSq < miterLimitSq) {
|
410
|
+
emitLineTo(miter[0], miter[1], color, rev);
|
411
|
+
}
|
412
|
+
}
|
493
413
|
|
494
|
-
|
495
|
-
|
414
|
+
public void moveTo(int x0, int y0, int c0) {
|
415
|
+
// System.out.println("LineStroker.moveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
|
496
416
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
this.pcolor0 = color0;
|
502
|
-
this.x0 = x1;
|
503
|
-
this.y0 = y1;
|
504
|
-
this.color0 = c1;
|
505
|
-
this.prev = LinePath.SEG_LINETO;
|
417
|
+
if (lineToOrigin) {
|
418
|
+
// not closing the path, do the previous lineTo
|
419
|
+
lineToImpl(sx0, sy0, scolor0, joinToOrigin);
|
420
|
+
lineToOrigin = false;
|
506
421
|
}
|
507
422
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
lineToOrigin = false;
|
512
|
-
}
|
423
|
+
if (prev == LinePath.SEG_LINETO) {
|
424
|
+
finish();
|
425
|
+
}
|
513
426
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
427
|
+
this.sx0 = this.x0 = x0;
|
428
|
+
this.sy0 = this.y0 = y0;
|
429
|
+
this.scolor0 = this.color0 = c0;
|
430
|
+
this.rindex = 0;
|
431
|
+
this.started = false;
|
432
|
+
this.joinSegment = false;
|
433
|
+
this.prev = LinePath.SEG_MOVETO;
|
434
|
+
}
|
435
|
+
|
436
|
+
boolean joinSegment = false;
|
437
|
+
|
438
|
+
public void lineJoin() {
|
439
|
+
// System.out.println("LineStroker.lineJoin()");
|
440
|
+
this.joinSegment = true;
|
441
|
+
}
|
442
|
+
|
443
|
+
public void lineTo(int x1, int y1, int c1) {
|
444
|
+
// System.out.println("LineStroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")");
|
445
|
+
|
446
|
+
if (lineToOrigin) {
|
447
|
+
if (x1 == sx0 && y1 == sy0) {
|
448
|
+
// staying in the starting point
|
449
|
+
return;
|
450
|
+
}
|
451
|
+
|
452
|
+
// not closing the path, do the previous lineTo
|
453
|
+
lineToImpl(sx0, sy0, scolor0, joinToOrigin);
|
454
|
+
lineToOrigin = false;
|
455
|
+
} else if (x1 == x0 && y1 == y0) {
|
456
|
+
return;
|
457
|
+
} else if (x1 == sx0 && y1 == sy0) {
|
458
|
+
lineToOrigin = true;
|
459
|
+
joinToOrigin = joinSegment;
|
460
|
+
joinSegment = false;
|
461
|
+
return;
|
462
|
+
}
|
518
463
|
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
464
|
+
lineToImpl(x1, y1, c1, joinSegment);
|
465
|
+
joinSegment = false;
|
466
|
+
}
|
467
|
+
|
468
|
+
private void lineToImpl(int x1, int y1, int c1, boolean joinSegment) {
|
469
|
+
computeOffset(x0, y0, x1, y1, offset);
|
470
|
+
int mx = offset[0];
|
471
|
+
int my = offset[1];
|
472
|
+
|
473
|
+
if (!started) {
|
474
|
+
emitMoveTo(x0 + mx, y0 + my, color0);
|
475
|
+
this.sx1 = x1;
|
476
|
+
this.sy1 = y1;
|
477
|
+
this.mx0 = mx;
|
478
|
+
this.my0 = my;
|
479
|
+
started = true;
|
480
|
+
} else {
|
481
|
+
boolean ccw = isCCW(px0, py0, x0, y0, x1, y1);
|
482
|
+
if (joinSegment) {
|
483
|
+
if (joinStyle == LinePath.JOIN_MITER) {
|
484
|
+
drawMiter(px0, py0, x0, y0, x1, y1, omx, omy, mx, my, color0, ccw);
|
485
|
+
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
486
|
+
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
530
487
|
ROUND_JOIN_THRESHOLD);
|
531
|
-
}
|
532
|
-
} else {
|
533
|
-
// Draw internal joins as round
|
534
|
-
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
535
|
-
ROUND_JOIN_INTERNAL_THRESHOLD);
|
536
488
|
}
|
489
|
+
} else {
|
490
|
+
// Draw internal joins as round
|
491
|
+
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
492
|
+
ROUND_JOIN_INTERNAL_THRESHOLD);
|
493
|
+
}
|
537
494
|
|
538
|
-
|
539
|
-
|
495
|
+
emitLineTo(x0, y0, color0, !ccw);
|
496
|
+
}
|
540
497
|
|
541
|
-
|
498
|
+
emitLineTo(x0 + mx, y0 + my, color0, false);
|
499
|
+
emitLineTo(x1 + mx, y1 + my, c1, false);
|
500
|
+
|
501
|
+
emitLineTo(x0 - mx, y0 - my, color0, true);
|
502
|
+
emitLineTo(x1 - mx, y1 - my, c1, true);
|
503
|
+
|
504
|
+
this.omx = mx;
|
505
|
+
this.omy = my;
|
506
|
+
this.px0 = x0;
|
507
|
+
this.py0 = y0;
|
508
|
+
this.pcolor0 = color0;
|
509
|
+
this.x0 = x1;
|
510
|
+
this.y0 = y1;
|
511
|
+
this.color0 = c1;
|
512
|
+
this.prev = LinePath.SEG_LINETO;
|
513
|
+
}
|
514
|
+
|
515
|
+
public void close() {
|
516
|
+
if (lineToOrigin) {
|
517
|
+
// ignore the previous lineTo
|
518
|
+
lineToOrigin = false;
|
519
|
+
}
|
542
520
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
548
|
-
drawRoundJoin(sx0, sy0, mx, my, mx0, my0, 0, scolor0, false, false,
|
549
|
-
ROUND_JOIN_THRESHOLD);
|
550
|
-
}
|
551
|
-
}
|
521
|
+
if (!started) {
|
522
|
+
finish();
|
523
|
+
return;
|
524
|
+
}
|
552
525
|
|
553
|
-
|
554
|
-
|
526
|
+
computeOffset(x0, y0, sx0, sy0, offset);
|
527
|
+
int mx = offset[0];
|
528
|
+
int my = offset[1];
|
529
|
+
|
530
|
+
// Draw penultimate join
|
531
|
+
boolean ccw = isCCW(px0, py0, x0, y0, sx0, sy0);
|
532
|
+
if (joinSegment) {
|
533
|
+
if (joinStyle == LinePath.JOIN_MITER) {
|
534
|
+
drawMiter(px0, py0, x0, y0, sx0, sy0, omx, omy, mx, my, pcolor0, ccw);
|
535
|
+
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
536
|
+
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
537
|
+
ROUND_JOIN_THRESHOLD);
|
538
|
+
}
|
539
|
+
} else {
|
540
|
+
// Draw internal joins as round
|
541
|
+
drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
|
542
|
+
ROUND_JOIN_INTERNAL_THRESHOLD);
|
543
|
+
}
|
555
544
|
|
556
|
-
|
557
|
-
|
558
|
-
if (joinStyle == LinePath.JOIN_MITER) {
|
559
|
-
drawMiter(x0, y0, sx0, sy0, sx1, sy1, -mx, -my, -mx0, -my0, color0,
|
560
|
-
false);
|
561
|
-
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
562
|
-
drawRoundJoin(sx0, sy0, -mx, -my, -mx0, -my0, 0, scolor0, true, false,
|
563
|
-
ROUND_JOIN_THRESHOLD);
|
564
|
-
}
|
565
|
-
}
|
545
|
+
emitLineTo(x0 + mx, y0 + my, color0);
|
546
|
+
emitLineTo(sx0 + mx, sy0 + my, scolor0);
|
566
547
|
|
567
|
-
|
568
|
-
emitLineTo(x0 - mx, y0 - my, color0);
|
569
|
-
for (int i = rindex - 3; i >= 0; i -= 3) {
|
570
|
-
emitLineTo(reverse[i], reverse[i + 1], reverse[i + 2]);
|
571
|
-
}
|
548
|
+
ccw = isCCW(x0, y0, sx0, sy0, sx1, sy1);
|
572
549
|
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
550
|
+
// Draw final join on the outside
|
551
|
+
if (!ccw) {
|
552
|
+
if (joinStyle == LinePath.JOIN_MITER) {
|
553
|
+
drawMiter(x0, y0, sx0, sy0, sx1, sy1, mx, my, mx0, my0, color0, false);
|
554
|
+
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
555
|
+
drawRoundJoin(sx0, sy0, mx, my, mx0, my0, 0, scolor0, false, false,
|
556
|
+
ROUND_JOIN_THRESHOLD);
|
557
|
+
}
|
580
558
|
}
|
581
559
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
this.joinSegment = false;
|
595
|
-
this.prev = LinePath.SEG_MOVETO;
|
560
|
+
emitLineTo(sx0 + mx0, sy0 + my0, scolor0);
|
561
|
+
emitLineTo(sx0 - mx0, sy0 - my0, scolor0); // same as reverse[0], reverse[1]
|
562
|
+
|
563
|
+
// Draw final join on the inside
|
564
|
+
if (ccw) {
|
565
|
+
if (joinStyle == LinePath.JOIN_MITER) {
|
566
|
+
drawMiter(x0, y0, sx0, sy0, sx1, sy1, -mx, -my, -mx0, -my0, color0,
|
567
|
+
false);
|
568
|
+
} else if (joinStyle == LinePath.JOIN_ROUND) {
|
569
|
+
drawRoundJoin(sx0, sy0, -mx, -my, -mx0, -my0, 0, scolor0, true, false,
|
570
|
+
ROUND_JOIN_THRESHOLD);
|
571
|
+
}
|
596
572
|
}
|
597
573
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
long llen = (int) LinePath.hypot(la, lb);
|
603
|
-
return llen;
|
574
|
+
emitLineTo(sx0 - mx, sy0 - my, scolor0);
|
575
|
+
emitLineTo(x0 - mx, y0 - my, color0);
|
576
|
+
for (int i = rindex - 3; i >= 0; i -= 3) {
|
577
|
+
emitLineTo(reverse[i], reverse[i + 1], reverse[i + 2]);
|
604
578
|
}
|
605
579
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
emitLineTo(capx - omx, capy - omy, color0);
|
622
|
-
}
|
623
|
-
}
|
580
|
+
this.x0 = this.sx0;
|
581
|
+
this.y0 = this.sy0;
|
582
|
+
this.rindex = 0;
|
583
|
+
this.started = false;
|
584
|
+
this.joinSegment = false;
|
585
|
+
this.prev = LinePath.SEG_CLOSE;
|
586
|
+
emitClose();
|
587
|
+
}
|
588
|
+
|
589
|
+
public void end() {
|
590
|
+
if (lineToOrigin) {
|
591
|
+
// not closing the path, do the previous lineTo
|
592
|
+
lineToImpl(sx0, sy0, scolor0, joinToOrigin);
|
593
|
+
lineToOrigin = false;
|
594
|
+
}
|
624
595
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
this.rindex = 0;
|
596
|
+
if (prev == LinePath.SEG_LINETO) {
|
597
|
+
finish();
|
598
|
+
}
|
629
599
|
|
630
|
-
|
631
|
-
|
600
|
+
output.end();
|
601
|
+
this.joinSegment = false;
|
602
|
+
this.prev = LinePath.SEG_MOVETO;
|
603
|
+
}
|
604
|
+
|
605
|
+
long lineLength(long ldx, long ldy) {
|
606
|
+
long ldet = ((long) m00 * m11 - (long) m01 * m10) >> 16;
|
607
|
+
long la = (ldy * m00 - ldx * m10) / ldet;
|
608
|
+
long lb = (ldy * m01 - ldx * m11) / ldet;
|
609
|
+
long llen = (int) LinePath.hypot(la, lb);
|
610
|
+
return llen;
|
611
|
+
}
|
612
|
+
|
613
|
+
private void finish() {
|
614
|
+
if (capStyle == LinePath.CAP_ROUND) {
|
615
|
+
drawRoundJoin(x0, y0, omx, omy, -omx, -omy, 1, color0, false, false,
|
632
616
|
ROUND_JOIN_THRESHOLD);
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
}
|
647
|
-
|
648
|
-
emitClose();
|
649
|
-
this.joinSegment = false;
|
617
|
+
} else if (capStyle == LinePath.CAP_SQUARE) {
|
618
|
+
long ldx = px0 - x0;
|
619
|
+
long ldy = py0 - y0;
|
620
|
+
long llen = lineLength(ldx, ldy);
|
621
|
+
if (0 < llen) {
|
622
|
+
long s = (long) lineWidth2 * 65536 / llen;
|
623
|
+
|
624
|
+
int capx = x0 - (int) (ldx * s >> 16);
|
625
|
+
int capy = y0 - (int) (ldy * s >> 16);
|
626
|
+
|
627
|
+
emitLineTo(capx + omx, capy + omy, color0);
|
628
|
+
emitLineTo(capx - omx, capy - omy, color0);
|
629
|
+
}
|
650
630
|
}
|
651
631
|
|
652
|
-
|
653
|
-
|
632
|
+
for (int i = rindex - 3; i >= 0; i -= 3) {
|
633
|
+
emitLineTo(reverse[i], reverse[i + 1], reverse[i + 2]);
|
654
634
|
}
|
635
|
+
this.rindex = 0;
|
655
636
|
|
656
|
-
|
657
|
-
|
637
|
+
if (capStyle == LinePath.CAP_ROUND) {
|
638
|
+
drawRoundJoin(sx0, sy0, -mx0, -my0, mx0, my0, 1, scolor0, false, false,
|
639
|
+
ROUND_JOIN_THRESHOLD);
|
640
|
+
} else if (capStyle == LinePath.CAP_SQUARE) {
|
641
|
+
long ldx = sx1 - sx0;
|
642
|
+
long ldy = sy1 - sy0;
|
643
|
+
long llen = lineLength(ldx, ldy);
|
644
|
+
if (0 < llen) {
|
645
|
+
long s = (long) lineWidth2 * 65536 / llen;
|
646
|
+
|
647
|
+
int capx = sx0 - (int) (ldx * s >> 16);
|
648
|
+
int capy = sy0 - (int) (ldy * s >> 16);
|
649
|
+
|
650
|
+
emitLineTo(capx - mx0, capy - my0, scolor0);
|
651
|
+
emitLineTo(capx + mx0, capy + my0, scolor0);
|
652
|
+
}
|
658
653
|
}
|
659
654
|
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
655
|
+
emitClose();
|
656
|
+
this.joinSegment = false;
|
657
|
+
}
|
658
|
+
|
659
|
+
private void emitMoveTo(int x0, int y0, int c0) {
|
660
|
+
output.moveTo(x0, y0, c0);
|
661
|
+
}
|
662
|
+
|
663
|
+
private void emitLineTo(int x1, int y1, int c1) {
|
664
|
+
output.lineTo(x1, y1, c1);
|
665
|
+
}
|
666
|
+
|
667
|
+
private void emitLineTo(int x1, int y1, int c1, boolean rev) {
|
668
|
+
if (rev) {
|
669
|
+
ensureCapacity(rindex + 3);
|
670
|
+
reverse[rindex++] = x1;
|
671
|
+
reverse[rindex++] = y1;
|
672
|
+
reverse[rindex++] = c1;
|
673
|
+
} else {
|
674
|
+
emitLineTo(x1, y1, c1);
|
669
675
|
}
|
676
|
+
}
|
670
677
|
|
671
|
-
|
672
|
-
|
673
|
-
|
678
|
+
private void emitClose() {
|
679
|
+
output.close();
|
680
|
+
}
|
674
681
|
}
|