1
2
3 package org.xwt;
4 import org.xwt.util.*;
5 import java.util.*;
6
7
8
9
10
31
32
33 public final class VectorGraphics {
34
35
36
37 private static final int DEFAULT_PATHLEN = 1000;
38 private static final float PI = (float)Math.PI;
39
40
41
42
43 public static VectorPath parseVectorPath(String s) {
44 if (s == null) return null;
45 PathTokenizer t = new PathTokenizer(s);
46 VectorPath ret = new VectorPath();
47 char last_command = 'M';
48 boolean first = true;
49 while(t.hasMoreTokens()) {
50 char command = t.parseCommand();
51 if (first && command != 'M') throw new RuntimeException("the first command of a path must be 'M'");
52 first = false;
53 boolean relative = Character.toLowerCase(command) == command;
54 command = Character.toLowerCase(command);
55 ret.parseSingleCommandAndArguments(t, command, relative);
56 last_command = command;
57 }
58 return ret;
59 }
60
61
62
63
64
65 public static final class Affine {
66
67
68
69
70 public floatfloatfloatfloatfloat Affine(float _a, float _b, float _c, float _d, float _e, float _f) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; }
71 public String toString() { return "[ " + a + ", " + b + ", " + c + ", " + d + ", " + e + ", " + f + " ]"; }
72 public Affine copy() { return new Affine(a, b, c, d, e, f); }
73 public static Affine identity() { return new Affine(1, 0, 0, 1, 0, 0); }
74 public static Affine scale(float sx, float sy) { return new Affine(sx, 0, 0, sy, 0, 0); }
75 public static Affine shear(float degrees) {
76 return new Affine(1, 0, (float)Math.tan(degrees * (float)(Math.PI / 180.0)), 1, 0, 0); }
77 public static Affine translate(float tx, float ty) { return new Affine(1, 0, 0, 1, tx, ty); }
78 public static Affine flip(boolean horiz, boolean vert) { return new Affine(horiz ? -1 : 1, 0, 0, vert ? -1 : 1, 0, 0); }
79 public float multiply_px(float x, float y) { return x * a + y * c + e; }
80 public float multiply_py(float x, float y) { return x * b + y * d + f; }
81 public boolean equalsIgnoringTranslation(Affine x) { return a == x.a && b == x.b && c == x.c && d == x.d; }
82
83 public boolean equals(Object o) {
84 if (!(o instanceof Affine)) return false;
85 Affine x = (Affine)o;
86 return a == x.a && b == x.b && c == x.c && d == x.d && e == x.e && f == x.f;
87 }
88
89 public static Affine rotate(float degrees) {
90 float s = (float)Math.sin(degrees * (float)(Math.PI / 180.0));
91 float c = (float)Math.cos(degrees * (float)(Math.PI / 180.0));
92 return new Affine(c, s, -s, c, 0, 0);
93 }
94
95 /** this = this * a */
96 public Affine multiply(Affine A) {
97 float _a = this.a * A.a + this.b * A.c;
98 float _b = this.a * A.b + this.b * A.d;
99 float _c = this.c * A.a + this.d * A.c;
100 float _d = this.c * A.b + this.d * A.d;
101 float _e = this.e * A.a + this.f * A.c + A.e;
102 float _f = this.e * A.b + this.f * A.d + A.f;
103 a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
104 return this;
105 }
106
107 public void invert() {
108 float det = 1 / (a * d - b * c);
109 float _a = d * det;
110 float _b = -1 * b * det;
111 float _c = -1 * c * det;
112 float _d = a * det;
113 float _e = -1 * e * a - f * c;
114 float _f = -1 * e * b - f * d;
115 a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
116 }
117 }
118
119
120 // PathTokenizer //////////////////////////////////////////////////////////////////////////////
121
122 public static Affine parseTransform(String t) {
123 if (t == null) return null;
124 t = t.trim();
125 Affine ret = VectorGraphics.Affine.identity();
126 while (t.length() > 0) {
127 if (t.startsWith("skewX(")) {
128 // FIXME
129
130 } else if (t.startsWith("shear(")) {
131 // FIXME: nonstandard; remove this
132 ret.multiply(VectorGraphics.Affine.shear(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
133
134 } else if (t.startsWith("skewY(")) {
135 // FIXME
136
137 } else if (t.startsWith("rotate(")) {
138 String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
139 if (sub.indexOf(',') != -1) {
140 float angle = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
141 sub = sub.substring(sub.indexOf(',') + 1);
142 float cx = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
143 sub = sub.substring(sub.indexOf(',') + 1);
144 float cy = Float.parseFloat(sub);
145 ret.multiply(VectorGraphics.Affine.translate(cx, cy));
146 ret.multiply(VectorGraphics.Affine.rotate(angle));
147 ret.multiply(VectorGraphics.Affine.translate(-1 * cx, -1 * cy));
148 } else {
149 ret.multiply(VectorGraphics.Affine.rotate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
150 }
151
152 } else if (t.startsWith("translate(")) {
153 String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
154 if (sub.indexOf(',') > -1) {
155 ret.multiply(VectorGraphics.Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
156 Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
157 } else {
158 ret.multiply(VectorGraphics.Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))), 0));
159 }
160
161 } else if (t.startsWith("flip(")) {
162 String which = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
163 ret.multiply(VectorGraphics.Affine.flip(which.equals("horizontal"), which.equals("vertical")));
164
165 } else if (t.startsWith("scale(")) {
166 String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
167 if (sub.indexOf(',') > -1) {
168 ret.multiply(VectorGraphics.Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
169 Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
170 } else {
171 ret.multiply(VectorGraphics.Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
172 Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(',')))));
173 }
174
175 } else if (t.startsWith("matrix(")) {
176 // FIXME: is this mapped right?
177 float d[] = new float[6];
178 StringTokenizer st = new StringTokenizer(t, ",", false);
179 for(int i=0; i<6; i++)
180 d[i] = Float.parseFloat(st.nextToken());
181 ret.multiply(new VectorGraphics.Affine(d[0], d[1], d[2], d[3], d[4], d[5]));
182 }
183 t = t.substring(t.indexOf(')') + 1).trim();
184 }
185 return ret;
186 }
187
188 public static final float PX_PER_INCH = 72;
189 public static final float INCHES_PER_CM = (float)0.3937;
190 public static final float INCHES_PER_MM = INCHES_PER_CM / 10;
191
192 public static class PathTokenizer {
193 // FIXME: check array bounds exception for improperly terminated string
194 String s;
195 int i = 0;
196 char lastCommand = 'M';
197 public PathTokenizer(String s) { this.s = s; }
198 private void consumeWhitespace() {
199 while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
200 if (i < s.length() && s.charAt(i) == ',') i++;
201 while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
202 }
203 public boolean hasMoreTokens() { consumeWhitespace(); return i < s.length(); }
204 public char parseCommand() {
205 consumeWhitespace();
206 char c = s.charAt(i);
207 if (!Character.isLetter(c)) return lastCommand;
208 i++;
209 return lastCommand = c;
210 }
211 public float parseFloat() {
212 consumeWhitespace();
213 int start = i;
214 float multiplier = 1;
215 for(; i < s.length(); i++) {
216 char c = s.charAt(i);
217 if (Character.isWhitespace(c) || c == ',' || (c == '-' && i != start)) break;
218 if (!((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E' || c == '-')) {
219 if (c == '%') { // FIXME
220 } else if (s.regionMatches(i, "pt", 0, i+2)) { // FIXME
221 } else if (s.regionMatches(i, "em", 0, i+2)) { // FIXME
222 } else if (s.regionMatches(i, "pc", 0, i+2)) { // FIXME
223 } else if (s.regionMatches(i, "ex", 0, i+2)) { // FIXME
224 } else if (s.regionMatches(i, "mm", 0, i+2)) { i += 2; multiplier = INCHES_PER_MM * PX_PER_INCH; break;
225 } else if (s.regionMatches(i, "cm", 0, i+2)) { i += 2; multiplier = INCHES_PER_CM * PX_PER_INCH; break;
226 } else if (s.regionMatches(i, "in", 0, i+2)) { i += 2; multiplier = PX_PER_INCH; break;
227 } else if (s.regionMatches(i, "px", 0, i+2)) { i += 2; break;
228 } else if (Character.isLetter(c)) break;
229 throw new RuntimeException("didn't expect character \"" + c + "\" in a numeric constant");
230 }
231 }
232 if (start == i) throw new RuntimeException("FIXME");
233 return Float.parseFloat(s.substring(start, i)) * multiplier;
234 }
235 }
236
237
238 // Abstract Path //////////////////////////////////////////////////////////////////////////////
239
240 /** an abstract path; may contain splines and arcs */
241 public static class VectorPath {
242
243 // the number of vertices on this path
244 int numvertices = 0;
245
246 // the vertices of the path
247 float[] x = new float[DEFAULT_PATHLEN];
248 float[] y = new float[DEFAULT_PATHLEN];
249
250 // the type of each edge; type[i] is the type of the edge from x[i],y[i] to x[i+1],y[i+1]
251 byte[] type = new byte[DEFAULT_PATHLEN];
252
253 // bezier control points
254 float[] c1x = new float[DEFAULT_PATHLEN]; // or rx (arcto)
255 float[] c1y = new float[DEFAULT_PATHLEN]; // or ry (arcto)
256 float[] c2x = new float[DEFAULT_PATHLEN]; // or x-axis-rotation (arcto)
257 float[] c2y = new float[DEFAULT_PATHLEN]; // or large-arc << 1 | sweep (arcto)
258
259 boolean closed = false;
260
261 static final byte TYPE_MOVETO = 0;
262 static final byte TYPE_LINETO = 1;
263 static final byte TYPE_ARCTO = 2;
264 static final byte TYPE_CUBIC = 3;
265 static final byte TYPE_QUADRADIC = 4;
266
267 /** Creates a concrete vector path transformed through the given matrix. */
268 public RasterPath realize(Affine a) {
269
270 RasterPath ret = new RasterPath();
271 int NUMSTEPS = 5; // FIXME
272 ret.numvertices = 1;
273 ret.x[0] = (int)Math.round(a.multiply_px(x[0], y[0]));
274 ret.y[0] = (int)Math.round(a.multiply_py(x[0], y[0]));
275
276 for(int i=1; i<numvertices; i++) {
277 if (type[i] == TYPE_LINETO) {
278 float rx = x[i];
279 float ry = y[i];
280 ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
281 ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
282 ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
283
284 } else if (type[i] == TYPE_MOVETO) {
285 float rx = x[i];
286 float ry = y[i];
287 ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
288 ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
289 ret.numvertices++;
290
291 } else if (type[i] == TYPE_ARCTO) {
292 float rx = c1x[i];
293 float ry = c1y[i];
294 float phi = c2x[i];
295 float fa = ((int)c2y[i]) >> 1;
296 float fs = ((int)c2y[i]) & 1;
297 float x1 = x[i];
298 float y1 = y[i];
299 float x2 = x[i+1];
300 float y2 = y[i+1];
301
302 // F.6.5: given x1,y1,x2,y2,fa,fs, compute cx,cy,theta1,dtheta
303 float x1_ = (float)Math.cos(phi) * (x1 - x2) / 2 + (float)Math.sin(phi) * (y1 - y2) / 2;
304 float y1_ = -1 * (float)Math.sin(phi) * (x1 - x2) / 2 + (float)Math.cos(phi) * (y1 - y2) / 2;
305 float tmp = (float)Math.sqrt((rx * rx * ry * ry - rx * rx * y1_ * y1_ - ry * ry * x1_ * x1_) /
306 (rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_));
307 float cx_ = (fa == fs ? -1 : 1) * tmp * (rx * y1_ / ry);
308 float cy_ = (fa == fs ? -1 : 1) * -1 * tmp * (ry * x1_ / rx);
309 float cx = (float)Math.cos(phi) * cx_ - (float)Math.sin(phi) * cy_ + (x1 + x2) / 2;
310 float cy = (float)Math.sin(phi) * cx_ + (float)Math.cos(phi) * cy_ + (y1 + y2) / 2;
311
312 // F.6.4 Conversion from center to endpoint parameterization
313 float ux = 1, uy = 0, vx = (x1_ - cx_) / rx, vy = (y1_ - cy_) / ry;
314 float det = ux * vy - uy * vx;
315 float theta1 = (det < 0 ? -1 : 1) *
316 (float)Math.acos((ux * vx + uy * vy) /
317 ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
318 ux = (x1_ - cx_) / rx; uy = (y1_ - cy_) / ry;
319 vx = (-1 * x1_ - cx_) / rx; vy = (-1 * y1_ - cy_) / ry;
320 det = ux * vy - uy * vx;
321 float dtheta = (det < 0 ? -1 : 1) *
322 (float)Math.acos((ux * vx + uy * vy) /
323 ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
324 dtheta = dtheta % (float)(2 * Math.PI);
325
326 if (fs == 0 && dtheta > 0) theta1 -= 2 * PI;
327 if (fs == 1 && dtheta < 0) theta1 += 2 * PI;
328
329 if (fa == 1 && dtheta < 0) dtheta = 2 * PI + dtheta;
330 else if (fa == 1 && dtheta > 0) dtheta = -1 * (2 * PI - dtheta);
331
332 // FIXME: integrate F.6.6
333 // FIXME: isn't quite ending where it should...
334
335 // F.6.3: Parameterization alternatives
336 float theta = theta1;
337 for(int j=0; j<NUMSTEPS; j++) {
338 float rasterx = rx * (float)Math.cos(theta) * (float)Math.cos(phi) -
339 ry * (float)Math.sin(theta) * (float)Math.sin(phi) + cx;
340 float rastery = rx * (float)Math.cos(theta) * (float)Math.sin(phi) +
341 ry * (float)Math.cos(phi) * (float)Math.sin(theta) + cy;
342 ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rasterx, rastery));
343 ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rasterx, rastery));
344 ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
345 theta += dtheta / NUMSTEPS;
346 }
347
348 } else if (type[i] == TYPE_CUBIC) {
349
350 float ax = x[i+1] - 3 * c2x[i] + 3 * c1x[i] - x[i];
351 float bx = 3 * c2x[i] - 6 * c1x[i] + 3 * x[i];
352 float cx = 3 * c1x[i] - 3 * x[i];
353 float dx = x[i];
354 float ay = y[i+1] - 3 * c2y[i] + 3 * c1y[i] - y[i];
355 float by = 3 * c2y[i] - 6 * c1y[i] + 3 * y[i];
356 float cy = 3 * c1y[i] - 3 * y[i];
357 float dy = y[i];
358
359 for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
360 float rx = ax * t * t * t + bx * t * t + cx * t + dx;
361 float ry = ay * t * t * t + by * t * t + cy * t + dy;
362 ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
363 ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
364 ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
365 }
366
367
368 } else if (type[i] == TYPE_QUADRADIC) {
369
370 float bx = x[i+1] - 2 * c1x[i] + x[i];
371 float cx = 2 * c1x[i] - 2 * x[i];
372 float dx = x[i];
373 float by = y[i+1] - 2 * c1y[i] + y[i];
374 float cy = 2 * c1y[i] - 2 * y[i];
375 float dy = y[i];
376
377 for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
378 float rx = bx * t * t + cx * t + dx;
379 float ry = by * t * t + cy * t + dy;
380 ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
381 ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
382 ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
383 }
384
385 }
386
387 }
388
389 if (ret.numedges > 0) ret.sort(0, ret.numedges - 1, false);
390 return ret;
391 }
392
393 protected void parseSingleCommandAndArguments(PathTokenizer t, char command, boolean relative) {
394 if (numvertices == 0 && command != 'm') throw new RuntimeException("first command MUST be an 'm'");
395 if (numvertices > x.length - 2) {
396 float[] new_x = new float[x.length * 2]; System.arraycopy(x, 0, new_x, 0, x.length); x = new_x;
397 float[] new_y = new float[y.length * 2]; System.arraycopy(y, 0, new_y, 0, y.length); y = new_y;
398 }
399 switch(command) {
400 case 'z': {
401 int where;
402 type[numvertices-1] = TYPE_LINETO;
403 for(where = numvertices - 1; where > 0; where--)
404 if (type[where - 1] == TYPE_MOVETO) break;
405 x[numvertices] = x[where];
406 y[numvertices] = y[where];
407 numvertices++;
408 closed = true;
409 break;
410 }
411
412 case 'm': {
413 if (numvertices > 0) type[numvertices-1] = TYPE_MOVETO;
414 x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
415 y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
416 numvertices++;
417 break;
418 }
419
420 case 'l': case 'h': case 'v': {
421 type[numvertices-1] = TYPE_LINETO;
422 float first = t.parseFloat(), second;
423 if (command == 'h') {
424 second = relative ? 0 : y[numvertices - 1];
425 } else if (command == 'v') {
426 second = first; first = relative ? 0 : x[numvertices - 1];
427 } else {
428 second = t.parseFloat();
429 }
430 x[numvertices] = first + (relative ? x[numvertices - 1] : 0);
431 y[numvertices] = second + (relative ? y[numvertices - 1] : 0);
432 numvertices++;
433 break;
434 }
435
436 case 'a': {
437 type[numvertices-1] = TYPE_ARCTO;
438 c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
439 c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
440 c2x[numvertices-1] = (t.parseFloat() / 360) * 2 * PI;
441 c2y[numvertices-1] = (((int)t.parseFloat()) << 1) | (int)t.parseFloat();
442 x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
443 y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
444 numvertices++;
445 break;
446 }
447
448 case 's': case 'c': {
449 type[numvertices-1] = TYPE_CUBIC;
450 if (command == 'c') {
451 c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
452 c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
453 } else if (numvertices > 1 && type[numvertices-2] == TYPE_CUBIC) {
454 c1x[numvertices-1] = 2 * x[numvertices - 1] - c2x[numvertices-2];
455 c1y[numvertices-1] = 2 * y[numvertices - 1] - c2y[numvertices-2];
456 } else {
457 c1x[numvertices-1] = x[numvertices-1];
458 c1y[numvertices-1] = y[numvertices-1];
459 }
460 c2x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
461 c2y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
462 x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
463 y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
464 numvertices++;
465 break;
466 }
467
468 case 't': case 'q': {
469 type[numvertices-1] = TYPE_QUADRADIC;
470 if (command == 'q') {
471 c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
472 c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
473 } else if (numvertices > 1 && type[numvertices-2] == TYPE_QUADRADIC) {
474 c1x[numvertices-1] = 2 * x[numvertices - 1] - c1x[numvertices-2];
475 c1y[numvertices-1] = 2 * y[numvertices - 1] - c1y[numvertices-2];
476 } else {
477 c1x[numvertices-1] = x[numvertices-1];
478 c1y[numvertices-1] = y[numvertices-1];
479 }
480 x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
481 y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
482 numvertices++;
483 break;
484 }
485
486 default:
487 // FIXME
488 }
489
490 /*
491 // invariant: after this loop, no two lines intersect other than at a vertex
492 // FIXME: cleanup
493 int index = numvertices - 2;
494 for(int i=0; i<Math.min(numvertices - 3, index); i++) {
495 for(int j = index; j < numvertices - 1; j++) {
496
497 // I'm not sure how to deal with vertical lines...
498 if (x[i+1] == x[i] || x[j+1] == x[j]) continue;
499
500 float islope = (y[i+1] - y[i]) / (x[i+1] - x[i]);
501 float jslope = (y[j+1] - y[j]) / (x[j+1] - x[j]);
502 if (islope == jslope) continue; // parallel lines can't intersect
503
504 float _x = (islope * x[i] - jslope * x[j] + y[j] - y[i]) / (islope - jslope);
505 float _y = islope * (_x - x[i]) + y[i];
506
507 if (_x > Math.min(x[i+1], x[i]) && _x < Math.max(x[i+1], x[i]) &&
508 _x > Math.min(x[j+1], x[j]) && _x < Math.max(x[j+1], x[j])) {
509 // FIXME: something's not right in here. See if we can do without fracturing line 'i'.
510 for(int k = ++numvertices; k>i; k--) { x[k] = x[k - 1]; y[k] = y[k - 1]; }
511 x[i+1] = _x;
512 y[i+1] = _y;
513 x[numvertices] = x[numvertices - 1]; x[numvertices - 1] = _x;
514 y[numvertices] = y[numvertices - 1]; y[numvertices - 1] = _y;
515 edges[numedges++] = numvertices - 1; numvertices++;
516 index++;
517 break; // actually 'continue' the outermost loop
518 }
519 }
520 }
521 */
522
523 }
524 }
525
526
527
528
529 // Rasterized Vector Path //////////////////////////////////////////////////////////////////////////////
530
531 /** a vector path */
532 public static class RasterPath {
533
534 // the vertices of this path
535 int[] x = new int[DEFAULT_PATHLEN];
536 int[] y = new int[DEFAULT_PATHLEN];
537 int numvertices = 0;
538
539 /**
540 * A list of the vertices on this path which *start* an *edge* (rather than a moveto), sorted by increasing y.
541 * example: x[edges[1]],y[edges[1]] - x[edges[i]+1],y[edges[i]+1] is the second-topmost edge
542 * note that if x[i],y[i] - x[i+1],y[i+1] is a MOVETO, then no element in edges will be equal to i
543 */
544 int[] edges = new int[DEFAULT_PATHLEN];
545 int numedges = 0;
546
547 /** translate a rasterized path */
548 public void translate(int dx, int dy) { for(int i=0; i<numvertices; i++) { x[i] += dx; y[i] += dy; } }
549
550 /** simple quicksort, from http://sourceforge.net/snippet/detail.php?type=snippet&id=100240 */
551 int sort(int left, int right, boolean partition) {
552 if (partition) {
553 int i, j, middle;
554 middle = (left + right) / 2;
555 int s = edges[right]; edges[right] = edges[middle]; edges[middle] = s;
556 for (i = left - 1, j = right; ; ) {
557 while (y[edges[++i]] < y[edges[right]]);
558 while (j > left && y[edges[--j]] > y[edges[right]]);
559 if (i >= j) break;
560 s = edges[i]; edges[i] = edges[j]; edges[j] = s;
561 }
562 s = edges[right]; edges[right] = edges[i]; edges[i] = s;
563 return i;
564 } else {
565 if (left >= right) return 0;
566 int p = sort(left, right, true);
567 sort(left, p - 1, false);
568 sort(p + 1, right, false);
569 return 0;
570 }
571 }
572
573 /** finds the x value at which the line intercepts the line y=_y */
574 private int intercept(int i, float _y, boolean includeTop, boolean includeBottom) {
575 if (includeTop ? (_y < Math.min(y[i], y[i+1])) : (_y <= Math.min(y[i], y[i+1])))
576 return Integer.MIN_VALUE;
577 if (includeBottom ? (_y > Math.max(y[i], y[i+1])) : (_y >= Math.max(y[i], y[i+1])))
578 return Integer.MIN_VALUE;
579 return (int)Math.round((((float)(x[i + 1] - x[i])) /
580 ((float)(y[i + 1] - y[i])) ) * ((float)(_y - y[i])) + x[i]);
581 }
582
583 /** fill the interior of the path */
584 public void fill(PixelBuffer buf, Paint paint) {
585 if (numedges == 0) return;
586 int y0 = y[edges[0]], y1 = y0;
587 boolean useEvenOdd = false;
588
589 // we iterate over all endpoints in increasing y-coordinate order
590 for(int index = 1; index<numedges; index++) {
591 int count = 0;
592
593 // we now examine the horizontal band between y=y0 and y=y1
594 y0 = y1;
595 y1 = y[edges[index]];
596 if (y0 == y1) continue;
597
598 // within this band, we iterate over all edges
599 int x0 = Integer.MIN_VALUE;
600 int leftSegment = -1;
601 while(true) {
602 int x1 = Integer.MAX_VALUE;
603 int rightSegment = Integer.MAX_VALUE;
604 for(int i=0; i<numedges; i++) {
605 if (y[edges[i]] == y[edges[i]+1]) continue; // ignore horizontal lines; they are irrelevant.
606 // we order the segments by the x-coordinate of their midpoint;
607 // since segments cannot intersect, this is a well-ordering
608 int i0 = intercept(edges[i], y0, true, false);
609 int i1 = intercept(edges[i], y1, false, true);
610 if (i0 == Integer.MIN_VALUE || i1 == Integer.MIN_VALUE) continue;
611 int midpoint = i0 + i1;
612 if (midpoint < x0) continue;
613 if (midpoint == x0 && i <= leftSegment) continue;
614 if (midpoint > x1) continue;
615 if (midpoint == x1 && i >= rightSegment) continue;
616 rightSegment = i;
617 x1 = midpoint;
618 }
619 if (leftSegment == rightSegment || rightSegment == Integer.MAX_VALUE) break;
620 if (leftSegment != -1)
621 if ((useEvenOdd && count % 2 != 0) || (!useEvenOdd && count != 0))
622 paint.fillTrapezoid(intercept(edges[leftSegment], y0, true, true),
623 intercept(edges[rightSegment], y0, true, true), y0,
624 intercept(edges[leftSegment], y1, true, true),
625 intercept(edges[rightSegment], y1, true, true), y1,
626 buf);
627 if (useEvenOdd) count++;
628 else count += (y[edges[rightSegment]] < y[edges[rightSegment]+1]) ? -1 : 1;
629 leftSegment = rightSegment; x0 = x1;
630 }
631 }
632 }
633
634 /** stroke the outline of the path */
635 public void stroke(PixelBuffer buf, int width, int color) { stroke(buf, width, color, null, 0, 0); }
636 public void stroke(PixelBuffer buf, int width, int color, String dashArray, int dashOffset, float segLength) {
637
638 if (dashArray == null) {
639 for(int i=0; i<numedges; i++)
640 buf.drawLine((int)x[edges[i]],
641 (int)y[edges[i]], (int)x[edges[i]+1], (int)y[edges[i]+1], width, color, false);
642 return;
643 }
644
645 float ratio = 1;
646 if (segLength > 0) {
647 float actualLength = 0;
648 for(int i=0; i<numvertices; i++) {
649 // skip over MOVETOs -- they do not contribute to path length
650 if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
651 if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
652 int x1 = x[i];
653 int x2 = x[i + 1];
654 int y1 = y[i];
655 int y2 = y[i + 1];
656 actualLength += java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
657 }
658 ratio = actualLength / segLength;
659 }
660 PathTokenizer pt = new PathTokenizer(dashArray);
661 Vector v = new Vector();
662 while (pt.hasMoreTokens()) v.addElement(new Float(pt.parseFloat()));
663 float[] dashes = new float[v.size() % 2 == 0 ? v.size() : 2 * v.size()];
664 for(int i=0; i<dashes.length; i++) dashes[i] = ((Float)v.elementAt(i % v.size())).floatValue();
665 float length = 0;
666 int dashpos = dashOffset;
667 boolean on = dashpos % 2 == 0;
668 for(int i=0; i<numvertices; i++) {
669 // skip over MOVETOs -- they do not contribute to path length
670 if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
671 if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
672 int x1 = (int)x[i];
673 int x2 = (int)x[i + 1];
674 int y1 = (int)y[i];
675 int y2 = (int)y[i + 1];
676 float segmentLength = (float)java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
677 int _x1 = x1, _y1 = y1;
678 float pos = 0;
679 do {
680 pos = Math.min(segmentLength, pos + dashes[dashpos] * ratio);
681 if (pos != segmentLength) dashpos = (dashpos + 1) % dashes.length;
682 int _x2 = (int)((x2 * pos + x1 * (segmentLength - pos)) / segmentLength);
683 int _y2 = (int)((y2 * pos + y1 * (segmentLength - pos)) / segmentLength);
684 if (on) buf.drawLine(_x1, _y1, _x2, _y2, width, color, false);
685 on = !on;
686 _x1 = _x2; _y1 = _y2;
687 } while(pos < segmentLength);
688 }
689 }
690
691 // FEATURE: make this faster and cache it; also deal with negative coordinates
692 public int boundingBoxWidth() {
693 int ret = 0;
694 for(int i=0; i<numvertices; i++) ret = Math.max(ret, x[i]);
695 return ret;
696 }
697
698 // FEATURE: make this faster and cache it; also deal with negative coordinates
699 public int boundingBoxHeight() {
700 int ret = 0;
701 for(int i=0; i<numvertices; i++) ret = Math.max(ret, y[i]);
702 return ret;
703 }
704 }
705
706
707 // Paint //////////////////////////////////////////////////////////////////////////////
708
709 public static interface Paint {
710 public abstract void
711 fillTrapezoid(int tx1, int tx2, int ty1, int tx3, int tx4, int ty2, PixelBuffer buf);
712 }
713
714 public static class SingleColorPaint implements Paint {
715 int color;
716 public SingleColorPaint(int color) { this.color = color; }
717 public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, PixelBuffer buf) {
718 buf.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
719 }
720 }
721
722 }
723
724
725
726
727
728
729
730
731
732 /*
733 public static abstract class GradientPaint extends Paint {
734 public GradientPaint(boolean reflect, boolean repeat, Affine gradientTransform,
735 int[] stop_colors, float[] stop_offsets) {
736 this.reflect = reflect; this.repeat = repeat;
737 this.gradientTransform = gradientTransform;
738 this.stop_colors = stop_colors;
739 this.stop_offsets = stop_offsets;
740 }
741 Affine gradientTransform = Affine.identity();
742 boolean useBoundingBox = false; // FIXME not supported
743 boolean patternUseBoundingBox = false; // FIXME not supported
744
745 // it's invalid for both of these to be true
746 boolean reflect = false; // FIXME not supported
747 boolean repeat = false; // FIXME not supported
748 int[] stop_colors;
749 float[] stop_offsets;
750
751 public void fillTrapezoid(float tx1, float tx2, float ty1, float tx3, float tx4, float ty2, PixelBuffer buf) {
752 Affine a = buf.a;
753 Affine inverse = a.copy().invert();
754 float slope1 = (tx3 - tx1) / (ty2 - ty1);
755 float slope2 = (tx4 - tx2) / (ty2 - ty1);
756 for(float y=ty1; y<ty2; y++) {
757 float _x1 = (y - ty1) * slope1 + tx1;
758 float _x2 = (y - ty1) * slope2 + tx2;
759 if (_x1 > _x2) { float _x0 = _x1; _x1 = _x2; _x2 = _x0; }
760
761 for(float x=_x1; x<_x2; x++) {
762
763 float distance = isLinear ?
764 // length of projection of <x,y> onto the gradient vector == {<x,y> \dot {grad \over |grad|}}
765 (x * (x2 - x1) + y * (y2 - y1)) / (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) :
766
767 // radial form is simple! FIXME, not quite right
768 (float)Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
769
770 // FIXME: offsets are 0..1, not 0..length(gradient)
771 int i = 0; for(; i<stop_offsets.length; i++) if (distance < stop_offsets[i]) break;
772
773 // FIXME: handle points beyond the bounds
774 if (i < 0 || i >= stop_offsets.length) continue;
775
776 // gradate from offsets[i - 1] to offsets[i]
777 float percentage = ((distance - stop_offsets[i - 1]) / (stop_offsets[i] - stop_offsets[i - 1]));
778
779 int a = (int)((((stop_colors[i] >> 24) & 0xff) - ((stop_colors[i - 1] >> 24) & 0xff)) * percentage) +
780 ((stop_colors[i - 1] >> 24) & 0xff);
781 int r = (int)((((stop_colors[i] >> 16) & 0xff) - ((stop_colors[i - 1] >> 16) & 0xff)) * percentage) +
782 ((stop_colors[i - 1] >> 16) & 0xff);
783 int g = (int)((((stop_colors[i] >> 8) & 0xff) - ((stop_colors[i - 1] >> 8) & 0xff)) * percentage) +
784 ((stop_colors[i - 1] >> 8) & 0xff);
785 int b = (int)((((stop_colors[i] >> 0) & 0xff) - ((stop_colors[i - 1] >> 0) & 0xff)) * percentage) +
786 ((stop_colors[i - 1] >> 0) & 0xff);
787 int argb = (a << 24) | (r << 16) | (g << 8) | b;
788 buf.drawPoint((int)x, (int)Math.floor(y), argb);
789 }
790 }
791 }
792 }
793
794 public static class LinearGradientPaint extends GradientPaint {
795 public LinearGradientPaint(float x1, float y1, float x2, float y2, boolean reflect, boolean repeat,
796 Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
797 super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
798 this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2;
799 }
800 float x1 = 0, y1 = 0, x2 = 300, y2 = 300;
801 }
802
803 public static class RadialGradientPaint extends GradientPaint {
804 public RadialGradientPaint(float cx, float cy, float fx, float fy, float r, boolean reflect, boolean repeat,
805 Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
806 super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
807 this.cx = cx; this.cy = cy; this.fx = fx; this.fy = fy; this.r = r;
808 }
809
810 float cx, cy, r, fx, fy;
811
812 }
813 */
814
815 ????????????????float??????????????????????a?????????????????????????b????????????????????????????c???????????????????????????????d??????????????????????????????????e?????????????????????????????????????f??Affine?????????float???????????????????float?????????????????????????????float???????????????????????????????????????float?????????????????????????????????????????????????float???????????????????????????????????????????????????????????float???????????????????????????????????????????????????????????????????????a???????????????????????????????????????????????????????????????????????????_a???????????????????????????????????????????????????????????????????????????????b???????????????????????????????????????????????????????????????????????????????????_b???????????????????????????????????????????????????????????????????????????????????????c???????????????????????????????????????????????????????????????????????????????????????????_c???????????????????????????????????????????????????????????????????????????????????????????????d???????????????????????????????????????????????????????????????????????????????????????????????????_d???????????????????????????????????????????????????????????????????????????????????????????????????????e???????????????????????????????????????????????????????????????????????????????????????????????????????????_e???????????????????????????????????????????????????????????????????????????????????????????????????????????????f???????????????????????????????????????????????????????????????????????????????????????????????????????????????????_f????????????????toString???????????????????????????????????????????a??????????????????????????????????????????????????????b?????????????????????????????????????????????????????????????????c????????????????????????????????????????????????????????????????????????????d???????????????????????????????????????????????????????????????????????????????????????e??????????????????????????????????????????????????????????????????????????????????????????????????f?????????Affine????????????????copy????????????????????????????????????Affine???????????????????????????????????????????a??????????????????????????????????????????????b?????????????????????????????????????????????????c????????????????????????????????????????????????????d???????????????????????????????????????????????????????e??????????????????????????????????????????????????????????f???????????????????????Affine??????????????????????????????identity??????????????????????????????????????????????????????Affine????????????????Affine???????????????????????scale?????????????????????????????float???????????????????????????????????????float??????????????????????????????????????????????????????????????Affine?????????????????????????????????????????????????????????????????????sx???????????????????????????????????????????????????????????????????????????????sy????????????????Affine???????????????????????shear?????????????????????????????float????????????????????????Affine?????????????????????????????????????????????????????degrees????????????????Affine???????????????????????translate?????????????????????????????????float???????????????????????????????????????????float??????????????????????????????????????????????????????????????????Affine?????????????????????????????????????????????????????????????????????????????????????tx?????????????????????????????????????????????????????????????????????????????????????????ty????????????????Affine???????????????????????flip????????????????????????????boolean???????????????????????????????????????????boolean??????????????????????????????????????????????????????????????????????Affine?????????????????????????????????????????????????????????????????????????????horiz???????????????????????????????????????????????????????????????????????????????????????????????????vert????????????????float??????????????????????multiply_px??????????????????????????????????float???????????????????????????????????????????float?????????????????????????????????????????????????????????????x?????????????????????????????????????????????????????????????????a?????????????????????????????????????????????????????????????????????y?????????????????????????????????????????????????????????????????????????c?????????????????????????????????????????????????????????????????????????????e?????????float???????????????multiply_py???????????????????????????float????????????????????????????????????float??????????????????????????????????????????????????????x??????????????????????????????????????????????????????????b??????????????????????????????????????????????????????????????y??????????????????????????????????????????????????????????????????d??????????????????????????????????????????????????????????????????????f????????????????boolean????????????????????????equalsIgnoringTranslation??????????????????????????????????????????????????Affine?????????????????????????????????????????????????????????????????????a??????????????????????????????????????????????????????????????????????????x????????????????????????????????????????????????????????????????????????????a?????????????????????????????????????????????????????????????????????????????????b??????????????????????????????????????????????????????????????????????????????????????x????????????????????????????????????????????????????????????????????????????????????????b?????????????????????????????????????????????????????????????????????????????????????????????c??????????????????????????????????????????????????????????????????????????????????????????????????x????????????????????????????????????????????????????????????????????????????????????????????????????c?????????????????????????????????????????????????????????????????????????????????????????????????????????d??????????????????????????????????????????????????????????????????????????????????????????????????????????????x????????????????????????????????????????????????????????????????????????????????????????????????????????????????d????????????????boolean????????????????????????equals???????????????????????????????Object???????????????????o?????????????Affine?????????????????????????Affine????????????????????????????????o????????????????????a?????????????????????????x???????????????????????????a????????????????????????????????b?????????????????????????????????????x???????????????????????????????????????b????????????????????????????????????????????c?????????????????????????????????????????????????x???????????????????????????????????????????????????c????????????????????????????????????????????????????????d?????????????????????????????????????????????????????????????x???????????????????????????????????????????????????????????????d????????????????????????????????????????????????????????????????????e?????????????????????????????????????????????????????????????????????????x???????????????????????????????????????????????????????????????????????????e????????????????????????????????????????????????????????????????????????????????f?????????????????????????????????????????????????????????????????????????????????????x???????????????????????????????????????????????????????????????????????????????????????f????????????????Affine???????????????????????rotate??????????????????????????????float??????float????????????????????????????????degrees??????float????????????????????????????????degrees?????????????????Affine????????????????????????c???????????????????????????s???????????????????????????????s??????????????????????????????????c??????????????????Affine???????????????????????multiply????????????????????????????????Affine??????float??????????????????????????A????????????????????????????a?????????????????????????????????????????A???????????????????????????????????????????c??????float??????????????????????????A????????????????????????????b?????????????????????????????????????????A???????????????????????????????????????????d??????float??????????????????????????A????????????????????????????a?????????????????????????????????????????A???????????????????????????????????????????c??????float??????????????????????????A????????????????????????????b?????????????????????????????????????????A???????????????????????????????????????????d??????float??????????????????????????A????????????????????????????a?????????????????????????????????????????A???????????????????????????????????????????c???????????????????????????????????????????????A?????????????????????????????????????????????????e??????float??????????????????????????A????????????????????????????b?????????????????????????????????????????A???????????????????????????????????????????d???????????????????????????????????????????????A?????????????????????????????????????????????????f??????a??????????_a??????????????b??????????????????_b??????????????????????c??????????????????????????_c??????????????????????????????d??????????????????????????????????_d??????????????????????????????????????e??????????????????????????????????????????_e??????????????????????????????????????????????f??????????????????????????????????????????????????_f????????????????void?????????????????????invert??????float???????????????????????a???????????????????????????d???????????????????????????????b???????????????????????????????????c??????float?????????????????d?????????????????????det??????float??????????????????????b??????????????????????????det??????float??????????????????????c??????????????????????????det??????float?????????????????a?????????????????????det??????float??????????????????????e??????????????????????????a??????????????????????????????f??????????????????????????????????c??????float??????????????????????e??????????????????????????b??????????????????????????????f??????????????????????????????????d??????a??????????_a??????????????b??????????????????_b??????????????????????c??????????????????????????_c??????????????????????????????d??????????????????????????????????_d??????????????????????????????????????e??????????????????????????????????????????_e??????????????????????????????????????????????f??????????????????????????????????????????????????_f????????????????????????Affine??????????????????????????parseTransform?????????????t?????????t?????????????t?????????Affine??????????????????????VectorGraphics?????????????????????????????????????Affine????????????????????????????????????????????identity????????????????t?????????????????t?????????????????????????????????????????t??????????????????????????????????ret?????????????????????multiply??????????????????????????????VectorGraphics?????????????????????????????????????????????Affine????????????????????????????????????????????????????shear???????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????t????????????????????????t?????????????????????????????????????????t??????????????????????????????t??????????????????????????????????????????t??????????????????????????????????????????????????????????????t?????????????????????sub?????????????????????float????????????????????????????????????????????????????sub?????????????????????????????????????????????????????????????????????sub?????????????????????sub???????????????????????????sub?????????????????????????????????????????sub?????????????????????float?????????????????????????????????????????????????sub??????????????????????????????????????????????????????????????????sub?????????????????????sub???????????????????????????sub?????????????????????????????????????????sub?????????????????????float?????????????????????????????????????????????????sub?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????translate??????????????????????????????????????????????????????????????????cx??????????????????????????????????????????????????????????????????????cy?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????rotate???????????????????????????????????????????????????????????????angle?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????translate???????????????????????????????????????????????????????????????????????cx????????????????????????????????????????????????????????????????????????????????cy?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????rotate????????????????????????????????????????????????????????????????????????????????t????????????????????????????????????????????????????????????????????????????????????????????t????????????????????????????????????????????????????????????????????????????????????????????????????????????????t????????????????????????t??????????????????????????????t??????????????????????????????????????????t??????????????????????????????????????????????????????????????t?????????????????????sub?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????translate???????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????????t?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????translate???????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????????t????????????????????????t????????????????????????????????t????????????????????????????????????????????t????????????????????????????????????????????????????????????????t?????????????????ret?????????????????????multiply??????????????????????????????VectorGraphics?????????????????????????????????????????????Affine????????????????????????????????????????????????????flip?????????????????????????????????????????????????????????which?????????????????????????????????????????????????????????????????????????????????????which????????????????????????t??????????????????????????????t??????????????????????????????????????????t??????????????????????????????????????????????????????????????t?????????????????????sub?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????scale???????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????t?????????????????????ret?????????????????????????multiply??????????????????????????????????VectorGraphics?????????????????????????????????????????????????Affine????????????????????????????????????????????????????????scale???????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????t???????????????????????????????????????????????????????????????????????????????????????????????????????????????t????????????????????????t??????????????????????????????????float?????????????????????????????????float??????????????????????????????????????????????????????????t?????????????????????int??????????????????????????????i???????????????????????????????????i?????????????????????d???????????????????????i?????????????????????????????????????????????st?????????????????ret?????????????????????multiply????????????????????????????????????????????????????????d??????????????????????????????????????????????????????????????d????????????????????????????????????????????????????????????????????d??????????????????????????????????????????????????????????????????????????d????????????????????????????????????????????????????????????????????????????????d??????????????????????????????????????????????????????????????????????????????????????d?????????????t?????????????????t?????????????????????????????t????????????????ret?????????????????????????float???????????????????????????????PX_PER_INCH?????????????????????????float???????????????????????????????INCHES_PER_CM?????????????????????????float???????????????????????????????INCHES_PER_MM???????????????????????????????????????????????INCHES_PER_CM?????????????????????????PathTokenizer?????????????????????????s?????????int?????????????i?????????char??????????????lastCommand????????????????PathTokenizer???????????????????????????????????????????????????s?????????????????void??????????????????????consumeWhitespace???????????????????i???????????????????????s?????????????????????????????????????????????????????????????s??????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????i?????????????????i?????????????????????s???????????????????????????????????s????????????????????????????????????????????i???????????????????????????????????????????????????????i???????????????????i???????????????????????s?????????????????????????????????????????????????????????????s??????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????i????????????????boolean????????????????????????hasMoreTokens??????????????????????????????????????????????????????????????????????i????????????????char?????????????????????parseCommand?????????????char??????????????????????s?????????????????????????????????????c??????????????????????????????????c????????????????float??????????????????????parseFloat?????????????int?????????????????????????i?????????????float???????????????????i???????????????????????????????????i?????????????????char???????????????????????????????????i????????????????????????????????????????????c??????????????????????????????????????????????????c???????????????????????????????????????????????????????????????c???????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????start????????????????????????c????????????????????????????????????c?????????????????????????????????????????????????c?????????????????????????????????????????????????????????????c?????????????????????????????????????????????????????????????????????????c?????????????????????????????????????????????????????????????????????????????????????c?????????????????????????c????????????????????????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????multiplier?????????????????????????????????????????????????????????????????????????????????????????INCHES_PER_MM?????????????????????????????????????????????????????????????????????????????????????????????????????????PX_PER_INCH????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????multiplier?????????????????????????????????????????????????????????????????????????????????????????INCHES_PER_CM?????????????????????????????????????????????????????????????????????????????????????????????????????????PX_PER_INCH????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????multiplier?????????????????????????????????????????????????????????????????????????????????????????PX_PER_INCH????????????????????????????????????????????????i????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????i???????????????????????????????????????????????????c???????????????????????????????????????????????????????????????????????????????c?????????????????start??????????????????????????i?????????????????????????????????????????????????start????????????????????????????????????????????????????????i??????????????????????????????????????????????????????????????multiplier???????????????????????????????????VectorPath???????????int??????numvertices???????????float??????????x??????????????????float????????????????????????DEFAULT_PATHLEN??float??????????y??????????????????float????????????????????????DEFAULT_PATHLEN???????????byte?????????type????????????????????byte?????????????????????????DEFAULT_PATHLEN????float??????????c1x????????????????????float??????????????????????????DEFAULT_PATHLEN???????????????????????????????????????????????float??????????c1y????????????????????float??????????????????????????DEFAULT_PATHLEN???????????????????????????????????????????????float??????????c2x????????????????????float??????????????????????????DEFAULT_PATHLEN???????????????????????????????????????????????float??????????c2y????????????????????float??????????????????????????DEFAULT_PATHLEN???????????????????????????????????????????????boolean??????????closed???????????????byte????????????????????TYPE_MOVETO???????????????byte????????????????????TYPE_LINETO???????????????byte????????????????????TYPE_ARCTO???????????????byte????????????????????TYPE_CUBIC???????????????byte????????????????????TYPE_QUADRADIC??????????????????RasterPath????????????????????realize????????????????????????????Affine?????????????RasterPath?????????????int??????????????????????????????????????ret??????????numvertices?????????????ret?????????????????x????????????????????????????????????????a??????????????????????????????????????????multiply_px??????????????????????????????????????????????????????x????????????????????????????????????????????????????????????y?????????????ret?????????????????y????????????????????????????????????????a??????????????????????????????????????????multiply_py??????????????????????????????????????????????????????x????????????????????????????????????????????????????????????y??????????int???????????????????i?????????????????????numvertices??????????????????????????????????i???????type????????????i??????????????????TYPE_LINETO???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i?????????????????????ret?????????????????????????x???????????????????????????ret???????????????????????????????numvertices??????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????multiply_px????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????ry?????????????????????ret?????????????????????????y???????????????????????????ret???????????????????????????????numvertices??????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????multiply_py????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????ry?????????????????????ret?????????????????????????edges???????????????????????????????ret???????????????????????????????????numedges?????????????????????????????????????????????????ret?????????????????????????????????????????????????????numvertices??????????????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????????????numvertices????????????????????????????type?????????????????????????????????i???????????????????????????????????????TYPE_MOVETO???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i?????????????????????ret?????????????????????????x???????????????????????????ret???????????????????????????????numvertices??????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????multiply_px????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????ry?????????????????????ret?????????????????????????y???????????????????????????ret???????????????????????????????numvertices??????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????multiply_py????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????ry?????????????????????ret?????????????????????????numvertices??????????????type???????????????????i?????????????????????????TYPE_ARCTO???????float??????????????????c1x??????????????????????i???????float??????????????????c1y??????????????????????i???????float???????????????????c2x???????????????????????i???????float????????????????????????c2y????????????????????????????i???????float????????????????????????c2y????????????????????????????i???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i??????????????float???????????????????????????????????phi???????????????????????????????????????????x1????????????????????????????????????????????????x2??????????????????????????????????????????????????????????????????????????phi??????????????????????????????????????????????????????????????????????????????????y1???????????????????????????????????????????????????????????????????????????????????????y2???????float????????????????????????????????????????phi????????????????????????????????????????????????x1?????????????????????????????????????????????????????x2???????????????????????????????????????????????????????????????????????????????phi???????????????????????????????????????????????????????????????????????????????????????y1????????????????????????????????????????????????????????????????????????????????????????????y2???????float?????????????????????????????????????rx??????????????????????????????????????????rx???????????????????????????????????????????????ry????????????????????????????????????????????????????ry?????????????????????????????????????????????????????????rx??????????????????????????????????????????????????????????????rx???????????????????????????????????????????????????????????????????y1_?????????????????????????????????????????????????????????????????????????y1_???????????????????????????????????????????????????????????????????????????????ry????????????????????????????????????????????????????????????????????????????????????ry?????????????????????????????????????????????????????????????????????????????????????????x1_???????????????????????????????????????????????????????????????????????????????????????????????x1_???????????????????????????????????????????????????rx????????????????????????????????????????????????????????rx?????????????????????????????????????????????????????????????y1_???????????????????????????????????????????????????????????????????y1_?????????????????????????????????????????????????????????????????????????ry??????????????????????????????????????????????????????????????????????????????ry???????????????????????????????????????????????????????????????????????????????????x1_?????????????????????????????????????????????????????????????????????????????????????????x1_???????float????????????????????fa??????????????????????????fs?????????????????????????????????????????tmp????????????????????????????????????????????????rx?????????????????????????????????????????????????????y1_???????????????????????????????????????????????????????????ry???????float????????????????????fa??????????????????????????fs??????????????????????????????????????????????tmp?????????????????????????????????????????????????????ry??????????????????????????????????????????????????????????x1_????????????????????????????????????????????????????????????????rx???????float??????????????????????????????????phi?????????????????????????????????????????cx_???????????????????????????????????????????????????????????????phi??????????????????????????????????????????????????????????????????????cy_?????????????????????????????????????????????????????????????????????????????x1??????????????????????????????????????????????????????????????????????????????????x2???????float??????????????????????????????????phi?????????????????????????????????????????cx_???????????????????????????????????????????????????????????????phi??????????????????????????????????????????????????????????????????????cy_?????????????????????????????????????????????????????????????????????????????y1??????????????????????????????????????????????????????????????????????????????????y2??????????????????????????????????????????float?????????????????????float?????????????????????float?????????????????????float?????????????????????????????????????????????????x1_???????????????????????????????????????????????????????cx_??????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????y1_??????????????????????????????????????????????????????????????????????????????cy_?????????????????????????????????????????????????????????????????????????????????????ry?????????????????????float?????????????????????????????????ux??????????????????????????????????????vy???????????????????????????????????????????uy????????????????????????????????????????????????vx?????????????????????float?????????????????????????????????????det???????????????????????????????????????????ux????????????????????????????????????????????????vx?????????????????????????????????????????????????????uy??????????????????????????????????????????????????????????vy?????????????????????????????????????????????????????ux??????????????????????????????????????????????????????????ux???????????????????????????????????????????????????????????????uy????????????????????????????????????????????????????????????????????uy???????????????????????????????????????????????????????????????????????????????????????????vx????????????????????????????????????????????????????????????????????????????????????????????????vx?????????????????????????????????????????????????????????????????????????????????????????????????????vy??????????????????????????????????????????????????????????????????????????????????????????????????????????vy?????????????????????ux???????????????????????????x1_?????????????????????????????????cx_????????????????????????????????????????rx????????????????????????????????????????????uy??????????????????????????????????????????????????y1_????????????????????????????????????????????????????????cy_???????????????????????????????????????????????????????????????ry?????????????????????vx????????????????????????????????x1_??????????????????????????????????????cx_?????????????????????????????????????????????rx?????????????????????????????????????????????????vy????????????????????????????????????????????????????????????y1_??????????????????????????????????????????????????????????????????cy_?????????????????????????????????????????????????????????????????????????ry?????????????????????det???????????????????????????ux????????????????????????????????vy?????????????????????????????????????uy??????????????????????????????????????????vx?????????????????????float?????????????????????????????????????det???????????????????????????????????????????ux????????????????????????????????????????????????vx?????????????????????????????????????????????????????uy??????????????????????????????????????????????????????????vy?????????????????????????????????????????????????????ux??????????????????????????????????????????????????????????ux???????????????????????????????????????????????????????????????uy????????????????????????????????????????????????????????????????????uy???????????????????????????????????????????????????????????????????????????????????????????vx????????????????????????????????????????????????????????????????????????????????????????????????vx?????????????????????????????????????????????????????????????????????????????????????????????????????vy??????????????????????????????????????????????????????????????????????????????????????????????????????????vy?????????????????????dtheta??????????????????????????????dtheta???????????fs??????????????????????dtheta??????????????????????????????????theta1????????????????????????????????????????????????PI???????????fs??????????????????????dtheta??????????????????????????????????theta1????????????????????????????????????????????????PI???????????fa??????????????????????dtheta??????????????????????????????????dtheta???????????????????????????????????????????????PI????????????????????????????????????????????????????dtheta????????????????fa???????????????????????????dtheta???????????????????????????????????????dtheta??????????????????????????????????????????????????????????PI???????????????????????????????????????????????????????????????dtheta????????????????????????????float?????????????????????theta1???????????int????????????????????j??????????????????????NUMSTEPS????????????????????????????????j????float????????????????????rx?????????????????????????????????????????theta??????????????????????????????????????????????????????????????????phi?????????????????????????????ry??????????????????????????????????????????????????theta???????????????????????????????????????????????????????????????????????????phi??????????????????????????????????????????????????????????????????????????????????cx????float????????????????????rx?????????????????????????????????????????theta??????????????????????????????????????????????????????????????????phi?????????????????????????????ry??????????????????????????????????????????????????phi?????????????????????????????????????????????????????????????????????????theta??????????????????????????????????????????????????????????????????????????????????cy?????????????????????????ret?????????????????????????????x???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_px????????????????????????????????????????????????????????????????????????????????rasterx?????????????????????????????????????????????????????????????????????????????????????????rastery?????????????????????????ret?????????????????????????????y???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_py????????????????????????????????????????????????????????????????????????????????rasterx?????????????????????????????????????????????????????????????????????????????????????????rastery?????????????????????????ret?????????????????????????????edges???????????????????????????????????ret???????????????????????????????????????numedges?????????????????????????????????????????????????????ret?????????????????????????????????????????????????????????numvertices??????????????????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????????????????numvertices????theta?????????????dtheta??????????????????????NUMSTEPS??????????????type???????????????????i?????????????????????????TYPE_CUBIC???????float??????????????????x????????????????????i???????????????????????????????c2x???????????????????????????????????i????????????????????????????????????????????c1x????????????????????????????????????????????????i?????????????????????????????????????????????????????x???????????????????????????????????????????????????????i???????float??????????????????????c2x??????????????????????????i???????????????????????????????????c1x???????????????????????????????????????i????????????????????????????????????????????????x??????????????????????????????????????????????????i???????float??????????????????????c1x??????????????????????????i???????????????????????????????????x?????????????????????????????????????i???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i???????????????????????????????c2y???????????????????????????????????i????????????????????????????????????????????c1y????????????????????????????????????????????????i?????????????????????????????????????????????????????y???????????????????????????????????????????????????????i???????float??????????????????????c2y??????????????????????????i???????????????????????????????????c1y???????????????????????????????????????i????????????????????????????????????????????????y??????????????????????????????????????????????????i???????float??????????????????????c1y??????????????????????????i???????????????????????????????????y?????????????????????????????????????i???????float??????????????????y????????????????????i???????????float??????????????????????t???????????????????????????t???????????????????????????????????????????NUMSTEPS????float???????????????ax????????????????????t????????????????????????t????????????????????????????t????????????????????????????????bx?????????????????????????????????????t?????????????????????????????????????????t?????????????????????????????????????????????cx??????????????????????????????????????????????????t??????????????????????????????????????????????????????dx????float???????????????ay????????????????????t????????????????????????t????????????????????????????t????????????????????????????????by?????????????????????????????????????t?????????????????????????????????????????t?????????????????????????????????????????????cy??????????????????????????????????????????????????t??????????????????????????????????????????????????????dy?????????????????????????ret?????????????????????????????x???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_px????????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????????ry?????????????????????????ret?????????????????????????????y???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_py????????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????????ry?????????????????????????ret?????????????????????????????edges???????????????????????????????????ret???????????????????????????????????????numedges?????????????????????????????????????????????????????ret?????????????????????????????????????????????????????????numvertices??????????????????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????????????????numvertices??????????????type???????????????????i?????????????????????????TYPE_QUADRADIC???????float??????????????????x????????????????????i???????????????????????????????c1x???????????????????????????????????i????????????????????????????????????????x??????????????????????????????????????????i???????float??????????????????????c1x??????????????????????????i???????????????????????????????????x?????????????????????????????????????i???????float??????????????????x????????????????????i???????float??????????????????y????????????????????i???????????????????????????????c1y???????????????????????????????????i????????????????????????????????????????y??????????????????????????????????????????i???????float??????????????????????c1y??????????????????????????i???????????????????????????????????y?????????????????????????????????????i???????float??????????????????y????????????????????i?????????????????????????float????????????????????????????????????t?????????????????????????????????????????t?????????????????????????????????????????????????????????NUMSTEPS????float???????????????bx????????????????????t????????????????????????t????????????????????????????cx?????????????????????????????????t?????????????????????????????????????dx????float???????????????by????????????????????t????????????????????????t????????????????????????????cy?????????????????????????????????t?????????????????????????????????????dy?????????????????????????ret?????????????????????????????x???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_px????????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????????ry?????????????????????????ret?????????????????????????????y???????????????????????????????ret???????????????????????????????????numvertices??????????????????????????????????????????????????????????????????a????????????????????????????????????????????????????????????????????multiply_py????????????????????????????????????????????????????????????????????????????????rx????????????????????????????????????????????????????????????????????????????????????ry?????????????????????????ret?????????????????????????????edges???????????????????????????????????ret???????????????????????????????????????numedges?????????????????????????????????????????????????????ret?????????????????????????????????????????????????????????numvertices??????????????????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????????????????numvertices?????????????????ret?????????????????????numedges???????????????????????????????????ret???????????????????????????????????????sort???????????????????????????????????????????????ret???????????????????????????????????????????????????numedges????????????????????ret???????????????????void????????????????????????parseSingleCommandAndArguments???????????????????????????????????????????????????????PathTokenizer????????????????????????????????????????????????????????????????????????char??????????????????????????????????????????????????????????????????????????????????????boolean?????????????????????????????????????command?????????????????float?????????????????????????????????????float?????????????????????????????????????????????????????????????????????????????????new_x??????????????????????????????????????????????????????????????????????????????????????????????????????????new_x?????????????????float?????????????????????????????????????float?????????????????????????????????????????????????????????????????????????????????new_y??????????????????????????????????????????????????????????????????????????????????????????????????????????new_y????????????????????command???int???????where????????????????????????????????where???????????????????????????????????????????where????????????????where????????????????????????????????????where????????????????????????????????????where????????????????????t??????????????????????parseFloat??????????????????????????????????????relative????????????????????t??????????????????????parseFloat??????????????????????????????????????relative?????????????????float?????????????????float???????????????????????????????t?????????????????????????????????parseFloat?????????????????????command?????????????????????second??????????????????????????????relative????????????????????????????command?????????????????????second??????????????????????????????first?????????????????????????????????????first?????????????????????????????????????????????relative?????????????????????second??????????????????????????????t????????????????????????????????parseFloat??????????????????????????????????first???????????????????????????????????????????relative??????????????????????????????????second????????????????????????????????????????????relative????????????????????????t??????????????????????????parseFloat??????????????????????????????????????????relative????????????????????????t??????????????????????????parseFloat??????????????????????????????????????????relative?????????????????????????t???????????????????????????parseFloat?????????????????????????????????????????????????????PI???????????????????????????????t?????????????????????????????????parseFloat????????????????????????????????????????????????????????????t??????????????????????????????????????????????????????????????parseFloat????????????????????t??????????????????????parseFloat??????????????????????????????????????relative????????????????????t??????????????????????parseFloat??????????????????????????????????????relative?????????????????????command??????????????????????????????????????????t????????????????????????????????????????????parseFloat????????????????????????????????????????????????????????????relative??????????????????????????????????????????t????????????????????????????????????????????parseFloat????????????????????????????????????????????????????????????relative??????????????????????????????????????t????????????????????????????????????????parseFloat????????????????????????????????????????????????????????relative??????????????????????????????????????t????????????????????????????????????????parseFloat????????????????????????????????????????????????????????relative????????????????????t??????????????????????parseFloat??????????????????????????????????????relative????????????????????t??????????????????????parseFloat??????????????????????????????????????relative?????????????????????command??????????????????????????????????????????t????????????????????????????????????????????parseFloat????????????????????????????????????????????????????????????relative??????????????????????????????????????????t????????????????????????????????????????????parseFloat????????????????????????????????????????????????????????????relative??????????????????????????????????t????????????????????????????????????parseFloat????????????????????????????????????????????????????relative??????????????????????????????????t????????????????????????????????????parseFloat????????????????????????????????????????????????????relative?????????????????????????????????????????????????????????????????RasterPath????int????????x????????????????int????????????????????DEFAULT_PATHLEN??int????????y????????????????int????????????????????DEFAULT_PATHLEN??int??????numvertices???????????int????????edges????????????????????int????????????????????????DEFAULT_PATHLEN?????????int?????????????numedges?????????????????????????void?????????????????????translate???????????????????????????????int???????????????????????????????????????int?????????????????????????????????????????????????????int??????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????numvertices?????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????x??????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????dx????????????????????????????????????????????????????????????????????????????????????????????????y??????????????????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????dy??????????????????int?????????????sort??????????????????int????????????????????????????int???????????????????????????????????????boolean??????????partition???int???int???int???middle?????????????left????????????????????right???int???????????edges?????????????????right?????????????????????????edges???????????????????????????????right????????????????????????????????????????edges??????????????????????????????????????????????middle???????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????middle???????????????????????????????????????????????????????????????????????s????????i????????????left??????????????????????j??????????????????????????right??????????????y????????????????edges????????????????????????i??????????????????????????????y????????????????????????????????edges??????????????????????????????????????right??????????????j??????????????????left??????????????????????????y????????????????????????????edges????????????????????????????????????j??????????????????????????????????????????y????????????????????????????????????????????edges??????????????????????????????????????????????????right???????????i????????????????j???????s???????????edges?????????????????i?????????????????????edges???????????????????????????i????????????????????????????????edges??????????????????????????????????????j??????????????????????????????????????????edges????????????????????????????????????????????????j?????????????????????????????????????????????????????s???s???????edges?????????????right?????????????????????edges???????????????????????????right????????????????????????????????????edges??????????????????????????????????????????i??????????????????????????????????????????????edges????????????????????????????????????????????????????i?????????????????????????????????????????????????????????s??????????i???????left???????????????right???int???????????sort????????????????left??????????????????????right???sort????????left??????????????p???sort????????p???????????????right???????????????????int??????????????intercept????????????????????????int???????????????????????????????float?????????????????????????????????????????boolean?????????????????????????????????????????????????????????????boolean?????????????????includeTop???????????????????????????????_y?????????????????????????????????????????????y???????????????????????????????????????????????i???????????????????????????????????????????????????y?????????????????????????????????????????????????????i???????????????????????????????????????????????????????????????_y??????????????????????????????????????????????????????????????????????????????y????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????y??????????????????????????????????????????????????????????????????????????????????????i?????????????????includeBottom??????????????????????????????????_y????????????????????????????????????????????????y??????????????????????????????????????????????????i??????????????????????????????????????????????????????y????????????????????????????????????????????????????????i??????????????????????????????????????????????????????????????????_y?????????????????????????????????????????????????????????????????????????????????y???????????????????????????????????????????????????????????????????????????????????i???????????????????????????????????????????????????????????????????????????????????????y?????????????????????????????????????????????????????????????????????????????????????????i???????????????????????????????????????x?????????????????????????????????????????i??????????????????????????????????????????????????x????????????????????????????????????????????????????i??????????????????????????????????????????????y????????????????????????????????????????????????i?????????????????????????????????????????????????????????y???????????????????????????????????????????????????????????i?????????????????????????????????????????????????????????????????????????????_y??????????????????????????????????????????????????????????????????????????????????y????????????????????????????????????????????????????????????????????????????????????i???????????????????????????????????????????????????????????????????????????????????????????x?????????????????????????????????????????????????????????????????????????????????????????????i??????????????????void??????????????fill???????????????????PixelBuffer????????????????????????????????????Paint?????????????????numedges??????int??????int???????????????y?????????????????edges?????????????????????????????????y0??????boolean??????????????????????????????int????????????????????????????????index??????????????????????????????????????numedges????????????????????????????????????????????????index?????????????????int????????????????????y0????????y1???y1????????y??????????edges????????????????index?????????????????????y0???????????????????????????y1??????????????????????????????????int?????????????????int?????????????????????int?????????????????????int?????????????????????????int??????????????????????????????????i????????????????????????????????????numedges??????????????????????????????????????????????i?????????????????????????????y???????????????????????????????edges?????????????????????????????????????i????????????????????????????????????????????y??????????????????????????????????????????????edges????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????int??????????????????????????????????intercept????????????????????????????????????????????edges??????????????????????????????????????????????????i??????????????????????????????????????????????????????y0?????????????????????????int??????????????????????????????????intercept????????????????????????????????????????????edges??????????????????????????????????????????????????i??????????????????????????????????????????????????????y1?????????????????????????????i0????????????????????????????????????????????????????????i1?????????????????????????int????????????????????????????????????????i0?????????????????????????????????????????????i1?????????????????????????????midpoint????????????????????????????????????????x0?????????????????????????????midpoint?????????????????????????????????????????x0???????????????????????????????????????????????i????????????????????????????????????????????????????leftSegment?????????????????????????????midpoint????????????????????????????????????????x1?????????????????????????????midpoint?????????????????????????????????????????x1???????????????????????????????????????????????i????????????????????????????????????????????????????rightSegment?????????????????????????rightSegment????????????????????????????????????????i?????????????????????????x1??????????????????????????????midpoint?????????????????????????leftSegment????????????????????????????????????????rightSegment????????????????????????????????????????????????????????rightSegment?????????????????????????leftSegment??????????????????????????????useEvenOdd????????????????????????????????????????????count?????????????????????????????????????????????????????????????????useEvenOdd???????????????????????????????????????????????????????????????????????????????count?????????????????????????????paint???????????????????????????????????fillTrapezoid?????????????????????????????????????????????????intercept???????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????leftSegment???????????????????????????????????????????????????????????????????????????????y0?????????????????????????????????????????????????intercept???????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????rightSegment????????????????????????????????????????????????????????????????????????????????y0?????????????????????????????????????????????????????????????????????????????????????????????????y0?????????????????????????????????????????????????intercept???????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????leftSegment???????????????????????????????????????????????????????????????????????????????y1?????????????????????????????????????????????????intercept???????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????rightSegment????????????????????????????????????????????????????????????????????????????????y1?????????????????????????????????????????????????????????????????????????????????????????????????y1?????????????????????????????????????????????????buf?????????????????????????useEvenOdd?????????????????????????????????????count??????????????????????????count????????????????????????????????????y??????????????????????????????????????edges????????????????????????????????????????????rightSegment?????????????????????????????????????????????????????????????y???????????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????????rightSegment?????????????????????leftSegment???????????????????????????????????rightSegment?????????????????????????????????????????????????x0??????????????????????????????????????????????????????x1?????????????????????????void?????????????????????stroke????????????????????????????PixelBuffer?????????????????????????????????????????????int????????????????????????????????????????????????????????int?????????????????????????????????????????????????????????????????????stroke????????????????????????????????????????????????????????????????????????????buf?????????????????????????????????????????????????????????????????????????????????width????????????????????????????????????????????????????????????????????????????????????????color????????????????void?????????????????????stroke????????????????????????????PixelBuffer?????????????????????????????????????????????int????????????????????????????????????????????????????????int?????????????????????????????????????????????????????????????????????????????????????int?????????????????????????????????????????????????????????????????????????????????????????????????????float?????????????????dashArray?????????????????????int??????????????????????????????i????????????????????????????????numedges??????????????????????????????????????????i?????????????????????buf?????????????????????????drawLine???????????????????????????????????????x?????????????????????????????????????????edges???????????????????????????????????????????????i???????????????????????????????????????y?????????????????????????????????????????edges???????????????????????????????????????????????i?????????????????????????????????????????????????????????x???????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????i?????????????????????????????????????????????????????????????????????????????y???????????????????????????????????????????????????????????????????????????????edges?????????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????????????width???????????????????????????????????????????????????????????????????????????????????????????????????color?????????????float?????????????????segLength?????????????????float?????????????????????int??????????????????????????????i????????????????????????????????numvertices?????????????????????????????????????????????i??????????????????????????????????????????????x???????????????????????????i?????????????????????????????????x???????????????????????????????????i???????????????????????????????????????????y?????????????????????????????????????????????i???????????????????????????????????????????????????y?????????????????????????????????????????????????????i?????????????????????????x???????????????????????????i???????????????????????????????????x?????????????????????????????????????i?????????????????????????????????????????????y???????????????????????????????????????????????i???????????????????????????????????????????????????????y?????????????????????????????????????????????????????????i?????????????????????int??????????????????????????????x????????????????????????????????i?????????????????????int??????????????????????????????x????????????????????????????????i?????????????????????int??????????????????????????????y????????????????????????????????i?????????????????????int??????????????????????????????y????????????????????????????????i?????????????????????actualLength??????????????????????????????????????????????????????????x2???????????????????????????????????????????????????????????????x1??????????????????????????????????????????????????????????????????????x2???????????????????????????????????????????????????????????????????????????x1??????????????????????????????????????????????????????????????????????????????????y2???????????????????????????????????????????????????????????????????????????????????????y1??????????????????????????????????????????????????????????????????????????????????????????????y2???????????????????????????????????????????????????????????????????????????????????????????????????y1?????????????????ratio?????????????????????????actualLength????????????????????????????????????????segLength?????????????PathTokenizer????????????????????????????????????PathTokenizer??????????????????????????????????????????????????dashArray????????????????????pt???????????????????????hasMoreTokens????????????????????????????????????????v???????????????????????????????????????????????????????????????pt??????????????????????????????????????????????????????????????????parseFloat?????????????float??????????????????????????????????float????????????????????????????????????????v????????????????????????????????????????????????????????????v???????????????????????????????????????????????????????????????????????????v?????????????????int??????????????????????????i????????????????????????????dashes???????????????????????????????????????????i????????????????????????????????????????????????dashes???????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????v????????????????????????????????????????????????????????????????????????????????i????????????????????????????????????????????????????????????????????????????????????v?????????????float?????????????int???????????????????????????dashOffset?????????????boolean??????????????????????????dashpos?????????????????int??????????????????????????i????????????????????????????numvertices?????????????????????????????????????????i??????????????????????????????????????x???????????????????????i?????????????????????????????x???????????????????????????????i???????????????????????????????????????y?????????????????????????????????????????i???????????????????????????????????????????????y?????????????????????????????????????????????????i?????????????????????x???????????????????????i???????????????????????????????x?????????????????????????????????i?????????????????????????????????????????y???????????????????????????????????????????i???????????????????????????????????????????????????y?????????????????????????????????????????????????????i?????????????????int???????????????????????????????x?????????????????????????????????i?????????????????int???????????????????????????????x?????????????????????????????????i?????????????????int???????????????????????????????y?????????????????????????????????i?????????????????int???????????????????????????????y?????????????????????????????????i?????????????????float???????????????????????????????????????????????????????????????????x2????????????????????????????????????????????????????????????????????????x1???????????????????????????????????????????????????????????????????????????????x2????????????????????????????????????????????????????????????????????????????????????x1???????????????????????????????????????????????????????????????????????????????????????????y2????????????????????????????????????????????????????????????????????????????????????????????????y1???????????????????????????????????????????????????????????????????????????????????????????????????????y2????????????????????????????????????????????????????????????????????????????????????????????????????????????y1?????????????????int?????????????????int???????????????????????????x1?????????????????????????????????????y1?????????????????float?????????????????????pos????????????????????????????????????segmentLength???????????????????????????????????????????????????pos?????????????????????????????????????????????????????????dashes????????????????????????????????????????????????????????????????dashpos???????????????????????????????????????????????????????????????????????????ratio?????????????????????????pos????????????????????????????????segmentLength???????????????????????????????????????????????dashpos??????????????????????????????????????????????????????????dashpos?????????????????????????????????????????????????????????????????????????dashes?????????????????????int??????????????????????????????????????x2???????????????????????????????????????????pos?????????????????????????????????????????????????x1???????????????????????????????????????????????????????segmentLength???????????????????????????????????????????????????????????????????????pos???????????????????????????????????????????????????????????????????????????????segmentLength?????????????????????int??????????????????????????????????????y2???????????????????????????????????????????pos?????????????????????????????????????????????????y1???????????????????????????????????????????????????????segmentLength???????????????????????????????????????????????????????????????????????pos???????????????????????????????????????????????????????????????????????????????segmentLength?????????????????????????on?????????????????????????????buf?????????????????????????????????drawLine??????????????????????????????????????????_x1???????????????????????????????????????????????_y1????????????????????????????????????????????????????_x2?????????????????????????????????????????????????????????_y2??????????????????????????????????????????????????????????????width?????????????????????????????????????????????????????????????????????color?????????????????????on???????????????????????????on?????????????????????_x1???????????????????????????_x2????????????????????????????????_y1??????????????????????????????????????_y2?????????????????????????pos???????????????????????????????segmentLength?????????????????????????int????????????????????boundingBoxWidth?????????????int?????????????????int??????????????????????????i????????????????????????????numvertices?????????????????????????????????????????i??????????????????????????????????????????????ret?????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????x????????????????????????????????????????????????????????????????????i????????????????????ret?????????????????????????int????????????????????boundingBoxHeight?????????????int?????????????????int??????????????????????????i????????????????????????????numvertices?????????????????????????????????????????i??????????????????????????????????????????????ret?????????????????????????????????????????????????????????????ret??????????????????????????????????????????????????????????????????y????????????????????????????????????????????????????????????????????i????????????????????ret??????????????????????????????????Paint??????????????????void?????????????fillTrapezoid???????????????????????????int????????????????????????????????????int?????????????????????????????????????????????int??????????????????????????????????????????????????????int???????????????????????????????????????????????????????????????int????????????????????????????????????????????????????????????????????????int?????????????????????????????????????????????????????????????????????????????????PixelBuffer?????????????????????????SingleColorPaint?????????????????????????????????????????????????????Paint?????????int?????????????color????????????????SingleColorPaint?????????????????????????????????int???????????????????????????????????????????????????????????color????????????????void?????????????????????fillTrapezoid???????????????????????????????????int???????????????????????????????????????????int???????????????????????????????????????????????????int???????????????????????????????????????????????????????????int???????????????????????????????????????????????????????????????????int???????????????????????????????????????????????????????????????????????????int???????????????????????????????????????????????????????????????????????????????????PixelBuffer?????????????buf?????????????????fillTrapezoid???????????????????????????????x1???????????????????????????????????x2???????????????????????????????????????y1???????????????????????????????????????????x3???????????????????????????????????????????????x4???????????????????????????????????????????????????y2???????????????????????????????????????????????????????color?????