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.CubicCurve2D; 30 import com.sun.javafx.geom.Ellipse2D; 31 import com.sun.javafx.geom.Line2D; 32 import com.sun.javafx.geom.Path2D; 33 import com.sun.javafx.geom.QuadCurve2D; 34 import com.sun.javafx.geom.RoundRectangle2D; 35 import com.sun.javafx.geom.Shape; 36 import com.sun.javafx.geom.TransformedShape; 37 import static junit.framework.Assert.assertEquals; 38 import com.sun.javafx.geom.transform.BaseTransform; 39 import org.junit.Test; 40 41 /** 42 * 43 */ 44 public class TransformedShapeTest { 45 // Avoid integer coordinates so that float->double->float roundoff errors 46 // do not end up causing "failures of questionable value" 47 static Shape testShapes[] = { 48 new Arc2D(9.5f, 9.5f, 26.2f, 16.1f, 0, 270, Arc2D.PIE), 49 new Arc2D(9.5f, 9.5f, 26.2f, 16.1f, 0, 270, Arc2D.OPEN), 50 new Arc2D(9.5f, 9.5f, 26.2f, 16.1f, 0, 270, Arc2D.CHORD), 51 new CubicCurve2D(9.5f, 9.5f, 40.5f, 9.5f, 9.5f, 40.5f, 40.5f, 40.5f), 52 new Ellipse2D(9.5f, 9.5f, 21f, 16f), 53 new Line2D(9.5f, 9.5f, 40.5f, 40.5f), 54 makePath(Path2D.WIND_EVEN_ODD), 55 makePath(Path2D.WIND_NON_ZERO), 56 new QuadCurve2D(9.5f, 9.5f, 20.5f, 40.5f, 40.5f, 9.5f), 57 new RoundRectangle2D(9.5f, 9.5f, 21f, 16f, 5f, 5f), 58 }; 59 60 static Shape makePath(int rule) { 61 Path2D p2d = new Path2D(rule); 62 p2d.moveTo(9.5f, 9.5f); 63 p2d.lineTo(20.5f, 9.5f); 64 p2d.quadTo(20.5f, 30.5f, 40.5f, 40.5f); 65 p2d.lineTo(9.5f, 40.5f); 66 p2d.curveTo(30.5f, 30.5f, 20.5f, 10.5f, 40.5f, 10.5f); 67 p2d.lineTo(9.5f, 20.5f); 68 p2d.closePath(); 69 return p2d; 70 } 71 72 static BaseTransform testTransforms[] = { 73 BaseTransform.getTranslateInstance(5.125, 5.75), 74 BaseTransform.getRotateInstance(Math.toRadians(45), 25, 25), 75 BaseTransform.getScaleInstance(0.5, 0.5), 76 BaseTransform.getScaleInstance(1.75, 1.6), 77 }; 78 79 public @Test void testTranslatedShapes() { 80 for (Shape s : testShapes) { 81 test(TransformedShape.translatedShape(s, 5.125, 8.25)); 82 test(TransformedShape.translatedShape(s, -5.25, 8.125)); 83 test(TransformedShape.translatedShape(s, 5.125, -8.25)); 84 test(TransformedShape.translatedShape(s, -5.25, -8.125)); 85 } 86 } 87 88 public @Test void testTransformedShapes() { 89 BaseTransform combinedtx = BaseTransform.IDENTITY_TRANSFORM; 90 for (BaseTransform tx : testTransforms) { 91 test(tx); 92 combinedtx = combinedtx.deriveWithConcatenation(tx); 93 test(combinedtx); 94 } 95 } 96 97 static void test(BaseTransform tx) { 98 for (Shape s : testShapes) { 99 test(TransformedShape.transformedShape(s, tx)); 100 } 101 } 102 103 // Number of ulp to hunt around for a good answer for fuzzy testing 104 static final int FUZZY = 5; 105 106 static void test(TransformedShape s1) { 107 BaseTransform tx = s1.getTransformNoClone(); 108 Shape raws1 = s1.getDelegateNoClone(); 109 Shape s2 = tx.createTransformedShape(raws1); 110 for (int y = 0; y < 50; y++) { 111 for (int x = 0; x < 50; x++) { 112 boolean cp1 = s1.contains(x, y); 113 boolean cp2 = s2.contains(x, y); 114 boolean cr1 = s1.contains(x, y, 1, 1); 115 boolean cr2 = s2.contains(x, y, 1, 1); 116 boolean ir1 = s1.intersects(x, y, 1, 1); 117 boolean ir2 = s2.intersects(x, y, 1, 1); 118 boolean cpfail = (cp1 != cp2); 119 boolean crfail = (cr1 != cr2); 120 boolean irfail = (ir1 != ir2); 121 if (cpfail || crfail || irfail) { 122 Float ulpx = Math.ulp(x); 123 Float ulpy = Math.ulp(y); 124 for (int i = -FUZZY; i <= +FUZZY; i++) { 125 float fy = y + ulpy * i; 126 for (int j = -FUZZY; j <= +FUZZY; j++) { 127 float fx = x + ulpx * j; 128 cpfail = cpfail && (s1.contains(fx, fy) != 129 s2.contains(fx, fy)); 130 crfail = crfail && (s1.contains(fx, fy, 1, 1) != 131 s2.contains(fx, fy, 1, 1)); 132 irfail = irfail && (s1.intersects(fx, fy, 1, 1) != 133 s2.intersects(fx, fy, 1, 1)); 134 } 135 } 136 System.err.println("testing: "+raws1+" transformed by "+tx); 137 if (cpfail) { assertEquals(cp2, cp1); } 138 else if (crfail) { assertEquals(cr2, cr1); } 139 else if (irfail) { assertEquals(ir2, ir1); } 140 else { 141 System.err.println("fuzzy test required for ("+x+", "+y+")"); 142 } 143 } 144 } 145 } 146 } 147 }