1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package test.com.sun.javafx.geom; 27 28 import com.sun.javafx.geom.Arc2D; 29 import com.sun.javafx.geom.BoxBounds; 30 import com.sun.javafx.geom.IllegalPathStateException; 31 import com.sun.javafx.geom.Path2D; 32 import com.sun.javafx.geom.PathIterator; 33 import com.sun.javafx.geom.RectBounds; 34 import com.sun.javafx.geom.Shape; 35 import com.sun.javafx.geom.transform.BaseTransform; 36 import static junit.framework.Assert.assertTrue; 37 import static junit.framework.Assert.assertFalse; 38 import static junit.framework.Assert.assertEquals; 39 40 import org.junit.Test; 41 42 public class Path2DTest { 43 void checkLine(PathIterator pi, float x1, float y1, float x2, float y2) { 44 float coords[] = new float[2]; 45 assertFalse(pi.isDone()); 46 assertEquals(PathIterator.SEG_MOVETO, pi.currentSegment(coords)); 47 assertEquals(x1, coords[0], .001); 48 assertEquals(y1, coords[1], .001); 49 assertFalse(pi.isDone()); 50 pi.next(); 51 assertFalse(pi.isDone()); 52 assertEquals(PathIterator.SEG_LINETO, pi.currentSegment(coords)); 53 assertEquals(x2, coords[0], .001); 54 assertEquals(y2, coords[1], .001); 55 assertFalse(pi.isDone()); 56 pi.next(); 57 assertTrue(pi.isDone()); 58 } 59 60 void checkAndResetPaths(Path2D pref, Path2D ptest, float curx, float cury) { 61 checkAndResetPaths(pref, ptest, curx, cury, false); 62 } 63 64 void checkAndResetPaths(Path2D pref, Path2D ptest, 65 float curx, float cury, 66 boolean verbose) 67 { 68 assertEquals(curx, pref.getCurrentX(), .001); 69 assertEquals(cury, pref.getCurrentY(), .001); 70 checkShapes(pref, ptest, verbose); 71 pref.reset(); 72 ptest.reset(); 73 } 74 75 void checkShapes(Shape sref, Shape stest) { 76 checkShapes(sref, stest, false); 77 } 78 79 void checkShapes(Shape sref, Shape stest, boolean verbose) { 80 checkPaths(sref.getPathIterator(BaseTransform.IDENTITY_TRANSFORM), 81 stest.getPathIterator(BaseTransform.IDENTITY_TRANSFORM), 82 verbose); 83 } 84 85 void checkPaths(PathIterator piref, PathIterator pitest) { 86 checkPaths(piref, pitest, false); 87 } 88 89 static int numcoords[]; 90 static { 91 numcoords = new int[5]; 92 numcoords[PathIterator.SEG_MOVETO] = 2; 93 numcoords[PathIterator.SEG_LINETO] = 2; 94 numcoords[PathIterator.SEG_QUADTO] = 4; 95 numcoords[PathIterator.SEG_CUBICTO] = 6; 96 numcoords[PathIterator.SEG_CLOSE] = 0; 97 } 98 99 void checkPaths(PathIterator piref, PathIterator pitest, boolean verbose) { 100 float coordsref[] = new float[6]; 101 float coordstest[] = new float[6]; 102 while (!piref.isDone()) { 103 assertFalse(pitest.isDone()); 104 int typref = piref.currentSegment(coordsref); 105 int typtest = pitest.currentSegment(coordstest); 106 assertEquals(typref, typtest); 107 if (verbose) System.out.println("type = "+typref); 108 for (int i = 0; i < numcoords[typref]; i++) { 109 assertEquals(coordsref[i], coordstest[i], .001); 110 if (verbose) System.out.println("coord["+i+"] = "+coordsref[i]); 111 } 112 assertFalse(pitest.isDone()); 113 piref.next(); 114 pitest.next(); 115 } 116 assertTrue(pitest.isDone()); 117 } 118 119 double angle(double ux, double uy, double vx, double vy) { 120 double sgn = (ux * vy - uy * vx) > 0 ? 1f : -1f; 121 double dot = ux * vx + uy * vy; 122 double ulen = Math.hypot(ux, uy); 123 double vlen = Math.hypot(vx, vy); 124 double cos = dot / (ulen * vlen); 125 if (cos < -1f) cos = -1f; 126 else if (cos > 1f) cos = 1f; 127 return sgn * Math.acos(cos); 128 } 129 130 void checkArcTo(float x1, float y1, 131 float rw, float rh, float arcrad, 132 boolean largeArcs, boolean sweepFlag, 133 float x2, float y2) 134 { 135 // System.out.println("rw="+rw+", rh="+rh+", phi="+arcrad+", fA="+largeArcs+", fS="+sweepFlag+", x="+x2+", y="+y2); 136 // Comparing to math specified at: 137 // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes 138 Path2D path = new Path2D(); 139 path.moveTo(x1, y1); 140 path.arcTo(rw/2f, rh/2f, arcrad, largeArcs, sweepFlag, x2, y2); 141 double rx = rw/2.0; 142 double ry = rh/2.0; 143 if (rx == 0 || ry == 0) { 144 checkLine(path.getPathIterator(BaseTransform.IDENTITY_TRANSFORM), 145 x1, y1, x2, y2); 146 return; 147 } 148 double cosphi = Math.cos(arcrad); 149 double sinphi = Math.sin(arcrad); 150 double x1p = cosphi * ((x1 - x2) / 2f) + sinphi * ((y1 - y2) / 2f); 151 double y1p = -sinphi * ((x1 - x2) / 2f) + cosphi * ((y1 - y2) / 2f); 152 double x1psq = x1p * x1p; 153 double y1psq = y1p * y1p; 154 double rxsq = rx * rx; 155 double rysq = ry * ry; 156 double delta = (x1psq / rxsq) + (y1psq / rysq); 157 double num = rxsq * rysq - rxsq * y1psq - rysq * x1psq; 158 if (delta > 1f) { 159 rx *= Math.sqrt(delta); 160 ry *= Math.sqrt(delta); 161 rxsq = rx * rx; 162 rysq = ry * ry; 163 // Note that repeating the num calculation can sometimes yield 164 // a negative answer... 165 num = 0; 166 } 167 double den = rxsq * y1psq + rysq * x1psq; 168 double sgn = (largeArcs == sweepFlag) ? -1f : 1f; 169 double cxp = sgn * Math.sqrt(num / den) * (rx * y1p) / ry; 170 double cyp = sgn * Math.sqrt(num / den) * -(ry * x1p) / rx; 171 double cx = cosphi * cxp - sinphi * cyp + (x1 + x2) / 2f; 172 double cy = sinphi * cxp + cosphi * cyp + (y1 + y2) / 2f; 173 double theta = angle(1, 0, 174 (x1p - cxp) / rx, (y1p - cyp) / ry); 175 double dtheta = angle((x1p - cxp) / rx, (y1p - cyp) / ry, 176 (-x1p - cxp) / rx, (-y1p - cyp) / ry); 177 theta = Math.toDegrees(theta); 178 dtheta = Math.toDegrees(dtheta); 179 if (sweepFlag && dtheta < 0) dtheta += 360; 180 if (!sweepFlag && dtheta > 0) dtheta -= 360; 181 Arc2D arc = new Arc2D((float) (cx-rx), (float) (cy-ry), 182 (float) (rx*2.0), (float) (ry*2.0), 183 (float) -theta, (float) -dtheta, Arc2D.OPEN); 184 BaseTransform arctx = 185 BaseTransform.getRotateInstance(arcrad, cx, cy); 186 checkPaths(arc.getPathIterator(arctx), 187 path.getPathIterator(BaseTransform.IDENTITY_TRANSFORM)); 188 } 189 190 public @Test 191 void testArcTo() { 192 Path2D path = new Path2D(); 193 for (int pathdeg = 0; pathdeg <= 360; pathdeg += 15) { 194 double pathrad = Math.toRadians(pathdeg); 195 float px = (float) Math.cos(pathrad) * 50; 196 float py = (float) Math.sin(pathrad) * 50; 197 for (int arcdeg = 0; arcdeg <= 360; arcdeg += 15) { 198 float arcrad = (float) Math.toRadians(arcdeg); 199 for (int rw = 0; rw < 100; rw += 10) { 200 for (int rh = 0; rh < 100; rh += 10) { 201 checkArcTo(-px, -py, rw, rh, arcrad, false, false, px, py); 202 checkArcTo(-px, -py, rw, rh, arcrad, false, true, px, py); 203 checkArcTo(-px, -py, rw, rh, arcrad, true, false, px, py); 204 checkArcTo(-px, -py, rw, rh, arcrad, true, true, px, py); 205 } 206 } 207 } 208 } 209 RectBounds rectBounds = new RectBounds(10, 20, 20, 30); 210 assertFalse(rectBounds.isEmpty()); 211 rectBounds.makeEmpty(); 212 assertTrue(rectBounds.isEmpty()); 213 assertEquals(new RectBounds(), rectBounds); 214 215 BoxBounds boxBounds = new BoxBounds(10, 20, 10, 40, 50, 20); 216 assertFalse(boxBounds.isEmpty()); 217 boxBounds.makeEmpty(); 218 assertTrue(boxBounds.isEmpty()); 219 assertEquals(new BoxBounds(), boxBounds); 220 } 221 222 public @Test 223 void testEmptyPathException() { 224 int bad = 0; 225 Path2D p = new Path2D(); 226 try { p.lineTo(0, 0); bad++; } catch (IllegalPathStateException e) {} 227 try { p.quadTo(0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 228 try { p.curveTo(0, 0, 0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 229 try { p.arcTo(1, 1, 0, true, true, 1, 1); bad++; } catch (IllegalPathStateException e) {} 230 try { p.moveToRel(0, 0); bad++; } catch (IllegalPathStateException e) {} 231 try { p.lineToRel(0, 0); bad++; } catch (IllegalPathStateException e) {} 232 try { p.quadToRel(0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 233 try { p.curveToRel(0, 0, 0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 234 try { p.arcToRel(1, 1, 0, true, true, 1, 1); bad++; } catch (IllegalPathStateException e) {} 235 try { p.quadToSmooth(0, 0); bad++; } catch (IllegalPathStateException e) {} 236 try { p.curveToSmooth(0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 237 try { p.quadToSmoothRel(0, 0); bad++; } catch (IllegalPathStateException e) {} 238 try { p.curveToSmoothRel(0, 0, 0, 0); bad++; } catch (IllegalPathStateException e) {} 239 assertEquals(0, bad); 240 } 241 242 public @Test 243 void testRelative() { 244 Path2D pabs = new Path2D(); 245 Path2D prel = new Path2D(); 246 for (int x0 = -100; x0 < 100; x0 += 50) { 247 for (int y0 = -100; y0 < 100; y0 += 50) { 248 for (int x1 = -100; x1 < 100; x1 += 50) { 249 for (int y1 = -100; y1 < 100; y1 += 50) { 250 testRelative(pabs, prel, x0, y0, x1, y1); 251 } 252 } 253 } 254 } 255 } 256 257 private void testRelative(Path2D pabs, Path2D prel, 258 int x0, int y0, int x1, int y1) 259 { 260 // Test relative moveTo following moveTo 261 pabs.moveTo(x0, y0); 262 pabs.moveTo(x1, y1); 263 prel.moveTo(x0, y0); 264 prel.moveToRel(x1-x0, y1-y0); 265 checkAndResetPaths(pabs, prel, x1, y1); 266 267 // Test relative lineTo 268 pabs.moveTo(x0, y0); 269 pabs.lineTo(x1, y1); 270 prel.moveTo(x0, y0); 271 prel.lineToRel(x1-x0, y1-y0); 272 checkAndResetPaths(pabs, prel, x1, y1); 273 274 // test relative arcTo 275 pabs.moveTo(x0, y0); 276 pabs.arcTo(1, 1, 0, true, true, x1, y1); 277 prel.moveTo(x0, y0); 278 prel.arcToRel(1, 1, 0, true, true, x1-x0, y1-y0); 279 checkAndResetPaths(pabs, prel, x1, y1); 280 281 // test relative paths with longer coordinate lists 282 for (int x2 = -100; x2 < 100; x2 += 50) { 283 for (int y2 = -100; y2 < 100; y2 += 50) { 284 testRelative(pabs, prel, x0, y0, x1, y1, x2, y2); 285 } 286 } 287 } 288 289 private void testRelative(Path2D pabs, Path2D prel, 290 int x0, int y0, int x1, int y1, int x2, int y2) 291 { 292 // test relative quadTo 293 pabs.moveTo(x0, y0); 294 pabs.quadTo(x1, y1, x2, y2); 295 prel.moveTo(x0, y0); 296 prel.quadToRel(x1-x0, y1-y0, x2-x0, y2-y0); 297 checkAndResetPaths(pabs, prel, x2, y2); 298 299 for (int x3 = -100; x3 < 100; x3 += 50) { 300 for (int y3 = -100; y3 < 100; y3 += 50) { 301 // test relative cubic curveTo 302 pabs.moveTo(x0, y0); 303 pabs.curveTo(x1, y1, x2, y2, x3, y3); 304 prel.moveTo(x0, y0); 305 prel.curveToRel(x1-x0, y1-y0, x2-x0, y2-y0, x3-x0, y3-y0); 306 checkAndResetPaths(pabs, prel, x3, y3); 307 } 308 } 309 } 310 311 public @Test 312 void testSmoothCurves() { 313 Path2D pabs = new Path2D(); 314 Path2D psmooth = new Path2D(); 315 for (int x0 = -100; x0 < 100; x0 += 50) { 316 for (int y0 = -100; y0 < 100; y0 += 50) { 317 for (int x1 = -100; x1 < 100; x1 += 50) { 318 for (int y1 = -100; y1 < 100; y1 += 50) { 319 testSmoothCurves(pabs, psmooth, x0, y0, x1, y1); 320 } 321 } 322 } 323 } 324 } 325 326 private void testSmoothCurves(Path2D pabs, Path2D psmooth, 327 int x0, int y0, int x1, int y1) 328 { 329 for (int xc0 = -100; xc0 < 100; xc0 += 100) { 330 for (int yc0 = -100; yc0 < 100; yc0 += 100) { 331 // test smooth quadto after lineTo 332 pabs.moveTo(x0, y0); 333 pabs.lineTo(xc0, yc0); 334 pabs.quadTo(xc0, yc0, x1, y1); 335 psmooth.moveTo(x0, y0); 336 psmooth.lineTo(xc0, yc0); 337 psmooth.quadToSmooth(x1, y1); 338 checkAndResetPaths(pabs, psmooth, x1, y1); 339 340 // test smooth relative quadTo after lineTo 341 pabs.moveTo(x0, y0); 342 pabs.lineTo(xc0, yc0); 343 pabs.quadTo(xc0, yc0, x1, y1); 344 psmooth.moveTo(x0, y0); 345 psmooth.lineTo(xc0, yc0); 346 psmooth.quadToSmoothRel(x1-xc0, y1-yc0); 347 checkAndResetPaths(pabs, psmooth, x1, y1); 348 349 for (int xc1 = -100; xc1 < 100; xc1 += 100) { 350 for (int yc1 = -100; yc1 < 100; yc1 += 100) { 351 float xc01 = (xc0 + xc1) / 2f; 352 float yc01 = (yc0 + yc1) / 2f; 353 354 // test smooth quadTo after quadTo 355 pabs.moveTo(x0, y0); 356 pabs.quadTo(xc0, yc0, xc01, yc01); 357 pabs.quadTo(xc1, yc1, x1, y1); 358 psmooth.moveTo(x0, y0); 359 psmooth.quadTo(xc0, yc0, xc01, yc01); 360 psmooth.quadToSmooth(x1, y1); 361 checkAndResetPaths(pabs, psmooth, x1, y1); 362 363 // test smooth relative quadTo after quadTo 364 pabs.moveTo(x0, y0); 365 pabs.quadTo(xc0, yc0, xc01, yc01); 366 pabs.quadTo(xc1, yc1, x1, y1); 367 psmooth.moveTo(x0, y0); 368 psmooth.quadTo(xc0, yc0, xc01, yc01); 369 psmooth.quadToSmoothRel(x1-xc01, y1-yc01); 370 checkAndResetPaths(pabs, psmooth, x1, y1); 371 372 // test smooth curveTo after lineTo 373 pabs.moveTo(x0, y0); 374 pabs.lineTo(xc0, yc0); 375 pabs.curveTo(xc0, yc0, xc1, yc1, x1, y1); 376 psmooth.moveTo(x0, y0); 377 psmooth.lineTo(xc0, yc0); 378 psmooth.curveToSmooth(xc1, yc1, x1, y1); 379 checkAndResetPaths(pabs, psmooth, x1, y1); 380 381 // test smooth relative curveTo after lineTo 382 pabs.moveTo(x0, y0); 383 pabs.lineTo(xc0, yc0); 384 pabs.curveTo(xc0, yc0, xc1, yc1, x1, y1); 385 psmooth.moveTo(x0, y0); 386 psmooth.lineTo(xc0, yc0); 387 psmooth.curveToSmoothRel(xc1-xc0, yc1-yc0, x1-xc0, y1-yc0); 388 checkAndResetPaths(pabs, psmooth, x1, y1); 389 390 testSmoothCurves(pabs, psmooth, 391 x0, y0, x1, y1, 392 xc0, yc0, xc01, yc01, xc1, yc1); 393 } 394 } 395 } 396 } 397 } 398 399 private void testSmoothCurves(Path2D pabs, Path2D psmooth, 400 int x0, int y0, int x1, int y1, 401 int xc0, int yc0, 402 float xc01, float yc01, 403 int xc1, int yc1) 404 { 405 for (int xc2 = -100; xc2 < 100; xc2 += 100) { 406 for (int yc2 = -100; yc2 < 100; yc2 += 100) { 407 // test smooth curveTo after quadTo 408 pabs.moveTo(x0, y0); 409 pabs.quadTo(xc0, yc0, xc01, yc01); 410 pabs.curveTo(xc1, yc1, xc2, yc2, x1, y1); 411 psmooth.moveTo(x0, y0); 412 psmooth.quadTo(xc0, yc0, xc01, yc01); 413 psmooth.curveToSmooth(xc2, yc2, x1, y1); 414 checkAndResetPaths(pabs, psmooth, x1, y1); 415 416 // test smooth relative curveTo after quadTo 417 pabs.moveTo(x0, y0); 418 pabs.quadTo(xc0, yc0, xc01, yc01); 419 pabs.curveTo(xc1, yc1, xc2, yc2, x1, y1); 420 psmooth.moveTo(x0, y0); 421 psmooth.quadTo(xc0, yc0, xc01, yc01); 422 psmooth.curveToSmoothRel(xc2-xc01, yc2-yc01, x1-xc01, y1-yc01); 423 checkAndResetPaths(pabs, psmooth, x1, y1); 424 425 float xc12 = (xc1 + xc2) / 2f; 426 float yc12 = (yc1 + yc2) / 2f; 427 428 // test smooth quadTo after curveTo 429 pabs.moveTo(x0, y0); 430 pabs.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 431 pabs.quadTo(xc2, yc2, x1, y1); 432 psmooth.moveTo(x0, y0); 433 psmooth.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 434 psmooth.quadToSmooth(x1, y1); 435 checkAndResetPaths(pabs, psmooth, x1, y1); 436 437 // test smooth relative quadTo after curveTo 438 pabs.moveTo(x0, y0); 439 pabs.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 440 pabs.quadTo(xc2, yc2, x1, y1); 441 psmooth.moveTo(x0, y0); 442 psmooth.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 443 psmooth.quadToSmoothRel(x1-xc12, y1-yc12); 444 checkAndResetPaths(pabs, psmooth, x1, y1); 445 446 for (int xc3 = -100; xc3 < 100; xc3 += 100) { 447 for (int yc3 = -100; yc3 < 100; yc3 += 100) { 448 // test smooth curveTo after curveTo 449 pabs.moveTo(x0, y0); 450 pabs.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 451 pabs.curveTo(xc2, yc2, xc3, yc3, x1, y1); 452 psmooth.moveTo(x0, y0); 453 psmooth.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 454 psmooth.curveToSmooth(xc3, yc3, x1, y1); 455 checkAndResetPaths(pabs, psmooth, x1, y1); 456 457 // test smooth relative curveTo after curveTo 458 pabs.moveTo(x0, y0); 459 pabs.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 460 pabs.curveTo(xc2, yc2, xc3, yc3, x1, y1); 461 psmooth.moveTo(x0, y0); 462 psmooth.curveTo(xc0, yc0, xc1, yc1, xc12, yc12); 463 psmooth.curveToSmoothRel(xc3-xc12, yc3-yc12, x1-xc12, y1-yc12); 464 checkAndResetPaths(pabs, psmooth, x1, y1); 465 } 466 } 467 } 468 } 469 } 470 471 public @Test 472 void testSVGPath() { 473 String svgpath = 474 "M 10 20 "+ 475 "L 20 30 "+ 476 "H 10 "+ 477 "V 20 "+ 478 "Q 20 30 10 20 "+ 479 "C 20 30 20 20 10 40 "+ 480 "T 10 50 "+ 481 "S 20 25 10 35 "+ 482 "A 40 60 10 0 0 15 20 "+ 483 "A 40 60 10 0 1 25 30 "+ 484 "A 40 60 10 1 0 15 10 "+ 485 "A 40 60 10 1 1 25 20 "+ 486 "Z "+ 487 "m 10 20 "+ 488 "l 20 20 "+ 489 "h 10 "+ 490 "v 20 "+ 491 "q 10 30 10 20 "+ 492 "c 10 30 10 20 10 40 "+ 493 "t 10 50 "+ 494 "s 10 25 10 35 "+ 495 "a 40 60 10 0 0 10 20 "+ 496 "a 40 60 10 0 1 10 20 "+ 497 "a 40 60 10 1 0 10 20 "+ 498 "a 40 60 10 1 1 10 20 "+ 499 "z"; 500 Path2D p2dtest = new Path2D(); 501 p2dtest.appendSVGPath(svgpath); 502 Path2D p2dref = new Path2D(); 503 p2dref.moveTo(10, 20); 504 p2dref.lineTo(20, 30); 505 p2dref.lineTo(10, p2dref.getCurrentY()); 506 p2dref.lineTo(p2dref.getCurrentX(), 20); 507 p2dref.quadTo(20, 30, 10, 20); 508 p2dref.curveTo(20, 30, 20, 20, 10, 40); 509 p2dref.quadToSmooth(10, 50); 510 p2dref.curveToSmooth(20, 25, 10, 35); 511 p2dref.arcTo(40, 60, (float) Math.toRadians(10), false, false, 15, 20); 512 p2dref.arcTo(40, 60, (float) Math.toRadians(10), false, true, 25, 30); 513 p2dref.arcTo(40, 60, (float) Math.toRadians(10), true, false, 15, 10); 514 p2dref.arcTo(40, 60, (float) Math.toRadians(10), true, true, 25, 20); 515 p2dref.closePath(); 516 p2dref.moveToRel(10, 20); 517 p2dref.lineToRel(20, 20); 518 p2dref.lineToRel(10, 0); 519 p2dref.lineToRel(0, 20); 520 p2dref.quadToRel(10, 30, 10, 20); 521 p2dref.curveToRel(10, 30, 10, 20, 10, 40); 522 p2dref.quadToSmoothRel(10, 50); 523 p2dref.curveToSmoothRel(10, 25, 10, 35); 524 p2dref.arcToRel(40, 60, (float) Math.toRadians(10), false, false, 10, 20); 525 p2dref.arcToRel(40, 60, (float) Math.toRadians(10), false, true, 10, 20); 526 p2dref.arcToRel(40, 60, (float) Math.toRadians(10), true, false, 10, 20); 527 p2dref.arcToRel(40, 60, (float) Math.toRadians(10), true, true, 10, 20); 528 p2dref.closePath(); 529 checkShapes(p2dref, p2dtest); 530 } 531 532 public @Test 533 void testSVGPathWS() { 534 String svgpathlotsofWS = 535 "M 10, 20 "+ 536 "L 20, 30 "+ 537 "H 10 "+ 538 "V 20 "+ 539 "Q 20, 30 10, 20 "+ 540 "C 20, 30 20, 20 10, 40 "+ 541 "T 10, 50 "+ 542 "S 20, 25 10, 35 "+ 543 "A 40, 60 10 0 0 15, 20 "+ 544 "A 40, 60 10 0 1 25, 30 "+ 545 "A 40, 60 10 1 0 15, 10 "+ 546 "A 40, 60 10 1 1 25, 20 "+ 547 "Z "+ 548 "m 10, 20 "+ 549 "l 20, 20 "+ 550 "h 10 "+ 551 "v 20 "+ 552 "q 10, 30 10, 20 "+ 553 "c 10, 30 10, 20 10, 40 "+ 554 "t 10, 50 "+ 555 "s 10, 25 10 35 "+ 556 "a 40, 60 10 0 0 10, 20 "+ 557 "a 40, 60 10 0 1 10, 20 "+ 558 "a 40, 60 10 1 0 10, 20 "+ 559 "a 40, 60 10 1 1 10, 20 "+ 560 "z"; 561 String svgpathminWS = 562 "M10,20"+ 563 "L20,30"+ 564 "H10"+ 565 "V20"+ 566 "Q20,30,10,20"+ 567 "C20,30,20,20,10,40"+ 568 "T10,50"+ 569 "S20,25,10,35"+ 570 "A40,60,10,0,0,15,20"+ 571 "A40,60,10,0,1,25,30"+ 572 "A40,60,10,1,0,15,10"+ 573 "A40,60,10,1,1,25,20"+ 574 "Z"+ 575 "m10,20"+ 576 "l20,20"+ 577 "h10"+ 578 "v20"+ 579 "q10,30,10,20"+ 580 "c10,30,10,20,10,40"+ 581 "t10,50"+ 582 "s10,25,10,35"+ 583 "a40,60,10,0,0,10,20"+ 584 "a40,60,10,0,1,10,20"+ 585 "a40,60,10,1,0,10,20"+ 586 "a40,60,10,1,1,10,20"+ 587 "z"; 588 Path2D p2dref = new Path2D(); 589 p2dref.appendSVGPath(svgpathlotsofWS); 590 Path2D p2dtest = new Path2D(); 591 p2dtest.appendSVGPath(svgpathminWS); 592 checkShapes(p2dref, p2dtest); 593 } 594 }