| /* | |
| * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /* | |
| * @test | |
| * @bug 6409478 | |
| * @summary Tests all hit testing methods of GeneralPath and Path2D | |
| * for graceful (i.e. non-infinite-loop) returns when any | |
| * of the path coordinates or test coordinates are | |
| * NaN or Infinite or even very large numbers. | |
| * @run main/timeout=15 NonFiniteTests | |
| */ | |
| import java.awt.geom.GeneralPath; | |
| import java.awt.geom.Path2D; | |
| import java.awt.geom.PathIterator; | |
| public class NonFiniteTests { | |
| public static final double DBL_NaN = Double.NaN; | |
| public static final double DBL_POS_INF = Double.POSITIVE_INFINITY; | |
| public static final double DBL_NEG_INF = Double.NEGATIVE_INFINITY; | |
| public static final double DBL_MAX = Double.MAX_VALUE; | |
| public static final double DBL_MIN = -Double.MAX_VALUE; | |
| public static final double FLT_MAX = Float.MAX_VALUE; | |
| public static final double FLT_MIN = -Float.MAX_VALUE; | |
| public static final int SEG_MOVETO = PathIterator.SEG_MOVETO; | |
| public static final int SEG_LINETO = PathIterator.SEG_LINETO; | |
| public static final int SEG_QUADTO = PathIterator.SEG_QUADTO; | |
| public static final int SEG_CUBICTO = PathIterator.SEG_CUBICTO; | |
| public static final int SEG_CLOSE = PathIterator.SEG_CLOSE; | |
| public static int types[] = { | |
| SEG_MOVETO, | |
| SEG_LINETO, | |
| SEG_QUADTO, | |
| SEG_CUBICTO, | |
| SEG_CLOSE, | |
| }; | |
| public static double coords[] = { | |
| // SEG_MOVETO coords | |
| 0.0, 0.0, | |
| // SEG_LINETO coords | |
| 50.0, 10.0, | |
| // SEG_QUADTO coords | |
| 100.0, 20.0, | |
| 100.0, 100.0, | |
| // SEG_CUBICTO coords | |
| 50.0, 150.0, | |
| 0.0, 100.0, | |
| -50.0, 50.0, | |
| // SEG_CLOSE coords | |
| }; | |
| public static double testpoints[] = { | |
| -100, -100, | |
| 0, 0, | |
| 50, 50, | |
| DBL_NaN, DBL_NaN, | |
| DBL_POS_INF, DBL_POS_INF, | |
| DBL_NEG_INF, DBL_NEG_INF, | |
| DBL_POS_INF, DBL_NEG_INF, | |
| DBL_NEG_INF, DBL_POS_INF, | |
| }; | |
| public static double testrects[] = { | |
| -100, -100, 10, 10, | |
| 0, 0, 10, 10, | |
| 50, 50, 10, 10, | |
| DBL_NaN, DBL_NaN, 10, 10, | |
| 10, 10, DBL_NaN, DBL_NaN, | |
| DBL_NaN, DBL_NaN, DBL_NaN, DBL_NaN, | |
| 10, 10, DBL_POS_INF, DBL_POS_INF, | |
| 10, 10, DBL_NEG_INF, DBL_NEG_INF, | |
| 10, 10, DBL_POS_INF, DBL_NEG_INF, | |
| 10, 10, DBL_NEG_INF, DBL_POS_INF, | |
| DBL_NEG_INF, DBL_NEG_INF, DBL_POS_INF, DBL_POS_INF, | |
| DBL_POS_INF, DBL_POS_INF, 10, 10, | |
| DBL_NEG_INF, DBL_NEG_INF, 10, 10, | |
| DBL_POS_INF, DBL_NEG_INF, 10, 10, | |
| DBL_NEG_INF, DBL_POS_INF, 10, 10, | |
| }; | |
| public static double replacecoords[] = { | |
| DBL_NEG_INF, | |
| DBL_MIN, | |
| FLT_MIN, | |
| DBL_NaN, | |
| FLT_MAX, | |
| DBL_MAX, | |
| DBL_POS_INF, | |
| }; | |
| public static void main(String argv[]) { | |
| test(types, coords); | |
| testNonFinites(types, coords, 2); | |
| } | |
| public static void testNonFinites(int types[], double coords[], | |
| int numvalues) | |
| { | |
| if (numvalues == 0) { | |
| test(types, coords); | |
| return; | |
| } | |
| numvalues--; | |
| for (int i = 0; i < coords.length; i++) { | |
| double savedval = coords[i]; | |
| //System.out.println("replacing coord #"+i); | |
| for (int j = 0; j < replacecoords.length; j++) { | |
| coords[i] = replacecoords[j]; | |
| testNonFinites(types, coords, numvalues); | |
| } | |
| coords[i] = savedval; | |
| } | |
| } | |
| public static void test(int types[], double coords[]) { | |
| testGP(new GeneralPath(), types, coords); | |
| try { | |
| P2DTest.test(types, coords); | |
| } catch (NoClassDefFoundError e) { | |
| // Skip Path2D tests on older runtimes... | |
| } | |
| } | |
| public static void testGP(GeneralPath gp, int types[], double coords[]) { | |
| int ci = 0; | |
| for (int i = 0; i < types.length; i++) { | |
| switch (types[i]) { | |
| case SEG_MOVETO: | |
| gp.moveTo((float) coords[ci++], (float) coords[ci++]); | |
| break; | |
| case SEG_LINETO: | |
| gp.lineTo((float) coords[ci++], (float) coords[ci++]); | |
| break; | |
| case SEG_QUADTO: | |
| gp.quadTo((float) coords[ci++], (float) coords[ci++], | |
| (float) coords[ci++], (float) coords[ci++]); | |
| break; | |
| case SEG_CUBICTO: | |
| gp.curveTo((float) coords[ci++], (float) coords[ci++], | |
| (float) coords[ci++], (float) coords[ci++], | |
| (float) coords[ci++], (float) coords[ci++]); | |
| break; | |
| case SEG_CLOSE: | |
| gp.closePath(); | |
| break; | |
| } | |
| } | |
| testGP(gp); | |
| } | |
| public static void testGP(GeneralPath gp) { | |
| for (int i = 0; i < testpoints.length; i += 2) { | |
| gp.contains(testpoints[i+0], testpoints[i+1]); | |
| } | |
| for (int i = 0; i < testrects.length; i += 4) { | |
| gp.contains(testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| gp.intersects(testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| } | |
| } | |
| public static class P2DTest { | |
| public static void test(int types[], double coords[]) { | |
| testPath(new Path2D.Float(), types, coords); | |
| testPath(new Path2D.Double(), types, coords); | |
| } | |
| public static void testPath(Path2D p2d, int types[], double coords[]) { | |
| int ci = 0; | |
| for (int i = 0; i < types.length; i++) { | |
| switch (types[i]) { | |
| case SEG_MOVETO: | |
| p2d.moveTo(coords[ci++], coords[ci++]); | |
| break; | |
| case SEG_LINETO: | |
| p2d.lineTo(coords[ci++], coords[ci++]); | |
| break; | |
| case SEG_QUADTO: | |
| p2d.quadTo(coords[ci++], coords[ci++], | |
| coords[ci++], coords[ci++]); | |
| break; | |
| case SEG_CUBICTO: | |
| p2d.curveTo(coords[ci++], coords[ci++], | |
| coords[ci++], coords[ci++], | |
| coords[ci++], coords[ci++]); | |
| break; | |
| case SEG_CLOSE: | |
| p2d.closePath(); | |
| break; | |
| } | |
| } | |
| testPath(p2d); | |
| } | |
| public static void testPath(Path2D p2d) { | |
| // contains point | |
| for (int i = 0; i < testpoints.length; i += 2) { | |
| p2d.contains(testpoints[i+0], testpoints[i+1]); | |
| contains(p2d, testpoints[i+0], testpoints[i+1]); | |
| } | |
| for (int i = 0; i < testrects.length; i += 4) { | |
| p2d.contains(testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| contains(p2d, | |
| testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| p2d.intersects(testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| intersects(p2d, | |
| testrects[i+0], testrects[i+1], | |
| testrects[i+2], testrects[i+3]); | |
| } | |
| } | |
| public static boolean contains(Path2D p2d, double x, double y) { | |
| return Path2D.contains(p2d.getPathIterator(null), x, y); | |
| } | |
| public static boolean contains(Path2D p2d, | |
| double x, double y, double w, double h) | |
| { | |
| return Path2D.contains(p2d.getPathIterator(null), x, y, w, h); | |
| } | |
| public static boolean intersects(Path2D p2d, | |
| double x, double y, double w, double h) | |
| { | |
| return Path2D.intersects(p2d.getPathIterator(null), x, y, w, h); | |
| } | |
| } | |
| } |