/* * 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); } } }