propane 2.7.2-java → 2.8.0.pre-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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -0
  3. data/CHANGELOG.md +1 -1
  4. data/README.md +10 -8
  5. data/Rakefile +1 -1
  6. data/lib/propane/app.rb +3 -3
  7. data/lib/propane/version.rb +1 -1
  8. data/lib/{processing-core.jar → propane-2.8.0.jar} +0 -0
  9. data/library/control_panel/control_panel.rb +3 -2
  10. data/pom.rb +89 -88
  11. data/pom.xml +75 -46
  12. data/propane.gemspec +1 -2
  13. data/src/main/java/japplemenubar/JAppleMenuBar.java +88 -0
  14. data/src/main/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  15. data/src/{monkstone → main/java/monkstone}/ColorUtil.java +0 -0
  16. data/src/{monkstone → main/java/monkstone}/MathToolModule.java +0 -0
  17. data/src/{monkstone → main/java/monkstone}/PropaneLibrary.java +0 -0
  18. data/src/{monkstone → main/java/monkstone}/core/LibraryProxy.java +0 -0
  19. data/src/{monkstone → main/java/monkstone}/fastmath/Deglut.java +0 -0
  20. data/src/{monkstone → main/java/monkstone}/fastmath/package-info.java +0 -0
  21. data/src/{monkstone → main/java/monkstone}/filechooser/Chooser.java +0 -0
  22. data/src/{monkstone → main/java/monkstone}/noise/SimplexNoise.java +0 -0
  23. data/src/{monkstone → main/java/monkstone}/slider/CustomHorizontalSlider.java +0 -0
  24. data/src/{monkstone → main/java/monkstone}/slider/CustomVerticalSlider.java +0 -0
  25. data/src/{monkstone → main/java/monkstone}/slider/SimpleHorizontalSlider.java +0 -0
  26. data/src/{monkstone → main/java/monkstone}/slider/SimpleSlider.java +0 -0
  27. data/src/{monkstone → main/java/monkstone}/slider/SimpleVerticalSlider.java +0 -0
  28. data/src/{monkstone → main/java/monkstone}/slider/Slider.java +0 -0
  29. data/src/{monkstone → main/java/monkstone}/slider/SliderBar.java +0 -0
  30. data/src/{monkstone → main/java/monkstone}/slider/SliderGroup.java +0 -0
  31. data/src/{monkstone → main/java/monkstone}/slider/WheelHandler.java +0 -0
  32. data/src/{monkstone → main/java/monkstone}/vecmath/AppRender.java +0 -0
  33. data/src/{monkstone → main/java/monkstone}/vecmath/JRender.java +0 -0
  34. data/src/{monkstone → main/java/monkstone}/vecmath/ShapeRender.java +0 -0
  35. data/src/{monkstone → main/java/monkstone}/vecmath/package-info.java +0 -0
  36. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/Vec2.java +0 -0
  37. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/package-info.java +0 -0
  38. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/Vec3.java +0 -0
  39. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/package-info.java +0 -0
  40. data/src/{monkstone → main/java/monkstone}/videoevent/VideoInterface.java +0 -0
  41. data/src/{monkstone → main/java/monkstone}/videoevent/package-info.java +0 -0
  42. data/src/main/java/processing/awt/PGraphicsJava2D.java +3029 -0
  43. data/src/main/java/processing/awt/PShapeJava2D.java +377 -0
  44. data/src/main/java/processing/awt/PSurfaceAWT.java +1567 -0
  45. data/src/main/java/processing/core/PApplet.java +15709 -0
  46. data/src/main/java/processing/core/PConstants.java +527 -0
  47. data/src/main/java/processing/core/PFont.java +1098 -0
  48. data/src/main/java/processing/core/PGraphics.java +8467 -0
  49. data/src/main/java/processing/core/PImage.java +3438 -0
  50. data/src/main/java/processing/core/PMatrix.java +208 -0
  51. data/src/main/java/processing/core/PMatrix2D.java +534 -0
  52. data/src/main/java/processing/core/PMatrix3D.java +877 -0
  53. data/src/main/java/processing/core/PShape.java +3445 -0
  54. data/src/main/java/processing/core/PShapeOBJ.java +469 -0
  55. data/src/main/java/processing/core/PShapeSVG.java +1787 -0
  56. data/src/main/java/processing/core/PStyle.java +63 -0
  57. data/src/main/java/processing/core/PSurface.java +161 -0
  58. data/src/main/java/processing/core/PSurfaceNone.java +374 -0
  59. data/src/main/java/processing/core/PVector.java +1063 -0
  60. data/src/main/java/processing/data/FloatDict.java +829 -0
  61. data/src/main/java/processing/data/FloatList.java +912 -0
  62. data/src/main/java/processing/data/IntDict.java +796 -0
  63. data/src/main/java/processing/data/IntList.java +913 -0
  64. data/src/main/java/processing/data/JSONArray.java +1260 -0
  65. data/src/main/java/processing/data/JSONObject.java +2282 -0
  66. data/src/main/java/processing/data/JSONTokener.java +435 -0
  67. data/src/main/java/processing/data/Sort.java +46 -0
  68. data/src/main/java/processing/data/StringDict.java +601 -0
  69. data/src/main/java/processing/data/StringList.java +775 -0
  70. data/src/main/java/processing/data/Table.java +4923 -0
  71. data/src/main/java/processing/data/TableRow.java +198 -0
  72. data/src/main/java/processing/data/XML.java +1149 -0
  73. data/src/main/java/processing/event/Event.java +125 -0
  74. data/src/main/java/processing/event/KeyEvent.java +70 -0
  75. data/src/main/java/processing/event/MouseEvent.java +149 -0
  76. data/src/main/java/processing/event/TouchEvent.java +57 -0
  77. data/src/main/java/processing/opengl/FontTexture.java +379 -0
  78. data/src/main/java/processing/opengl/FrameBuffer.java +503 -0
  79. data/src/main/java/processing/opengl/LinePath.java +623 -0
  80. data/src/main/java/processing/opengl/LineStroker.java +685 -0
  81. data/src/main/java/processing/opengl/PGL.java +3366 -0
  82. data/src/main/java/processing/opengl/PGraphics2D.java +615 -0
  83. data/src/main/java/processing/opengl/PGraphics3D.java +281 -0
  84. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13634 -0
  85. data/src/main/java/processing/opengl/PJOGL.java +1966 -0
  86. data/src/main/java/processing/opengl/PShader.java +1478 -0
  87. data/src/main/java/processing/opengl/PShapeOpenGL.java +5234 -0
  88. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1315 -0
  89. data/src/main/java/processing/opengl/Texture.java +1670 -0
  90. data/src/main/java/processing/opengl/VertexBuffer.java +88 -0
  91. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  92. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  93. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  94. data/src/main/java/processing/opengl/cursors/license.txt +27 -0
  95. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  96. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  97. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  98. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  99. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  100. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  101. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +154 -0
  102. data/src/main/java/processing/opengl/shaders/LightVert.glsl +151 -0
  103. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  104. data/src/main/java/processing/opengl/shaders/LineVert.glsl +100 -0
  105. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  106. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  107. data/src/main/java/processing/opengl/shaders/PointVert.glsl +56 -0
  108. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  109. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  110. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +160 -0
  111. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  112. data/src/main/java/processing/opengl/shaders/TexVert.glsl +38 -0
  113. data/src/main/resources/icon/icon-1024.png +0 -0
  114. data/src/main/resources/icon/icon-128.png +0 -0
  115. data/src/main/resources/icon/icon-16.png +0 -0
  116. data/src/main/resources/icon/icon-256.png +0 -0
  117. data/src/main/resources/icon/icon-32.png +0 -0
  118. data/src/main/resources/icon/icon-48.png +0 -0
  119. data/src/main/resources/icon/icon-512.png +0 -0
  120. data/src/main/resources/icon/icon-64.png +0 -0
  121. data/src/main/resources/license.txt +508 -0
  122. data/vendors/Rakefile +5 -20
  123. metadata +115 -33
  124. data/lib/propane.jar +0 -0
@@ -0,0 +1,685 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
5
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
+ *
7
+ * This code is free software; you can redistribute it and/or modify it
8
+ * under the terms of the GNU General Public License version 2 only, as
9
+ * published by the Free Software Foundation. Oracle designates this
10
+ * particular file as subject to the "Classpath" exception as provided
11
+ * by Oracle in the LICENSE file that accompanied this code.
12
+ *
13
+ * This code is distributed in the hope that it will be useful, but WITHOUT
14
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
+ * version 2 for more details (a copy is included in the LICENSE file that
17
+ * accompanied this code).
18
+ *
19
+ * You should have received a copy of the GNU General Public License version
20
+ * 2 along with this work; if not, write to the Free Software Foundation,
21
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22
+ *
23
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24
+ * or visit www.oracle.com if you need additional information or have any
25
+ * questions.
26
+ */
27
+
28
+ package processing.opengl;
29
+
30
+ import processing.core.PMatrix2D;
31
+
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
+ }
168
+
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
+ }
176
+
177
+ for (int i = 0; i < numPenSegments; i++) {
178
+ double r = lineWidth / 2.0;
179
+ double theta = i * 2 * Math.PI / numPenSegments;
180
+
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
+ }
186
+
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
+ }
220
+
221
+ m[0] = dx;
222
+ m[1] = dy;
223
+ }
224
+
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;
230
+ }
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) ? true : false;
262
+ }
263
+ for (int i = 0; i < numPenSegments; i++) {
264
+ px = cx + pen_dx[i];
265
+ py = cy + pen_dy[i];
266
+
267
+ boolean penSide = side(px, py, xa, ya, xb, yb);
268
+ if (penSide != centerSide) {
269
+ penIncluded[i] = true;
270
+ } else {
271
+ penIncluded[i] = false;
272
+ }
273
+ }
274
+
275
+ int start = -1, end = -1;
276
+ for (int i = 0; i < numPenSegments; i++) {
277
+ if (penIncluded[i]
278
+ && !penIncluded[(i + numPenSegments - 1) % numPenSegments]) {
279
+ start = i;
280
+ }
281
+ if (penIncluded[i] && !penIncluded[(i + 1) % numPenSegments]) {
282
+ end = i;
283
+ }
284
+ }
285
+
286
+ if (end < start) {
287
+ end += numPenSegments;
288
+ }
289
+
290
+ if (start != -1 && end != -1) {
291
+ long dxa = cx + pen_dx[start] - xa;
292
+ long dya = cy + pen_dy[start] - ya;
293
+ long dxb = cx + pen_dx[start] - xb;
294
+ long dyb = cy + pen_dy[start] - yb;
295
+
296
+ boolean rev = (dxa * dxa + dya * dya > dxb * dxb + dyb * dyb);
297
+ int i = rev ? end : start;
298
+ int incr = rev ? -1 : 1;
299
+ while (true) {
300
+ int idx = i % numPenSegments;
301
+ px = cx + pen_dx[idx];
302
+ py = cy + pen_dy[idx];
303
+ join[ncoords++] = px;
304
+ join[ncoords++] = py;
305
+ if (i == (rev ? start : end)) {
306
+ break;
307
+ }
308
+ i += incr;
309
+ }
310
+ }
311
+
312
+ return ncoords / 2;
313
+ }
314
+
315
+ //private static final long ROUND_JOIN_THRESHOLD = 1000L;
316
+ private static final long ROUND_JOIN_THRESHOLD = 100000000L;
317
+
318
+ private static final long ROUND_JOIN_INTERNAL_THRESHOLD = 1000000000L;
319
+
320
+ private void drawRoundJoin(int x, int y, int omx, int omy, int mx, int my,
321
+ int side, int color,
322
+ boolean flip, boolean rev, long threshold) {
323
+ if ((omx == 0 && omy == 0) || (mx == 0 && my == 0)) {
324
+ return;
325
+ }
326
+
327
+ long domx = (long) omx - mx;
328
+ long domy = (long) omy - my;
329
+ long len = domx * domx + domy * domy;
330
+ if (len < threshold) {
331
+ return;
332
+ }
333
+
334
+ if (rev) {
335
+ omx = -omx;
336
+ omy = -omy;
337
+ mx = -mx;
338
+ my = -my;
339
+ }
340
+
341
+ int bx0 = x + omx;
342
+ int by0 = y + omy;
343
+ int bx1 = x + mx;
344
+ int by1 = y + my;
345
+
346
+ int npoints = computeRoundJoin(x, y, bx0, by0, bx1, by1, side, flip, join);
347
+ for (int i = 0; i < npoints; i++) {
348
+ emitLineTo(join[2 * i], join[2 * i + 1], color, rev);
349
+ }
350
+ }
351
+
352
+ // Return the intersection point of the lines (ix0, iy0) -> (ix1, iy1)
353
+ // and (ix0p, iy0p) -> (ix1p, iy1p) in m[0] and m[1]
354
+ private void computeMiter(int ix0, int iy0, int ix1, int iy1, int ix0p,
355
+ int iy0p, int ix1p, int iy1p, int[] m) {
356
+ long x0 = ix0;
357
+ long y0 = iy0;
358
+ long x1 = ix1;
359
+ long y1 = iy1;
360
+
361
+ long x0p = ix0p;
362
+ long y0p = iy0p;
363
+ long x1p = ix1p;
364
+ long y1p = iy1p;
365
+
366
+ long x10 = x1 - x0;
367
+ long y10 = y1 - y0;
368
+ long x10p = x1p - x0p;
369
+ long y10p = y1p - y0p;
370
+
371
+ long den = (x10 * y10p - x10p * y10) >> 16;
372
+ if (den == 0) {
373
+ m[0] = ix0;
374
+ m[1] = iy0;
375
+ return;
376
+ }
377
+
378
+ long t = (x1p * (y0 - y0p) - x0 * y10p + x0p * (y1p - y0)) >> 16;
379
+ m[0] = (int) (x0 + (t * x10) / den);
380
+ m[1] = (int) (y0 + (t * y10) / den);
381
+ }
382
+
383
+ private void drawMiter(int px0, int py0, int x0, int y0, int x1, int y1,
384
+ int omx, int omy, int mx, int my, int color,
385
+ boolean rev) {
386
+ if (mx == omx && my == omy) {
387
+ return;
388
+ }
389
+ if (px0 == x0 && py0 == y0) {
390
+ return;
391
+ }
392
+ if (x0 == x1 && y0 == y1) {
393
+ return;
394
+ }
395
+
396
+ if (rev) {
397
+ omx = -omx;
398
+ omy = -omy;
399
+ mx = -mx;
400
+ my = -my;
401
+ }
402
+
403
+ computeMiter(px0 + omx, py0 + omy, x0 + omx, y0 + omy, x0 + mx, y0 + my, x1
404
+ + mx, y1 + my, miter);
405
+
406
+ // Compute miter length in untransformed coordinates
407
+ long dx = (long) miter[0] - x0;
408
+ long dy = (long) miter[1] - y0;
409
+ long a = (dy * m00 - dx * m10) >> 16;
410
+ long b = (dy * m01 - dx * m11) >> 16;
411
+ long lenSq = a * a + b * b;
412
+
413
+ if (lenSq < miterLimitSq) {
414
+ emitLineTo(miter[0], miter[1], color, rev);
415
+ }
416
+ }
417
+
418
+ public void moveTo(int x0, int y0, int c0) {
419
+ // System.out.println("LineStroker.moveTo(" + x0/65536.0 + ", " + y0/65536.0 + ")");
420
+
421
+ if (lineToOrigin) {
422
+ // not closing the path, do the previous lineTo
423
+ lineToImpl(sx0, sy0, scolor0, joinToOrigin);
424
+ lineToOrigin = false;
425
+ }
426
+
427
+ if (prev == LinePath.SEG_LINETO) {
428
+ finish();
429
+ }
430
+
431
+ this.sx0 = this.x0 = x0;
432
+ this.sy0 = this.y0 = y0;
433
+ this.scolor0 = this.color0 = c0;
434
+ this.rindex = 0;
435
+ this.started = false;
436
+ this.joinSegment = false;
437
+ this.prev = LinePath.SEG_MOVETO;
438
+ }
439
+
440
+ boolean joinSegment = false;
441
+
442
+ public void lineJoin() {
443
+ // System.out.println("LineStroker.lineJoin()");
444
+ this.joinSegment = true;
445
+ }
446
+
447
+ public void lineTo(int x1, int y1, int c1) {
448
+ // System.out.println("LineStroker.lineTo(" + x1/65536.0 + ", " + y1/65536.0 + ")");
449
+
450
+ if (lineToOrigin) {
451
+ if (x1 == sx0 && y1 == sy0) {
452
+ // staying in the starting point
453
+ return;
454
+ }
455
+
456
+ // not closing the path, do the previous lineTo
457
+ lineToImpl(sx0, sy0, scolor0, joinToOrigin);
458
+ lineToOrigin = false;
459
+ } else if (x1 == x0 && y1 == y0) {
460
+ return;
461
+ } else if (x1 == sx0 && y1 == sy0) {
462
+ lineToOrigin = true;
463
+ joinToOrigin = joinSegment;
464
+ joinSegment = false;
465
+ return;
466
+ }
467
+
468
+ lineToImpl(x1, y1, c1, joinSegment);
469
+ joinSegment = false;
470
+ }
471
+
472
+ private void lineToImpl(int x1, int y1, int c1, boolean joinSegment) {
473
+ computeOffset(x0, y0, x1, y1, offset);
474
+ int mx = offset[0];
475
+ int my = offset[1];
476
+
477
+ if (!started) {
478
+ emitMoveTo(x0 + mx, y0 + my, color0);
479
+ this.sx1 = x1;
480
+ this.sy1 = y1;
481
+ this.mx0 = mx;
482
+ this.my0 = my;
483
+ started = true;
484
+ } else {
485
+ boolean ccw = isCCW(px0, py0, x0, y0, x1, y1);
486
+ if (joinSegment) {
487
+ if (joinStyle == LinePath.JOIN_MITER) {
488
+ drawMiter(px0, py0, x0, y0, x1, y1, omx, omy, mx, my, color0, ccw);
489
+ } else if (joinStyle == LinePath.JOIN_ROUND) {
490
+ drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
491
+ ROUND_JOIN_THRESHOLD);
492
+ }
493
+ } else {
494
+ // Draw internal joins as round
495
+ drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
496
+ ROUND_JOIN_INTERNAL_THRESHOLD);
497
+ }
498
+
499
+ emitLineTo(x0, y0, color0, !ccw);
500
+ }
501
+
502
+ emitLineTo(x0 + mx, y0 + my, color0, false);
503
+ emitLineTo(x1 + mx, y1 + my, c1, false);
504
+
505
+ emitLineTo(x0 - mx, y0 - my, color0, true);
506
+ emitLineTo(x1 - mx, y1 - my, c1, true);
507
+
508
+ this.omx = mx;
509
+ this.omy = my;
510
+ this.px0 = x0;
511
+ this.py0 = y0;
512
+ this.pcolor0 = color0;
513
+ this.x0 = x1;
514
+ this.y0 = y1;
515
+ this.color0 = c1;
516
+ this.prev = LinePath.SEG_LINETO;
517
+ }
518
+
519
+ public void close() {
520
+ if (lineToOrigin) {
521
+ // ignore the previous lineTo
522
+ lineToOrigin = false;
523
+ }
524
+
525
+ if (!started) {
526
+ finish();
527
+ return;
528
+ }
529
+
530
+ computeOffset(x0, y0, sx0, sy0, offset);
531
+ int mx = offset[0];
532
+ int my = offset[1];
533
+
534
+ // Draw penultimate join
535
+ boolean ccw = isCCW(px0, py0, x0, y0, sx0, sy0);
536
+ if (joinSegment) {
537
+ if (joinStyle == LinePath.JOIN_MITER) {
538
+ drawMiter(px0, py0, x0, y0, sx0, sy0, omx, omy, mx, my, pcolor0, ccw);
539
+ } else if (joinStyle == LinePath.JOIN_ROUND) {
540
+ drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
541
+ ROUND_JOIN_THRESHOLD);
542
+ }
543
+ } else {
544
+ // Draw internal joins as round
545
+ drawRoundJoin(x0, y0, omx, omy, mx, my, 0, color0, false, ccw,
546
+ ROUND_JOIN_INTERNAL_THRESHOLD);
547
+ }
548
+
549
+ emitLineTo(x0 + mx, y0 + my, color0);
550
+ emitLineTo(sx0 + mx, sy0 + my, scolor0);
551
+
552
+ ccw = isCCW(x0, y0, sx0, sy0, sx1, sy1);
553
+
554
+ // Draw final join on the outside
555
+ if (!ccw) {
556
+ if (joinStyle == LinePath.JOIN_MITER) {
557
+ drawMiter(x0, y0, sx0, sy0, sx1, sy1, mx, my, mx0, my0, color0, false);
558
+ } else if (joinStyle == LinePath.JOIN_ROUND) {
559
+ drawRoundJoin(sx0, sy0, mx, my, mx0, my0, 0, scolor0, false, false,
560
+ ROUND_JOIN_THRESHOLD);
561
+ }
562
+ }
563
+
564
+ emitLineTo(sx0 + mx0, sy0 + my0, scolor0);
565
+ emitLineTo(sx0 - mx0, sy0 - my0, scolor0); // same as reverse[0], reverse[1]
566
+
567
+ // Draw final join on the inside
568
+ if (ccw) {
569
+ if (joinStyle == LinePath.JOIN_MITER) {
570
+ drawMiter(x0, y0, sx0, sy0, sx1, sy1, -mx, -my, -mx0, -my0, color0,
571
+ false);
572
+ } else if (joinStyle == LinePath.JOIN_ROUND) {
573
+ drawRoundJoin(sx0, sy0, -mx, -my, -mx0, -my0, 0, scolor0, true, false,
574
+ ROUND_JOIN_THRESHOLD);
575
+ }
576
+ }
577
+
578
+ emitLineTo(sx0 - mx, sy0 - my, scolor0);
579
+ emitLineTo(x0 - mx, y0 - my, color0);
580
+ for (int i = rindex - 3; i >= 0; i -= 3) {
581
+ emitLineTo(reverse[i], reverse[i + 1], reverse[i + 2]);
582
+ }
583
+
584
+ this.x0 = this.sx0;
585
+ this.y0 = this.sy0;
586
+ this.rindex = 0;
587
+ this.started = false;
588
+ this.joinSegment = false;
589
+ this.prev = LinePath.SEG_CLOSE;
590
+ emitClose();
591
+ }
592
+
593
+ public void end() {
594
+ if (lineToOrigin) {
595
+ // not closing the path, do the previous lineTo
596
+ lineToImpl(sx0, sy0, scolor0, joinToOrigin);
597
+ lineToOrigin = false;
598
+ }
599
+
600
+ if (prev == LinePath.SEG_LINETO) {
601
+ finish();
602
+ }
603
+
604
+ output.end();
605
+ this.joinSegment = false;
606
+ this.prev = LinePath.SEG_MOVETO;
607
+ }
608
+
609
+ long lineLength(long ldx, long ldy) {
610
+ long ldet = ((long) m00 * m11 - (long) m01 * m10) >> 16;
611
+ long la = (ldy * m00 - ldx * m10) / ldet;
612
+ long lb = (ldy * m01 - ldx * m11) / ldet;
613
+ long llen = (int) LinePath.hypot(la, lb);
614
+ return llen;
615
+ }
616
+
617
+ private void finish() {
618
+ if (capStyle == LinePath.CAP_ROUND) {
619
+ drawRoundJoin(x0, y0, omx, omy, -omx, -omy, 1, color0, false, false,
620
+ ROUND_JOIN_THRESHOLD);
621
+ } else if (capStyle == LinePath.CAP_SQUARE) {
622
+ long ldx = px0 - x0;
623
+ long ldy = py0 - y0;
624
+ long llen = lineLength(ldx, ldy);
625
+ if (0 < llen) {
626
+ long s = (long) lineWidth2 * 65536 / llen;
627
+
628
+ int capx = x0 - (int) (ldx * s >> 16);
629
+ int capy = y0 - (int) (ldy * s >> 16);
630
+
631
+ emitLineTo(capx + omx, capy + omy, color0);
632
+ emitLineTo(capx - omx, capy - omy, color0);
633
+ }
634
+ }
635
+
636
+ for (int i = rindex - 3; i >= 0; i -= 3) {
637
+ emitLineTo(reverse[i], reverse[i + 1], reverse[i + 2]);
638
+ }
639
+ this.rindex = 0;
640
+
641
+ if (capStyle == LinePath.CAP_ROUND) {
642
+ drawRoundJoin(sx0, sy0, -mx0, -my0, mx0, my0, 1, scolor0, false, false,
643
+ ROUND_JOIN_THRESHOLD);
644
+ } else if (capStyle == LinePath.CAP_SQUARE) {
645
+ long ldx = sx1 - sx0;
646
+ long ldy = sy1 - sy0;
647
+ long llen = lineLength(ldx, ldy);
648
+ if (0 < llen) {
649
+ long s = (long) lineWidth2 * 65536 / llen;
650
+
651
+ int capx = sx0 - (int) (ldx * s >> 16);
652
+ int capy = sy0 - (int) (ldy * s >> 16);
653
+
654
+ emitLineTo(capx - mx0, capy - my0, scolor0);
655
+ emitLineTo(capx + mx0, capy + my0, scolor0);
656
+ }
657
+ }
658
+
659
+ emitClose();
660
+ this.joinSegment = false;
661
+ }
662
+
663
+ private void emitMoveTo(int x0, int y0, int c0) {
664
+ output.moveTo(x0, y0, c0);
665
+ }
666
+
667
+ private void emitLineTo(int x1, int y1, int c1) {
668
+ output.lineTo(x1, y1, c1);
669
+ }
670
+
671
+ private void emitLineTo(int x1, int y1, int c1, boolean rev) {
672
+ if (rev) {
673
+ ensureCapacity(rindex + 3);
674
+ reverse[rindex++] = x1;
675
+ reverse[rindex++] = y1;
676
+ reverse[rindex++] = c1;
677
+ } else {
678
+ emitLineTo(x1, y1, c1);
679
+ }
680
+ }
681
+
682
+ private void emitClose() {
683
+ output.close();
684
+ }
685
+ }