1 /* 2 * Copyright (c) 2006, 2018, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6409478 27 * @summary Tests all hit testing methods of GeneralPath and Path2D 28 * for graceful (i.e. non-infinite-loop) returns when any 29 * of the path coordinates or test coordinates are 30 * NaN or Infinite or even very large numbers. 31 * @run main/timeout=15 NonFiniteTests 32 */ 33 34 import java.awt.geom.GeneralPath; 35 import java.awt.geom.Path2D; 36 import java.awt.geom.PathIterator; 37 38 public class NonFiniteTests { 39 public static final double DBL_NaN = Double.NaN; 40 public static final double DBL_POS_INF = Double.POSITIVE_INFINITY; 41 public static final double DBL_NEG_INF = Double.NEGATIVE_INFINITY; 42 public static final double DBL_MAX = Double.MAX_VALUE; 43 public static final double DBL_MIN = -Double.MAX_VALUE; 44 public static final double FLT_MAX = Float.MAX_VALUE; 45 public static final double FLT_MIN = -Float.MAX_VALUE; 46 47 public static final int SEG_MOVETO = PathIterator.SEG_MOVETO; 48 public static final int SEG_LINETO = PathIterator.SEG_LINETO; 49 public static final int SEG_QUADTO = PathIterator.SEG_QUADTO; 50 public static final int SEG_CUBICTO = PathIterator.SEG_CUBICTO; 51 public static final int SEG_CLOSE = PathIterator.SEG_CLOSE; 52 53 public static int types[] = { 54 SEG_MOVETO, 55 SEG_LINETO, 56 SEG_QUADTO, 57 SEG_CUBICTO, 58 SEG_CLOSE, 59 }; 60 61 public static double coords[] = { 62 // SEG_MOVETO coords 63 0.0, 0.0, 64 65 // SEG_LINETO coords 66 50.0, 10.0, 67 68 // SEG_QUADTO coords 69 100.0, 20.0, 70 100.0, 100.0, 71 72 // SEG_CUBICTO coords 73 50.0, 150.0, 74 0.0, 100.0, 75 -50.0, 50.0, 76 77 // SEG_CLOSE coords 78 }; 79 80 public static double testpoints[] = { 81 -100, -100, 82 0, 0, 83 50, 50, 84 DBL_NaN, DBL_NaN, 85 DBL_POS_INF, DBL_POS_INF, 86 DBL_NEG_INF, DBL_NEG_INF, 87 DBL_POS_INF, DBL_NEG_INF, 88 DBL_NEG_INF, DBL_POS_INF, 89 }; 90 91 public static double testrects[] = { 92 -100, -100, 10, 10, 93 0, 0, 10, 10, 94 50, 50, 10, 10, 95 DBL_NaN, DBL_NaN, 10, 10, 96 10, 10, DBL_NaN, DBL_NaN, 97 DBL_NaN, DBL_NaN, DBL_NaN, DBL_NaN, 98 10, 10, DBL_POS_INF, DBL_POS_INF, 99 10, 10, DBL_NEG_INF, DBL_NEG_INF, 100 10, 10, DBL_POS_INF, DBL_NEG_INF, 101 10, 10, DBL_NEG_INF, DBL_POS_INF, 102 DBL_NEG_INF, DBL_NEG_INF, DBL_POS_INF, DBL_POS_INF, 103 DBL_POS_INF, DBL_POS_INF, 10, 10, 104 DBL_NEG_INF, DBL_NEG_INF, 10, 10, 105 DBL_POS_INF, DBL_NEG_INF, 10, 10, 106 DBL_NEG_INF, DBL_POS_INF, 10, 10, 107 }; 108 109 public static double replacecoords[] = { 110 DBL_NEG_INF, 111 DBL_MIN, 112 FLT_MIN, 113 DBL_NaN, 114 FLT_MAX, 115 DBL_MAX, 116 DBL_POS_INF, 117 }; 118 main(String argv[])119 public static void main(String argv[]) { 120 test(types, coords); 121 testNonFinites(types, coords, 2); 122 } 123 testNonFinites(int types[], double coords[], int numvalues)124 public static void testNonFinites(int types[], double coords[], 125 int numvalues) 126 { 127 if (numvalues == 0) { 128 test(types, coords); 129 return; 130 } 131 numvalues--; 132 for (int i = 0; i < coords.length; i++) { 133 double savedval = coords[i]; 134 135 //System.out.println("replacing coord #"+i); 136 for (int j = 0; j < replacecoords.length; j++) { 137 coords[i] = replacecoords[j]; 138 testNonFinites(types, coords, numvalues); 139 } 140 141 coords[i] = savedval; 142 } 143 } 144 test(int types[], double coords[])145 public static void test(int types[], double coords[]) { 146 testGP(new GeneralPath(), types, coords); 147 try { 148 P2DTest.test(types, coords); 149 } catch (NoClassDefFoundError e) { 150 // Skip Path2D tests on older runtimes... 151 } 152 } 153 testGP(GeneralPath gp, int types[], double coords[])154 public static void testGP(GeneralPath gp, int types[], double coords[]) { 155 int ci = 0; 156 for (int i = 0; i < types.length; i++) { 157 switch (types[i]) { 158 case SEG_MOVETO: 159 gp.moveTo((float) coords[ci++], (float) coords[ci++]); 160 break; 161 case SEG_LINETO: 162 gp.lineTo((float) coords[ci++], (float) coords[ci++]); 163 break; 164 case SEG_QUADTO: 165 gp.quadTo((float) coords[ci++], (float) coords[ci++], 166 (float) coords[ci++], (float) coords[ci++]); 167 break; 168 case SEG_CUBICTO: 169 gp.curveTo((float) coords[ci++], (float) coords[ci++], 170 (float) coords[ci++], (float) coords[ci++], 171 (float) coords[ci++], (float) coords[ci++]); 172 break; 173 case SEG_CLOSE: 174 gp.closePath(); 175 break; 176 } 177 } 178 testGP(gp); 179 } 180 testGP(GeneralPath gp)181 public static void testGP(GeneralPath gp) { 182 for (int i = 0; i < testpoints.length; i += 2) { 183 gp.contains(testpoints[i+0], testpoints[i+1]); 184 } 185 186 for (int i = 0; i < testrects.length; i += 4) { 187 gp.contains(testrects[i+0], testrects[i+1], 188 testrects[i+2], testrects[i+3]); 189 gp.intersects(testrects[i+0], testrects[i+1], 190 testrects[i+2], testrects[i+3]); 191 } 192 } 193 194 public static class P2DTest { test(int types[], double coords[])195 public static void test(int types[], double coords[]) { 196 testPath(new Path2D.Float(), types, coords); 197 testPath(new Path2D.Double(), types, coords); 198 } 199 testPath(Path2D p2d, int types[], double coords[])200 public static void testPath(Path2D p2d, int types[], double coords[]) { 201 int ci = 0; 202 for (int i = 0; i < types.length; i++) { 203 switch (types[i]) { 204 case SEG_MOVETO: 205 p2d.moveTo(coords[ci++], coords[ci++]); 206 break; 207 case SEG_LINETO: 208 p2d.lineTo(coords[ci++], coords[ci++]); 209 break; 210 case SEG_QUADTO: 211 p2d.quadTo(coords[ci++], coords[ci++], 212 coords[ci++], coords[ci++]); 213 break; 214 case SEG_CUBICTO: 215 p2d.curveTo(coords[ci++], coords[ci++], 216 coords[ci++], coords[ci++], 217 coords[ci++], coords[ci++]); 218 break; 219 case SEG_CLOSE: 220 p2d.closePath(); 221 break; 222 } 223 } 224 testPath(p2d); 225 } 226 testPath(Path2D p2d)227 public static void testPath(Path2D p2d) { 228 // contains point 229 for (int i = 0; i < testpoints.length; i += 2) { 230 p2d.contains(testpoints[i+0], testpoints[i+1]); 231 contains(p2d, testpoints[i+0], testpoints[i+1]); 232 } 233 234 for (int i = 0; i < testrects.length; i += 4) { 235 p2d.contains(testrects[i+0], testrects[i+1], 236 testrects[i+2], testrects[i+3]); 237 contains(p2d, 238 testrects[i+0], testrects[i+1], 239 testrects[i+2], testrects[i+3]); 240 p2d.intersects(testrects[i+0], testrects[i+1], 241 testrects[i+2], testrects[i+3]); 242 intersects(p2d, 243 testrects[i+0], testrects[i+1], 244 testrects[i+2], testrects[i+3]); 245 } 246 } 247 contains(Path2D p2d, double x, double y)248 public static boolean contains(Path2D p2d, double x, double y) { 249 return Path2D.contains(p2d.getPathIterator(null), x, y); 250 } 251 contains(Path2D p2d, double x, double y, double w, double h)252 public static boolean contains(Path2D p2d, 253 double x, double y, double w, double h) 254 { 255 return Path2D.contains(p2d.getPathIterator(null), x, y, w, h); 256 } 257 intersects(Path2D p2d, double x, double y, double w, double h)258 public static boolean intersects(Path2D p2d, 259 double x, double y, double w, double h) 260 { 261 return Path2D.intersects(p2d.getPathIterator(null), x, y, w, h); 262 } 263 } 264 } 265