--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/AffineTransform/QuadRotInverseBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2000, 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 4388199
+ * @summary Tests inverse transform of an array of points with
+ * shearing and translation components in the AffineTransform
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+
+/*
+ * The AffineTransform method
+ * inverseTransform(double[],int,double[],int,int) produces incorrect
+ * results for pure shearing transformations or for shearing and
+ * translation transformations. The simpliest example of which is a
+ * rotation by 90 degrees.
+ */
+public class QuadRotInverseBug {
+ public static void main(String[] args) {
+ // First test a transform which rotates the coordinate system by 90
+ // degrees.
+ System.out.println("Using 90 degree rotation:");
+ AffineTransform xform = AffineTransform.getRotateInstance(Math.PI/2);
+ boolean test1failed = test(xform);
+ // Next test the transform with an added translation component
+ System.out.println("Using 90 degree rotation with translation:");
+ xform.translate(2,2);
+ boolean test2failed = test(xform);
+ if (test1failed || test2failed) {
+ throw new RuntimeException("test failed, see printout");
+ }
+ }
+
+ public static boolean test(AffineTransform xform) {
+ // Make needed arrays.
+ double[] originalPoint = new double[2];
+ double[] transformedPoint = new double[2];
+ double[] inverseFromOriginalXForm = new double[2];
+
+ Point2D originalPoint2D = new Point2D.Double();
+ Point2D transformedPoint2D = new Point2D.Double();
+ Point2D inverseFromOriginalPoint2D = new Point2D.Double();
+
+ // Make the original point to check (x,y)=(1,1).
+ originalPoint[0] = 1.;
+ originalPoint[1] = 1.;
+
+ try {
+
+ originalPoint2D.setLocation(originalPoint[0], originalPoint[1]);
+
+ // Make the transformed point.
+ xform.transform(originalPoint,0,transformedPoint,0,1);
+ xform.transform(originalPoint2D, transformedPoint2D);
+
+ // Transform the point back using the original transformation.
+ xform.inverseTransform(transformedPoint,0,
+ inverseFromOriginalXForm,0,1);
+ xform.inverseTransform(transformedPoint2D,
+ inverseFromOriginalPoint2D);
+ } catch (NoninvertibleTransformException e) {
+ throw new InternalError("transform wasn't invertible!");
+ }
+
+ System.out.println("Both points should be identical:");
+ System.out.println("Original Point: "+
+ originalPoint[0]+" "+
+ originalPoint[1]);
+ System.out.println("inverseTransform method used: "+
+ inverseFromOriginalXForm[0]+" "+
+ inverseFromOriginalXForm[1]);
+ System.out.println("Original Point2D: "+ originalPoint2D);
+ System.out.println("inverseTransform method used: "+
+ inverseFromOriginalPoint2D);
+ return (originalPoint[0] != inverseFromOriginalXForm[0] ||
+ originalPoint[1] != inverseFromOriginalXForm[1] ||
+ !originalPoint2D.equals(inverseFromOriginalPoint2D));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Arc2D/Arc2DIntersectsTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2003, 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 4724569
+ * @summary Arc2D "contains" and "intersects" problems, part II: fix enclosed.
+ */
+
+import java.awt.Shape;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Rectangle2D;
+
+public class Arc2DIntersectsTest {
+
+ static Shape[][] trues = {
+ {
+ new Arc2D.Double(0, 0, 100, 100, -45, 90, Arc2D.PIE),
+ new Rectangle2D.Double(0, 0, 100, 100),
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, -45, 90, Arc2D.PIE),
+ new Rectangle2D.Double(25, 25, 50, 50)
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, -45, 90, Arc2D.PIE),
+ new Rectangle2D.Double(60, 0, 20, 100)
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, -135, 270, Arc2D.CHORD),
+ new Rectangle2D.Double(20, 0, 20, 100)
+ }
+ };
+ static Shape[][] falses = {
+ {
+ new Arc2D.Double(0, 0, 100, 100, 0, 360, Arc2D.PIE),
+ new Rectangle2D.Double(0, 100, 100, 100)
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, 45, 20, Arc2D.PIE),
+ new Rectangle2D.Double(75, 75, 100, 100)
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, -10, 10, Arc2D.PIE),
+ new Rectangle2D.Double(50, 75, 50, 100)
+ },
+ {
+ new Arc2D.Double(0, 0, 100, 100, -10, 10, Arc2D.CHORD),
+ new Rectangle2D.Double(60, 0, 10, 100)
+ }
+ };
+
+ public static void main(String[] args) {
+
+ for (int i = 0; i < trues.length; i++) {
+ checkPair((Arc2D)trues[i][0], (Rectangle2D)trues[i][1], true);
+ }
+
+ for (int i = 0; i < falses.length; i++) {
+ checkPair((Arc2D)falses[i][0], (Rectangle2D)falses[i][1], false);
+ }
+ }
+
+ public static void checkPair(Arc2D arc, Rectangle2D rect, boolean expect) {
+
+ if (arc.intersects(rect) != expect) {
+ String errMsg = "Intersection of Arc(" +
+ arc.getX() + ", " + arc.getY() + ", " +
+ arc.getWidth() + ", " + arc.getHeight() + ", " +
+ "start = " + arc.getAngleStart() + ", " +
+ "extent = " + arc.getAngleExtent() + ", " +
+ typeName(arc.getArcType()) + ") and Rectangle(" +
+ rect.getX() + ", " + rect.getY() + ", " +
+ rect.getWidth() + ", " + rect.getHeight() + ") " +
+ "should be " + expect + ", BUT IT IS NOT.";
+ throw new RuntimeException(errMsg);
+ }
+ }
+
+ public static String typeName(int type) {
+
+ if (type == Arc2D.OPEN)
+ return "Open";
+ if (type == Arc2D.CHORD)
+ return "Chord";
+ if (type == Arc2D.PIE)
+ return "Pie";
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Arc2D/ChordContainsTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 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 4724563
+ * @summary Test the points out of arc to recognize as not containing.
+ */
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.Point2D;
+
+public class ChordContainsTest {
+
+ public void runTest() {
+
+ Arc2D a = new Arc2D.Double(-20, -20, 40, 40, -60, 120, Arc2D.CHORD);
+
+ // this point is surely out of chorded arc,
+ // it's closer to center
+ Point2D p = new Point2D.Double( a.getWidth() / 6, 0);
+
+ if (a.contains(p.getX(), p.getY())) {
+ throw new RuntimeException("Point out of arc recognized as containing");
+ }
+ }
+
+ public static void main(String[] args) {
+ ChordContainsTest test = new ChordContainsTest();
+ test.runTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Arc2D/NotConvexPieTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2003, 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 4725016
+ * @summary Tests the contains() method for not a convex pie with negative ext
+ */
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.Rectangle2D;
+
+public class NotConvexPieTest {
+
+ Arc2D aNegative = new Arc2D.Double(-100, -100, 200, 200,
+ -45, -270, Arc2D.PIE);
+ // this rectangle surely have all vertices inside the
+ // arc above but intersects the pie slices
+ Rectangle2D rect = new Rectangle2D.Double(-20, -40, 40, 80);
+
+ String failText = "Test failed: rect should not be contained in arc due to "
+ + "intersections with radii";
+
+ public void runTest() {
+
+ boolean contains = aNegative.contains(rect.getX(),
+ rect.getY(),
+ rect.getWidth(),
+ rect.getHeight());
+ if (contains) {
+ // test failed
+ throw new RuntimeException(failText);
+ }
+ }
+
+ public static void main(String[] args) {
+ NotConvexPieTest test = new NotConvexPieTest();
+ test.runTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Arc2D/SetAnglesTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003, 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 4724580
+ * @summary Pie slices should be colinear with vectors used to set angles.
+ */
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.Point2D;
+
+public class SetAnglesTest {
+
+ public void runTest() {
+
+ Arc2D arc = new Arc2D.Double(-10, -40, 20, 80, 0, 0, Arc2D.PIE);
+ Point2D p1 = new Point2D.Double(10, 10);
+ Point2D p2 = new Point2D.Double(10, -10);
+ double threshold = 1.0E-10;
+
+ arc.setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+
+ Point2D start = arc.getStartPoint();
+ Point2D end = arc.getEndPoint();
+
+ checkColinear(start.getX(), start.getY(), p1.getX(), p1.getY());
+ checkColinear(end.getX(), end.getY(), p2.getX(), p2.getY());
+ }
+
+ void checkColinear(double dx1, double dy1, double dx2, double dy2) {
+
+ double threshold = 1.0E-10;
+
+ if (!(dx1 * dx2 >= 0 &&
+ dy1 * dy2 >= 0 &&
+ Math.abs(dx1 * dy2 - dx2 * dy1) <= threshold)) {
+ throw new RuntimeException("Angles difference is too much");
+ }
+ }
+
+ public static void main(String[] args) {
+ SetAnglesTest test = new SetAnglesTest();
+ test.runTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Arc2D/SmallExtAngleTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003, 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 4836495
+ * @summary Very small ext angle of arc should not give NaNs in SEG_CUBICTO
+ */
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+
+public class SmallExtAngleTest {
+
+ public static void main(String[] args) {
+
+ String errorMsg = "NaN occured in coordinates of SEG_CUBICTO";
+ Rectangle2D bounds = new Rectangle2D.Double(-100, -100, 200, 200);
+ Arc2D arc = new Arc2D.Double(bounds, 90, -1.0E-7, Arc2D.PIE);
+ double[] coords = new double[6];
+
+ PathIterator p = arc.getPathIterator(null);
+ while (!p.isDone()) {
+
+ if (p.currentSegment(coords) == PathIterator.SEG_CUBICTO) {
+
+ for (int i = 0; i < 6; i++) {
+ if (coords[i] != coords[i]) {
+ throw new RuntimeException(errorMsg);
+ }
+ }
+ }
+ p.next();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/ArcSubtractEllipseBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * 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 6356485
+ * @summary Checks that subtracting a particular ellipse from an Arc
+ * does not cause an InternalError to be thrown.
+ */
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
+
+public class ArcSubtractEllipseBug {
+ public static void main(String[] args) {
+ double x = -4.250000000000002;
+ double y = 0.0;
+ double width = 8.5;
+ double height = 8.5;
+ double start = -450.0;
+ double extent = 180.0;
+
+ Arc2D outerArc = new Arc2D.Double(x, y, width, height,
+ start, extent, Arc2D.PIE);
+
+ Area tmp = new Area(outerArc);
+
+ x = -4.000000000000002;
+ y = 0.25;
+ width = 8.0;
+ height = 8.0;
+
+ Ellipse2D innerArc = new Ellipse2D.Double(x, y, width, height);
+
+ tmp.subtract(new Area(innerArc));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/AreaNaNBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * 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 6398602
+ * @summary Checks that problems finding the roots of curves does not
+ * cause the Area class to end up with NaN coordinates after
+ * being constructed from an otherwise normal and unremarkable
+ * path.
+ */
+
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+
+public class AreaNaNBug {
+ public static void main(String argv[]) {
+ GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+ gp.moveTo(-38.05311f, 75.25694f);
+ gp.curveTo(-48.18971f, 71.23722f,
+ -46.495422f, -113.844574f,
+ 124.16219f, 87.604744f);
+ gp.quadTo(105.644554f, 114.52495f,
+ 72.98282f, -78.52084f);
+ gp.lineTo(107.358795f, 29.33548f);
+ gp.quadTo(-16.562698f, -43.91586f,
+ 51.50203f, 38.51295f);
+ gp.lineTo(20.715876f, 44.4093f);
+ gp.closePath();
+ Area a = new Area(gp);
+ Rectangle2D r2d = a.getBounds2D();
+ if (Double.isNaN(r2d.getX()) ||
+ Double.isNaN(r2d.getY()) ||
+ Double.isNaN(r2d.getWidth()) ||
+ Double.isNaN(r2d.getHeight()))
+ {
+ throw new RuntimeException("Area bounds have NaN");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/AreaTransformTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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 6385010
+ * @summary Checks that transform does not fail with exception
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+
+/* Minimized testcase from bug report */
+
+public class AreaTransformTest {
+
+ public static void main(String[] args) {
+ AffineTransform t = AffineTransform.getRotateInstance(Math.PI/8);
+ GeneralPath path = new GeneralPath();
+
+ path.moveTo(-4516.23223633003f,10983.71557514126f);
+ path.lineTo(-1451.4908513919768f, 13100.559659959084f);
+ path.quadTo(-54.38163118565376f, 13679.261247085042f,
+ 1470.6331984752403f, 13679.261247085042f);
+ path.closePath();
+
+ Area area = new Area(path);
+
+ for (int i = 0; i < 8; i++) {
+ area.transform(t);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/BoundsCache.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999, 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 4188529 4240423
+ * @summary Verifies that the Area methods do not cache the bounds
+ * across operations.
+ */
+
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
+
+public class BoundsCache {
+
+ public static void main(String s[]) {
+ Ellipse2D cir = new Ellipse2D.Double(110.0,100.0, 50.0, 50.0);
+ Ellipse2D cir2 = new Ellipse2D.Double(110.0,100.0, 50.0, 50.0);
+ Area area_cir = new Area (cir);
+
+ System.out.println("before operation (bounds should be non-empty):");
+ System.out.println(" bounds are "+area_cir.getBounds());
+ System.out.println(" 2D bounds are "+area_cir.getBounds2D());
+ System.out.println(" isEmpty returns "+area_cir.isEmpty());
+ area_cir.subtract(new Area (cir2));
+ System.out.println("after operation (bounds should be empty):");
+ System.out.println(" bounds are "+area_cir.getBounds());
+ System.out.println(" 2D bounds are "+area_cir.getBounds2D());
+ System.out.println(" isEmpty returns "+area_cir.isEmpty());
+ if (!area_cir.isEmpty() ||
+ !area_cir.getBounds().isEmpty() ||
+ !area_cir.getBounds2D().isEmpty())
+ {
+ throw new RuntimeException("result was not empty!");
+ }
+
+ Area area = new Area(cir);
+ area.getBounds();
+ area.reset();
+ if (!area.getBounds().isEmpty()) {
+ throw new RuntimeException("result was not empty!");
+ }
+
+ area = new Area(cir);
+ Rectangle r = area.getBounds();
+ area.transform(new AffineTransform(1, 0, 0, 1, 10, 0));
+ if (area.getBounds().equals(r)) {
+ throw new RuntimeException("bounds not updated in transform!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/EqualsNull.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1999, 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 4245905
+ * @summary Verifies that the Area.equals(null) returns false
+ */
+
+import java.awt.geom.Area;
+
+public class EqualsNull {
+ public static void main(String argv[]) {
+ if (new Area().equals(null)) {
+ throw new RuntimeException("Area object equaled null");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/NPETests.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005, 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 6304542
+ * @summary Verifies that various Area methods throw NPE for null arguments
+ */
+
+import java.awt.geom.Area;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+public class NPETests {
+ static boolean verbose;
+ static int numfailures = 0;
+
+ public static void main(String argv[]) {
+ verbose = (argv.length > 0);
+ test(new Runnable() {
+ public void run() { new Area(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().add(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().subtract(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().intersect(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().exclusiveOr(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().transform(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().createTransformedArea(null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().contains((Point2D) null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().contains((Rectangle2D) null); }
+ });
+ test(new Runnable() {
+ public void run() { new Area().intersects((Rectangle2D) null); }
+ });
+ if (numfailures > 0) {
+ throw new RuntimeException(numfailures+
+ " methods failed to throw NPE");
+ }
+ }
+
+ public static void test(Runnable r) {
+ try {
+ r.run();
+ numfailures++;
+ if (verbose) {
+ new RuntimeException(r+" failed to throw NPE")
+ .printStackTrace();
+ }
+ } catch (NullPointerException e) {
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/PolygonAdd.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999, 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 4286894
+ * @summary Verifies that a particular case of Polygon addition
+ * correctly calculates the ordering of the Polygon edges.
+ */
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+
+public class PolygonAdd {
+ public static void main(String argv[]) {
+ // Original shapes: 4 touching rectangles
+ // (area works correctly with them if not transformed)
+ Shape b = new Rectangle(0,0,100,10);
+ Shape t = new Rectangle(0,90,100,10);
+ Shape l = new Rectangle(0,10,10,80);
+ Shape r = new Rectangle(90,10,10,80);
+
+ // Create a transform to rotate them by 10 degrees
+ AffineTransform M = new AffineTransform();
+ M.translate(-50,-50);
+ M.scale(3,3);
+ M.rotate(Math.toRadians(10));
+ M.translate(70,40);
+
+ Area area = new Area();
+ area.add(new Area(M.createTransformedShape(b)));
+ area.add(new Area(M.createTransformedShape(l)));
+ area.add(new Area(M.createTransformedShape(t)));
+ area.add(new Area(M.createTransformedShape(r)));
+
+ if (!area.contains(295, 145, 5, 5)) {
+ throw new RuntimeException("Area addition failed!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/PolygonSubtract.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1999, 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 4217589
+ * @summary Verifies that a particular case of Polygon subtraction
+ * correctly calculates the ordering of the Polygon edges.
+ */
+
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+
+public class PolygonSubtract {
+ public static void main(String argv[]) {
+ Area area = new Area();
+
+ GeneralPath ring1 = new GeneralPath();
+
+ ring1.moveTo(0, 45);
+ ring1.lineTo(90, 0);
+ ring1.lineTo(60, -45);
+ ring1.lineTo(-60, -45);
+ ring1.lineTo(-90, 0);
+
+ ring1.closePath();
+
+ area.add(new Area(ring1));
+
+ GeneralPath ring2 = new GeneralPath();
+
+ ring2.moveTo(0, 20);
+ ring2.lineTo(100, 0);
+ ring2.lineTo(30, -20);
+ ring2.lineTo(-30, -20);
+ ring2.lineTo(-100, 0);
+ ring2.closePath();
+
+ area.subtract(new Area(ring2));
+
+ if (!area.contains(50, 13, 2, 2)) {
+ throw new RuntimeException("Area subtraction failed!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/QuadCurveOOMBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,340 @@
+/*
+ * 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 6372340
+ * @summary Checks for infinite loop and OOM bugs dealing with Quad curves.
+ * @run main/timeout=20/othervm QuadCurveOOMBug
+ */
+
+import java.awt.Shape;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class QuadCurveOOMBug {
+ public static final String SEG_CLOSE = " SEG_CLOSE";
+ public static final String SEG_CUBICTO = " SEG_CUBICTO";
+ public static final String SEG_LINETO = " SEG_LINETO";
+ public static final String SEG_MOVETO = " SEG_MOVETO";
+ public static final String SEG_QUADTO = " SEG_QUADTO";
+
+ public static final byte[] strokedLineToSubtract = {
+ 0, 11, 32, 83, 69, 71, 95, 77, 79, 86,
+ 69, 84, 79, 68, 117, 7, -63, 67, 15, 6,
+ 87, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 117, 31, 16, 67, 15,
+ 23, 5, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 117, 68, -12, 67,
+ 15, 50, 54, 68, 117, 103, 16, 67, 15, 50,
+ 59, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 117, 110, 14, 67, 15,
+ 50, 59, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 117, -56, 26, 67,
+ 15, 48, -15, 68, 118, 22, 75, 67, 14, 112,
+ 95, 0, 11, 32, 83, 69, 71, 95, 81, 85,
+ 65, 68, 84, 79, 68, 118, 61, 115, 67, 14,
+ 15, 10, 68, 118, 94, 93, 67, 13, 127, -74,
+ 0, 11, 32, 83, 69, 71, 95, 76, 73, 78,
+ 69, 84, 79, 68, 118, 103, -80, 67, 13, 87,
+ 15, 0, 11, 32, 83, 69, 71, 95, 81, 85,
+ 65, 68, 84, 79, 68, 118, 21, -76, 67, 14,
+ -81, -105, 68, 117, -100, -84, 67, 14, -72, 72,
+ 0, 11, 32, 83, 69, 71, 95, 76, 73, 78,
+ 69, 84, 79, 68, 117, -88, 84, 67, 14, -72,
+ 72, 0, 11, 32, 83, 69, 71, 95, 81, 85,
+ 65, 68, 84, 79, 68, 117, 108, 85, 67, 14,
+ -73, 106, 68, 117, 53, 117, 67, 14, 74,
+ -61, 0, 11, 32, 83, 69, 71, 95, 76, 73, 78,
+ 69, 84, 79, 68, 117, 72, 27, 67, 14, 112,
+ 14, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 118, 87, -51, 67, 5,
+ -16, 100, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 118, 69, 39, 67,
+ 5, -53, 25, 0, 11, 32, 83, 69, 71, 95,
+ 81, 85, 65, 68, 84, 79, 68, 117, -5, -93,
+ 67, 5, 57, 38, 68, 117, -88, 84, 67, 5,
+ 56, 72, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 117, -100, -84, 67,
+ 5, 56, 72, 0, 11, 32, 83, 69, 71, 95,
+ 81, 85, 65, 68, 84, 79, 68, 117, 12, 86,
+ 67, 5, 64, -7, 68, 116, -89, -76, 67,
+ 6, -22, -51, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 116, -98, 97, 67,
+ 7, 19, 116, 0, 11, 32, 83, 69, 71, 95,
+ 81, 85, 65, 68, 84, 79, 68, 116, -75, -100,
+ 67, 6, -83, -7, 68, 116, -44, -9, 67, 6,
+ 95, -59, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 117, 26, -119, 67,
+ 5, -76, 14, 68, 117, 110, 14, 67, 5, -78,
+ 59, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 117, 103, 16, 67, 5,
+ -78, 59, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 117, 122, -71, 67,
+ 5, -78, 22, 68, 117, -119, -60, 67, 5, -68,
+ -61, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 117, 114, 117, 67, 5,
+ -84, 21, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 117, 7, -63, 67,
+ 15, 6, 87, 0, 10, 32, 83, 69, 71, 95,
+ 67, 76, 79, 83, 69,
+ };
+
+ public static final byte[] negSpace = {
+ 0, 11, 32, 83, 69, 71, 95, 77, 79, 86,
+ 69, 84, 79, 68, 116, -33, -12, 67, 4, 30,
+ -23, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 118, 59, 73, 67, 6,
+ -43, -109, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 117, 100, -97, 67,
+ 13, -118, -32, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 116, 9, 75,
+ 67, 10, -44, 54, 0, 10, 32, 83, 69, 71,
+ 95, 67, 76, 79, 83, 69,
+ };
+
+ public static final byte[] strokedLineToAdd = {
+ 0, 11, 32, 83, 69, 71, 95, 77, 79, 86,
+ 69, 84, 79, 68, 98, -100, -76, 67, -85, -36,
+ 6, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 98, -76, 4, 67, -85,
+ -48, 21, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 98, -102, -29, 67,
+ -85, -36, -5, 68, 98, -112, 107, 67, -85,
+ -35, 5, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 98, -84, 99, 67, -85,
+ -35, 5, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 98, -87, 1, 67,
+ -85, -35, 1, 68, 98, -107, -10, 67, -85, -43,
+ 23, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 98, -95, -98, 67, -85,
+ -39, -11, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 98, -53, -8, 67,
+ -85, -21, -99, 68, 98, -10, -6, 67, -85,
+ -21, -95, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 99, 2, -94, 67, -85,
+ -21, -95, 0, 11, 32, 83, 69, 71, 95, 81,
+ 85, 65, 68, 84, 79, 68, 98, -56, -104, 67,
+ -85, -21, 61, 68, 98, -109, 28, 67, -85, -73,
+ -35, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 98, -91, -62, 67, -85,
+ -55, -22, 0, 11, 32, 83, 69, 71, 95, 76,
+ 73, 78, 69, 84, 79, 68, 99, -82, -62, 67,
+ -89, -125, 126, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 99, -100, 28,
+ 67, -89, 113, 113, 0, 11, 32, 83, 69, 71,
+ 95, 81, 85, 65, 68, 84, 79, 68, 99, 83,
+ -6, 67, -89, 44, 5, 68, 99, 2, -94, 67,
+ -89, 43, -95, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 98, -10, -6,
+ 67, -89, 43, -95, 0, 11, 32, 83, 69, 71,
+ 95, 81, 85, 65, 68, 84, 79, 68, 99, 10,
+ -82, 67, -89, 43, -91, 68, 99, 29, -72, 67,
+ -89, 51, -113, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 99, 18, 16,
+ 67, -89, 46, -79, 0, 11, 32, 83, 69, 71,
+ 95, 81, 85, 65, 68, 84, 79, 68, 98, -25,
+ -73, 67, -89, 29, 9, 68, 98, -84, 99, 67,
+ -89, 29, 5, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 98, -112, 107,
+ 67, -89, 29, 5, 0, 11, 32, 83, 69, 71,
+ 95, 81, 85, 65, 68, 84, 79, 68, 98, 78,
+ 121, 67, -89, 28, -15, 68, 98, 29, -110, 67,
+ -89, 53, -27, 0, 11, 32, 83, 69, 71, 95,
+ 76, 73, 78, 69, 84, 79, 68, 98, 6, 66,
+ 67, -89, 65, -42, 0, 11, 32, 83, 69, 71,
+ 95, 76, 73, 78, 69, 84, 79, 68, 98, -100,
+ -76, 67, -85, -36, 6, 0, 10, 32, 83, 69,
+ 71, 95, 67, 76, 79, 83, 69,
+ };
+
+ public static final byte[] shapeAdded = {
+ 0, 11, 32, 83, 69, 71, 95, 77, 79, 86,
+ 69, 84, 79, 68, 102, 54, -63, 67, -84, -102,
+ 29, 0, 11, 32, 83, 69, 71, 95, 76, 73, 78,
+ 69, 84, 79, 68, 96, -120, 114, 67, -94,
+ 2, 48, 0, 11, 32, 83, 69, 71, 95, 76, 73,
+ 78, 69, 84, 79, 68, 94, -119, 0, 67,
+ -86, 67, -25, 0, 10, 32, 83, 69, 71, 95,
+ 67, 76, 79, 83, 69,
+ };
+
+ public static void main(String[] args) {
+ // Reversing the order of these try blocks has no effect.
+ try {
+ testAdd();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ try {
+ testSubtract();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void testSubtract() throws IOException
+ {
+ Shape lineShape = loadShape(strokedLineToSubtract, "Line");
+ Shape negShape = loadShape(negSpace, "Space");
+ Area lineArea = new Area(lineShape);
+ Area negArea = new Area(negShape);
+ System.err.println("Attempting to subtract ... ");
+ lineArea.subtract(negArea); // This is what throws the OutOfMemoryError
+ System.err.println("Subtraction succeeded.");
+ }
+
+ private static void testAdd() throws IOException
+ {
+ Shape lineShape = loadShape(strokedLineToAdd, "Line");
+ Shape negShape = loadShape(shapeAdded, "Space");
+ Area lineArea = new Area(lineShape);
+ Area negArea = new Area(negShape);
+ System.err.println("Attempting to add ... ");
+ lineArea.add(negArea); // This is what throws the OutOfMemoryError
+ System.err.println("Addition succeeded.");
+ }
+
+ /**
+ * Although this method isn't used by this test case, this is the method
+ * used to create the two data sets that the test case uses.
+ * @param name The name to give to the variable
+ * @param shape
+ */
+ public static void saveShapeData(Shape shape, String name)
+ {
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ DataOutputStream os = new DataOutputStream(byteStream);
+ try {
+ saveShapeToStream(shape, os);
+ System.out.println("\npublic static final byte[] " +
+ name + " = {\n");
+ byte[] data = byteStream.toByteArray();
+ int ii=0;
+ for (byte bt : data)
+ System.out.print(" " + Byte.toString(bt) + "," +
+ ((++ii)%20==0? "\n":""));
+ System.out.println("};");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void saveShapeToStream(Shape shape, DataOutputStream pOs)
+ throws IOException
+ {
+ PathIterator iter = shape.getPathIterator(null);
+ float[] coords = new float[6];
+ while(!iter.isDone()) {
+ int type = iter.currentSegment(coords);
+ switch(type) {
+ case PathIterator.SEG_CLOSE:
+ pOs.writeUTF(SEG_CLOSE);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ pOs.writeUTF(SEG_CUBICTO);
+ for (float coord : coords)
+ pOs.writeFloat(coord);
+ break;
+ case PathIterator.SEG_LINETO:
+ pOs.writeUTF(SEG_LINETO);
+ pOs.writeFloat(coords[0]);
+ pOs.writeFloat(coords[1]);
+ break;
+ case PathIterator.SEG_MOVETO:
+ pOs.writeUTF(SEG_MOVETO);
+ pOs.writeFloat(coords[0]);
+ pOs.writeFloat(coords[1]);
+ break;
+ case PathIterator.SEG_QUADTO:
+ pOs.writeUTF(SEG_QUADTO);
+ for (int ii=0; ii<4; ++ii)
+ pOs.writeFloat(coords[ii]);
+ break;
+ default:
+ System.err.print(" UNKNOWN:" + type);
+ break;
+ }
+ iter.next();
+ }
+ }
+
+
+ public static Shape loadShape(byte[] fileData, String name)
+ throws IOException
+ {
+ System.out.println("\n\n" + name + ":");
+ GeneralPath path = new GeneralPath();
+ path.setWindingRule(GeneralPath.WIND_NON_ZERO);
+ DataInputStream is=null;
+ is = new DataInputStream(new ByteArrayInputStream(fileData));
+ float[] coords = new float[6];
+ while (is.available()>0)
+ {
+ String type = is.readUTF();
+ System.out.print("\n" + type + "\n ");
+ if (type.equals(SEG_CLOSE)) {
+ path.closePath();
+ } else if (type.equals(SEG_CUBICTO)) {
+ for (int ii=0; ii<6; ++ii)
+ coords[ii] = readFloat(is);
+ path.curveTo(coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5]);
+ } else if (type.equals(SEG_LINETO)) {
+ for (int ii=0; ii<2; ++ii)
+ coords[ii] = readFloat(is);
+ path.lineTo(coords[0], coords[1]);
+ } else if (type.equals(SEG_MOVETO)) {
+ for (int ii=0; ii<2; ++ii)
+ coords[ii] = readFloat(is);
+ path.moveTo(coords[0], coords[1]);
+ } else if (type.equals(SEG_QUADTO)) {
+ for (int ii=0; ii<4; ++ii)
+ coords[ii] = readFloat(is);
+ path.quadTo(coords[0], coords[1], coords[2], coords[3]);
+ }
+ }
+ return path;
+ }
+
+ /**
+ * This call reads all the float values and prints them out.
+ * @param is
+ * @return
+ * @throws IOException
+ */
+ private static float readFloat(DataInputStream is) throws IOException
+ {
+ float ft = is.readFloat();
+ System.out.print("" + ft + ", ");
+ return ft;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/TightBBox.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1999, 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 4276812
+ * @summary Verifies that the Area.getBounds2D() method returns a very tight
+ * bounding box
+ */
+
+import java.awt.geom.Area;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.awt.geom.Rectangle2D;
+
+public class TightBBox {
+ public static void main(String argv[]) {
+ Point2D points[] = {
+ new Point2D.Double(0.0, 0.0),
+ new Point2D.Double(1.0, 0.0),
+ new Point2D.Double(1.0, 1.0),
+ new Point2D.Double(0.0, 1.0),
+ };
+ for (int i = 0; i < 4; i++) {
+ testCubic(points);
+ testQuad(points);
+ testLines(points);
+ rotate(points);
+ }
+ }
+
+ public static void testCubic(Point2D points[]) {
+ CubicCurve2D cubic =
+ new CubicCurve2D.Double(points[0].getX(), points[0].getY(),
+ points[1].getX(), points[1].getY(),
+ points[2].getX(), points[2].getY(),
+ points[3].getX(), points[3].getY());
+ Area a = new Area(cubic);
+ if (!cubic.getBounds2D().contains(a.getBounds2D())) {
+ throw new RuntimeException("Area bbox is larger than cubic");
+ }
+ double x = (points[0].getX() +
+ (points[1].getX() + points[2].getX()) * 3.0 +
+ points[3].getX()) / 8.0;
+ double y = (points[0].getY() +
+ (points[1].getY() + points[2].getY()) * 3.0 +
+ points[3].getY()) / 8.0;
+ Rectangle2D r =
+ new Rectangle2D.Double(points[0].getX(), points[0].getY(), 0, 0);
+ r.add(points[3].getX(), points[3].getY());
+ r.add(x, y);
+ checkBox(r, a.getBounds2D());
+ }
+
+ public static void testQuad(Point2D points[]) {
+ QuadCurve2D quad =
+ new QuadCurve2D.Double(points[0].getX(), points[0].getY(),
+ (points[1].getX() + points[2].getX()) / 2.0,
+ (points[1].getY() + points[2].getY()) / 2.0,
+ points[3].getX(), points[3].getY());
+ Area a = new Area(quad);
+ if (!quad.getBounds2D().contains(a.getBounds2D())) {
+ throw new RuntimeException("Area bbox is larger than quad");
+ }
+ // p0 + 2cp + p1 == p0 + 2(cp0+cp1)/2 + p1 == p0 + cp0 + cp1 + p1
+ double x = (points[0].getX() +
+ points[1].getX() + points[2].getX() +
+ points[3].getX()) / 4.0;
+ double y = (points[0].getY() +
+ points[1].getY() + points[2].getY() +
+ points[3].getY()) / 4.0;
+ Rectangle2D r =
+ new Rectangle2D.Double(points[0].getX(), points[0].getY(), 0, 0);
+ r.add(points[3].getX(), points[3].getY());
+ r.add(x, y);
+ checkBox(r, a.getBounds2D());
+ }
+
+ public static void testLines(Point2D points[]) {
+ GeneralPath gp = new GeneralPath();
+ gp.moveTo((float) points[0].getX(), (float) points[0].getY());
+ gp.lineTo((float) points[2].getX(), (float) points[2].getY());
+ gp.lineTo((float) points[1].getX(), (float) points[1].getY());
+ gp.lineTo((float) points[3].getX(), (float) points[3].getY());
+ gp.closePath();
+ Area a = new Area(gp);
+ if (!gp.getBounds2D().contains(a.getBounds2D())) {
+ throw new RuntimeException("Area bbox is larger than poly");
+ }
+ Rectangle2D r =
+ new Rectangle2D.Double(points[3].getX(), points[3].getY(), 0, 0);
+ for (int i = 0; i < 3; i++) {
+ r.add(points[i].getX(), points[i].getY());
+ }
+ checkBox(r, a.getBounds2D());
+ }
+
+ public static void checkBox(Rectangle2D r1, Rectangle2D r2) {
+ checkVal(r1.getMinX(), r2.getMinX());
+ checkVal(r1.getMinY(), r2.getMinY());
+ checkVal(r2.getMaxX(), r1.getMaxX());
+ checkVal(r2.getMaxY(), r1.getMaxY());
+ }
+
+ /*
+ * v1 and v2 should be roughly equal. The amount of computation
+ * involved in calculating bounding boxes is complex enough that
+ * you might expect the values to be slightly off and this should
+ * perhaps be a loose comparison, but our runtime seems to produce
+ * values that are exactly equal (even with double arithmetic),
+ * so this test will enforce exact equality for now.
+ */
+ public static void checkVal(double v1, double v2) {
+ if (v1 != v2) {
+ throw new RuntimeException("bounding box not minimal");
+ }
+ }
+
+ public static void rotate(Point2D[] points) {
+ Point2D p = points[0];
+ System.arraycopy(points, 1, points, 0, 3);
+ points[3] = p;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Area/TransformPrecision.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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 4632108
+ * @summary Verifies that the Area transform methods maintain double precision
+ */
+
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+
+public class TransformPrecision {
+ public static void main(String argv[]) {
+ int x = 1 << 27;
+ int y = 1 << 26;
+
+ AffineTransform tx = AffineTransform.getTranslateInstance(x, y);
+ AffineTransform untx = AffineTransform.getTranslateInstance(-x, -y);
+
+ Rectangle r = new Rectangle(10, 10, 20, 20);
+ Area a = new Area(r);
+
+ Area b = new Area(r);
+ b.transform(tx);
+ b.transform(untx);
+ if (!a.equals(b)) {
+ throw new RuntimeException("large translation hurt precision!");
+ }
+
+ b = a.createTransformedArea(tx);
+ b = b.createTransformedArea(untx);
+ if (!a.equals(b)) {
+ throw new RuntimeException("large translation hurt precision!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/CubicCurve2D/ContainsHang.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1999, 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 4246661
+ * @summary Verifies that the CubicCurve2D.contains method does not hang
+ * @run main/timeout=5 ContainsHang
+ */
+
+import java.awt.geom.CubicCurve2D;
+
+public class ContainsHang {
+ public static void main(String args[]) {
+ CubicCurve2D curve =
+ new CubicCurve2D.Double(83.0, 101.0,
+ -5.3919918959078075, 94.23530547506019,
+ 71.0, 39.0,
+ 122.0, 44.0);
+
+ System.out.println("Checking contains() >>>");
+ curve.contains(71.0, 44.0);
+ System.out.println("Check complete!!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/CubicCurve2D/ContainsPoint.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * 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 6396047
+ * @summary tests the CubicCurve2D.contains(x, y) method
+ */
+
+import java.awt.geom.CubicCurve2D;
+
+public class ContainsPoint {
+ public static void main(String args[]) {
+ CubicCurve2D curve =
+ new CubicCurve2D.Double(100.0, 100.0,
+ 200.0, 100.0,
+ 200.0, 200.0,
+ 100.0, 200.0);
+ if (curve.contains(0.0, 100.0)) {
+ throw new RuntimeException("contains point clearly "+
+ "outside of curve");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/EqualsHashcode.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2005, 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 6210287
+ * @summary Verifies that the various utility shapes implement
+ * the equals(Object) and hashCode methods adequately
+ */
+
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.util.Vector;
+
+public class EqualsHashcode {
+ public static final int NUMTESTS = 1000;
+
+ public static void main(String argv[]) {
+ new FloatRectangleTester().test();
+ new DoubleRectangleTester().test();
+
+ new FloatEllipseTester().test();
+ new DoubleEllipseTester().test();
+
+ new FloatArcTester().test();
+ new DoubleArcTester().test();
+
+ new FloatRoundRectTester().test();
+ new DoubleRoundRectTester().test();
+ }
+
+ /**
+ * Base utility class for random parameters for testing
+ */
+ public static abstract class Val {
+ protected String name;
+
+ protected Val(String name) {
+ this.name = name;
+ }
+
+ public abstract Object save();
+ public abstract void restore(Object save);
+
+ public abstract void randomize();
+ public abstract void perturb();
+ }
+
+ /**
+ * Base subclass for parameters with "special" values (Infinity, NaN, etc.)
+ */
+ public static abstract class SpecialVal extends Val {
+ protected SpecialVal(String name) {
+ super(name);
+ }
+
+ public abstract void setSpecial();
+
+ public abstract boolean isNaN();
+ }
+
+ /**
+ * Floating point parameter
+ */
+ public static class FloatVal extends SpecialVal {
+ private float v;
+
+ public FloatVal(String name) {
+ super(name);
+ }
+
+ public float getVal() {
+ return v;
+ }
+
+ public String toString() {
+ return name+" = "+v+" (flt)";
+ }
+
+ public Object save() {
+ return new Float(v);
+ }
+
+ public void restore(Object o) {
+ v = ((Float) o).floatValue();
+ }
+
+ public void randomize() {
+ v = (float) (Math.random() * 100);
+ }
+
+ public void perturb() {
+ v = v + 1;
+ }
+
+ public boolean hasSpecialCases() {
+ return true;
+ }
+
+ public void setSpecial() {
+ switch ((int) (Math.random() * 3)) {
+ case 0:
+ v = Float.NaN;
+ break;
+ case 1:
+ v = Float.POSITIVE_INFINITY;
+ break;
+ case 2:
+ v = Float.NEGATIVE_INFINITY;
+ break;
+ default:
+ throw new InternalError();
+ }
+ }
+
+ public boolean isNaN() {
+ return (v != v);
+ }
+ }
+
+ /**
+ * Double precision parameter
+ */
+ public static class DoubleVal extends SpecialVal {
+ private double v;
+
+ public DoubleVal(String name) {
+ super(name);
+ }
+
+ public double getVal() {
+ return v;
+ }
+
+ public String toString() {
+ return name+" = "+v+" (dbl)";
+ }
+
+ public Object save() {
+ return new Double(v);
+ }
+
+ public void restore(Object o) {
+ v = ((Double) o).doubleValue();
+ }
+
+ public void randomize() {
+ v = Math.random() * 100;
+ }
+
+ public void perturb() {
+ v = v + 1;
+ }
+
+ public boolean hasSpecialCases() {
+ return true;
+ }
+
+ public void setSpecial() {
+ switch ((int) (Math.random() * 3)) {
+ case 0:
+ v = Double.NaN;
+ break;
+ case 1:
+ v = Double.POSITIVE_INFINITY;
+ break;
+ case 2:
+ v = Double.NEGATIVE_INFINITY;
+ break;
+ default:
+ throw new InternalError();
+ }
+ }
+
+ public boolean isNaN() {
+ return (v != v);
+ }
+ }
+
+ /**
+ * Integer value with a specified min/max range.
+ */
+ public static class IntRangeVal extends Val {
+ public int v;
+ public int min;
+ public int max;
+
+ public IntRangeVal(String name, int min, int max) {
+ super(name);
+ this.min = min;
+ this.max = max;
+ }
+
+ public int getVal() {
+ return v;
+ }
+
+ public String toString() {
+ return name+" = "+v;
+ }
+
+ public Object save() {
+ return new Integer(v);
+ }
+
+ public void restore(Object o) {
+ v = ((Integer) o).intValue();
+ }
+
+ public void randomize() {
+ v = min + (int) (Math.random() * (max-min+1));
+ }
+
+ public void perturb() {
+ v = v + 1;
+ if (v > max) {
+ v = min;
+ }
+ }
+ }
+
+ /**
+ * Base class for testing a given type of shape.
+ * Subclasses must register all of their "parameters" which
+ * need to be randomized, specialized, and perturbed for
+ * testing.
+ * Subclasses must also implement makeShape() which makes
+ * a new shape object according to the current values of
+ * all of their parameters.
+ */
+ public static abstract class ShapeTester {
+ public Vector params = new Vector();
+
+ public void addParam(Val v) {
+ params.add(v);
+ }
+
+ public Val[] getParamArray() {
+ Val ret[] = new Val[params.size()];
+ for (int i = 0; i < params.size(); i++) {
+ ret[i] = (Val) params.get(i);
+ }
+ return ret;
+ }
+
+ public void error(String desc) {
+ Val params[] = getParamArray();
+ for (int j = 0; j < params.length; j++) {
+ System.err.println(params[j]);
+ }
+ throw new RuntimeException(desc);
+ }
+
+ public abstract Object makeShape();
+
+ public void test() {
+ Val params[] = getParamArray();
+ for (int i = 0; i < NUMTESTS; i++) {
+ // First, randomize all parameters
+ for (int j = 0; j < params.length; j++) {
+ params[j].randomize();
+ }
+
+ // Now make 2 copies from the same params and verify equals()
+ Object o1 = makeShape();
+ if (!o1.equals(o1)) {
+ error("Shapes not equal to itself!");
+ }
+ Object o2 = makeShape();
+ if (!o1.equals(o2)) {
+ error("Identical shapes not equal!");
+ }
+ if (o1.hashCode() != o2.hashCode()) {
+ error("Identical hashes not equal!");
+ }
+
+ // Now perturb the params 1 by 1 and verify !equals()
+ for (int j = 0; j < params.length; j++) {
+ Val param = params[j];
+ Object save = param.save();
+
+ param.perturb();
+ Object o3 = makeShape();
+ if (o1.equals(o3)) {
+ error("Perturbed shape still equal!");
+ }
+
+ // If param has "special values", test them as well
+ if (param instanceof SpecialVal) {
+ SpecialVal sparam = (SpecialVal) param;
+ sparam.setSpecial();
+ Object o4 = makeShape();
+ if (o1.equals(o4)) {
+ error("Specialized shape still equal!");
+ }
+ Object o5 = makeShape();
+ // objects equal iff param is not a NaN
+ if (o4.equals(o5) == sparam.isNaN()) {
+ error("Identical specialized shapes not equal!");
+ }
+ // hash codes always equal, even if NaN
+ // (Note: equals()/hashCode() contract allows this)
+ if (o4.hashCode() != o5.hashCode()) {
+ error("Identical specialized hashes not equal!");
+ }
+ }
+
+ // Restore original value of param and make sure
+ param.restore(save);
+ Object o6 = makeShape();
+ if (!o1.equals(o6)) {
+ error("Restored shape not equal!");
+ }
+ if (o1.hashCode() != o6.hashCode()) {
+ error("Restored hash not equal!");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Base tester class for objects with floating point xywh bounds
+ */
+ public static abstract class FloatBoundedShape extends ShapeTester {
+ public FloatVal x = new FloatVal("x");
+ public FloatVal y = new FloatVal("y");
+ public FloatVal w = new FloatVal("w");
+ public FloatVal h = new FloatVal("h");
+
+ public FloatBoundedShape() {
+ addParam(x);
+ addParam(y);
+ addParam(w);
+ addParam(h);
+ }
+ }
+
+ /**
+ * Base tester class for objects with double precision xywh bounds
+ */
+ public static abstract class DoubleBoundedShape extends ShapeTester {
+ public DoubleVal x = new DoubleVal("x");
+ public DoubleVal y = new DoubleVal("y");
+ public DoubleVal w = new DoubleVal("w");
+ public DoubleVal h = new DoubleVal("h");
+
+ public DoubleBoundedShape() {
+ addParam(x);
+ addParam(y);
+ addParam(w);
+ addParam(h);
+ }
+ }
+
+ public static class FloatRectangleTester extends FloatBoundedShape {
+ public Object makeShape() {
+ return new Rectangle2D.Float(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal());
+ }
+ }
+
+ public static class DoubleRectangleTester extends DoubleBoundedShape {
+ public Object makeShape() {
+ return new Rectangle2D.Double(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal());
+ }
+ }
+
+ public static class FloatEllipseTester extends FloatBoundedShape {
+ public Object makeShape() {
+ return new Ellipse2D.Float(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal());
+ }
+ }
+
+ public static class DoubleEllipseTester extends DoubleBoundedShape {
+ public Object makeShape() {
+ return new Ellipse2D.Double(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal());
+ }
+ }
+
+ public static class FloatArcTester extends FloatBoundedShape {
+ public FloatVal start = new FloatVal("start");
+ public FloatVal extent = new FloatVal("extent");
+ public IntRangeVal type = new IntRangeVal("type", 0, 2);
+
+ public FloatArcTester() {
+ addParam(start);
+ addParam(extent);
+ addParam(type);
+ }
+
+ public Object makeShape() {
+ return new Arc2D.Float(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal(),
+ start.getVal(), extent.getVal(),
+ type.getVal());
+ }
+ }
+
+ public static class DoubleArcTester extends DoubleBoundedShape {
+ public DoubleVal start = new DoubleVal("start");
+ public DoubleVal extent = new DoubleVal("extent");
+ public IntRangeVal type = new IntRangeVal("type", 0, 2);
+
+ public DoubleArcTester() {
+ addParam(start);
+ addParam(extent);
+ addParam(type);
+ }
+
+ public Object makeShape() {
+ return new Arc2D.Double(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal(),
+ start.getVal(), extent.getVal(),
+ type.getVal());
+ }
+ }
+
+ public static class FloatRoundRectTester extends FloatBoundedShape {
+ public FloatVal arcw = new FloatVal("arcw");
+ public FloatVal arch = new FloatVal("arch");
+
+ public FloatRoundRectTester() {
+ addParam(arcw);
+ addParam(arch);
+ }
+
+ public Object makeShape() {
+ return new RoundRectangle2D.Float(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal(),
+ arcw.getVal(), arch.getVal());
+ }
+ }
+
+ public static class DoubleRoundRectTester extends DoubleBoundedShape {
+ public DoubleVal arcw = new DoubleVal("arcw");
+ public DoubleVal arch = new DoubleVal("arch");
+
+ public DoubleRoundRectTester() {
+ addParam(arcw);
+ addParam(arch);
+ }
+
+ public Object makeShape() {
+ return new RoundRectangle2D.Double(x.getVal(), y.getVal(),
+ w.getVal(), h.getVal(),
+ arcw.getVal(), arch.getVal());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/GeneralPath/ContainsNaN.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 ContainsNaN
+ */
+
+import java.awt.geom.GeneralPath;
+
+public class ContainsNaN {
+ public static void main(String argv[]) {
+ GeneralPath gp = new GeneralPath();
+ gp.moveTo(0, 0);
+ gp.quadTo(100, 0, 100, 100);
+ gp.contains(Double.NaN, Double.NaN);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/GeneralPath/ContainsPoint.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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 6396047
+ * @summary tests the GeneralPath.contains(x, y) method
+ */
+
+import java.awt.geom.GeneralPath;
+
+public class ContainsPoint {
+ public static void main(String args[]) {
+ GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO);
+ gp.moveTo(46.69187927246094f, 95.8778305053711f);
+ gp.curveTo(-122.75305938720703f, 14.31462574005127f,
+ 66.84117889404297f, 26.061769485473633f,
+ -62.62519073486328f, -13.041547775268555f);
+ gp.closePath();
+ if (gp.contains(-122.75305938720703, -13.041547775268555)) {
+ throw new RuntimeException("contains point clearly "+
+ "outside of curve");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/GeneralPath/CreateTxReturnsGP.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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 6404847
+ * @summary Tests that GeneralPath.createTransformedShape() returns
+ * a GeneralPath object for backwards compatibility.
+ */
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+
+public class CreateTxReturnsGP {
+ public static void main(String argv[]) {
+ GeneralPath gp = new GeneralPath();
+ gp.moveTo(0, 0);
+ gp.lineTo(10, 10);
+ Shape s1 = gp.createTransformedShape(null);
+ Shape s2 = gp.createTransformedShape(new AffineTransform());
+ if (!(s1 instanceof GeneralPath) || !(s2 instanceof GeneralPath)) {
+ throw new RuntimeException("GeneralPath.createTransformedShape() "+
+ "did not return a GeneralPath");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/GeneralPath/EmptyRectHitTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * 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 6284484
+ * @summary Verifies that GeneralPath objects do not "contain" or "intersect"
+ * empty rectangles
+ */
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+
+public class EmptyRectHitTest {
+ public static int numerrors;
+
+ public static void main(String argv[]) {
+ Rectangle select1 = new Rectangle(1, 1, 1, 1);
+ Rectangle select2 = new Rectangle(1, 1, 0, 0);
+ Rectangle select3 = new Rectangle(100, 100, 1, 1);
+ Rectangle select4 = new Rectangle(100, 100, 0, 0);
+
+ Rectangle rect = new Rectangle(-5, -5, 10, 10);
+ test(rect, select1, true, true);
+ test(rect, select2, false, false);
+ test(rect, select3, false, false);
+ test(rect, select4, false, false);
+
+ GeneralPath gp = new GeneralPath(rect);
+ test(gp, select1, true, true);
+ test(gp, select2, false, false);
+ test(gp, select3, false, false);
+ test(gp, select4, false, false);
+
+ AffineTransform xform = new AffineTransform();
+ xform.setToRotation(Math.PI / 4);
+ Shape shape = xform.createTransformedShape(rect);
+ test(shape, select1, true, true);
+ test(shape, select2, false, false);
+ test(shape, select3, false, false);
+ test(shape, select4, false, false);
+
+ if (numerrors > 0) {
+ throw new RuntimeException(numerrors+" errors in tests");
+ }
+ }
+
+ public static void test(Shape testshape, Rectangle rect,
+ boolean shouldcontain, boolean shouldintersect)
+ {
+ if (testshape.contains(rect) != shouldcontain) {
+ error(testshape, rect, "contains", !shouldcontain);
+ }
+ if (testshape.intersects(rect) != shouldintersect) {
+ error(testshape, rect, "intersects", !shouldintersect);
+ }
+ }
+
+ public static void error(Shape t, Rectangle r, String type, boolean res) {
+ numerrors++;
+ System.err.println(t+type+"("+r+") == "+res);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/GeneralPath/IntersectsRect.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,53 @@
+/*
+ * 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 6396047
+ * @summary tests the GeneralPath.intersects(x, y, w, h) method
+ */
+
+import java.awt.geom.GeneralPath;
+
+public class IntersectsRect {
+ public static void main(String args[]) {
+ GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO);
+ gp.moveTo(-12.820351600646973f, 22.158836364746094f);
+ gp.quadTo(-26.008909225463867f, 83.72308349609375f,
+ 84.20527648925781f, 13.218562126159668f);
+ gp.quadTo(107.0041275024414f, 38.3076171875f,
+ -55.382022857666016f, -113.43235778808594f);
+ gp.lineTo(-43.795501708984375f, 52.847373962402344f);
+ gp.curveTo(37.72114944458008f, 70.46839141845703f,
+ -26.205299377441406f, -103.99849700927734f,
+ 108.40007781982422f, 101.23545837402344f);
+ gp.closePath();
+
+ if (gp.intersects(34.614093600596874, 22.15252370704289,
+ 0.5, 0.5) != false)
+ {
+ throw new RuntimeException("intersects rect clearly "+
+ "outside of path");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Line2D/AALineTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2004, 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 5089985
+ * @summary Test checks that drawing AA lines don't crash the VM
+ */
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.GeneralPath;
+import java.awt.image.BufferedImage;
+
+public class AALineTest {
+
+ /* Pairs of endpoints which cause VM crash */
+
+ public static int xBound [][] = {
+ {634,25,640,33},
+ {634,57,640,65},
+ {634,89,640,97},
+ {634,121,640,129},
+ {634,153,640,161},
+ {634,185,640,193},
+ {634,217,640,225},
+ {634,249,640,257},
+ {634,281,640,289},
+ {634,313,640,321},
+ {634,345,640,353},
+ {634,377,640,385},
+ {634,409,640,417},
+ {634,441,640,449}
+ };
+
+ public static int yBound [][] = {
+ {25, 634,33, 640},
+ {57, 634,65, 640},
+ {89, 634,97, 640},
+ {121,634,129,640},
+ {153,634,161,640},
+ {185,634,193,640},
+ {217,634,225,640},
+ {249,634,257,640},
+ {281,634,289,640},
+ {313,634,321,640},
+ {345,634,353,640},
+ {377,634,385,640},
+ {409,634,417,640},
+ {441,634,449,640}
+ };
+
+ public static void main(String[] args) {
+ BufferedImage image =
+ new BufferedImage(640, 480, BufferedImage.TYPE_INT_ARGB);
+
+ Graphics2D graphics = image.createGraphics();
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ GeneralPath path = new GeneralPath();
+ for(int i=0; i < xBound.length; i++) {
+ path.reset();
+ path.moveTo(0, 0);
+ path.lineTo(xBound[i][0],xBound[i][1]);
+ path.lineTo(xBound[i][2],xBound[i][3]);
+ path.closePath();
+ graphics.draw(path);
+ }
+
+ image = new BufferedImage(480, 640, BufferedImage.TYPE_INT_ARGB);
+
+ graphics = image.createGraphics();
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ for(int i=0; i < yBound.length; i++) {
+ path.reset();
+ path.moveTo(0, 0);
+ path.lineTo(yBound[i][0],yBound[i][1]);
+ path.lineTo(yBound[i][2],yBound[i][3]);
+ path.closePath();
+ graphics.draw(path);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Line2D/NegLineDistSqBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2002, 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 4335024
+ * @summary Verifies that the ptXXXDistSq methods return non-negative numbers
+ */
+
+import java.awt.geom.Line2D;
+
+public class NegLineDistSqBug {
+ static int errored;
+
+ public static void main (String[] args) {
+ // First a sanity check
+ test(1, 2, 3, 4, 15, 19, 21, 32);
+ // Next, the test numbers from bug report 4335024
+ test(-313.0, 241.0, -97.0, 75.0,
+ 126.15362619253153, -96.49769420351959, -97.0, 75.0);
+ // Next test 100 points along the line from bug report 4335024
+ for (double fract = 0.0; fract <= 0.5; fract += 0.01) {
+ test(-313.0, 241.0, -97.0, 75.0,
+ interp(-313.0, -97.0, fract), interp(241.0, 75.0, fract),
+ interp(-313.0, -97.0, 1-fract), interp(241.0, 75.0, 1-fract));
+ }
+ if (errored > 0) {
+ throw new RuntimeException(errored+" negative distances!");
+ }
+ }
+
+ public static double interp(double v1, double v2, double t) {
+ return (v1 * (1-t) + v2 * t);
+ }
+
+ public static void test(double l1x1, double l1y1,
+ double l1x2, double l1y2,
+ double l2x1, double l2y1,
+ double l2x2, double l2y2)
+ {
+ Line2D l1 = new Line2D.Double(l1x1, l1y1, l1x2, l1y2);
+ Line2D l2 = new Line2D.Double(l2x1, l2y1, l2x2, l2y2);
+ System.out.println("Line distances:");
+ verify(l1.ptLineDistSq(l2.getP1()));
+ verify(l1.ptLineDistSq(l2.getP2()));
+ System.out.println("Segment distances:");
+ verify(l1.ptSegDistSq(l2.getP1()));
+ verify(l1.ptSegDistSq(l2.getP2()));
+ }
+
+ public static void verify(double distSq) {
+ System.out.println(distSq);
+ if (distSq < 0) {
+ errored++;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Path2D/CreateTxReturnsSame.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * 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 6404847
+ * @summary Tests that Path2D.createTransformedShape() returns
+ * the same kind of object as the source.
+ */
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
+
+public class CreateTxReturnsSame {
+ public static void main(String argv[]) {
+ test(new GeneralPath());
+ test(new Path2D.Float());
+ test(new Path2D.Double());
+ }
+
+ public static void test(Path2D p2d) {
+ p2d.moveTo(0, 0);
+ p2d.lineTo(10, 10);
+ Shape s1 = p2d.createTransformedShape(null);
+ Shape s2 = p2d.createTransformedShape(new AffineTransform());
+ if (s1.getClass() != p2d.getClass() ||
+ s2.getClass() != p2d.getClass())
+ {
+ throw new RuntimeException(p2d.getClass().getName()+
+ ".createTransformedShape() "+
+ "did not return a "+
+ p2d.getClass().getName());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Path2D/NonFiniteTests.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,264 @@
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Path2D/UnitTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,1350 @@
+/*
+ * 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 4172661
+ * @summary Tests all public methods of Path2D classes on all 3 variants
+ * Path2D.Float, Path2D.Double, and GeneralPath.
+ * REMIND: Note that the hit testing tests will fail
+ * occasionally due to precision bugs in the various hit
+ * testing methods in the geometry classes.
+ * (Failure rates vary from 1 per 100 runs to 1 per thousands).
+ * See bug 6396047 to track progress on these failures.
+ */
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.FlatteningPathIterator;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.util.NoSuchElementException;
+
+public class UnitTest {
+ public static boolean verbose;
+
+ public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+ public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+
+ public static int CoordsForType[] = { 2, 2, 4, 6, 0 };
+
+ public static AffineTransform TxIdentity = new AffineTransform();
+ public static AffineTransform TxComplex = makeAT();
+
+ public static Shape TestShapes[];
+ public static SampleShape ShortSampleNonZero;
+ public static SampleShape ShortSampleEvenOdd;
+ public static SampleShape LongSampleNonZero;
+ public static SampleShape LongSampleEvenOdd;
+
+ public static Shape EmptyShapeNonZero =
+ new EmptyShape(WIND_NON_ZERO);
+ public static Shape EmptyShapeEvenOdd =
+ new EmptyShape(WIND_EVEN_ODD);
+
+ // Note: We pick a shape that is not anywhere near any of
+ // our test shapes so that the Path2D does not try to collapse
+ // out the connecting segment - an optimization that is too
+ // difficult to account for in the AppendedShape code.
+ public static Shape AppendShape = new Arc2D.Double(1000, 1000, 40, 40,
+ Math.PI/4, Math.PI,
+ Arc2D.CHORD);
+
+ public static AffineTransform makeAT() {
+ AffineTransform at = new AffineTransform();
+ at.scale(0.66, 0.23);
+ at.rotate(Math.toRadians(35.0));
+ at.shear(0.78, 1.32);
+ return at;
+ }
+
+ public static void init() {
+ TestShapes = new Shape[] {
+ EmptyShapeNonZero,
+ EmptyShapeEvenOdd,
+ new Line2D.Double(),
+ new Line2D.Double(rpc(), rpc(), rpc(), rpc()),
+ new Line2D.Double(rnc(), rnc(), rnc(), rnc()),
+ new Rectangle2D.Double(),
+ new Rectangle2D.Double(rpc(), rpc(), -1, -1),
+ new Rectangle2D.Double(rpc(), rpc(), rd(), rd()),
+ new Rectangle2D.Double(rnc(), rnc(), rd(), rd()),
+ new Ellipse2D.Double(),
+ new Ellipse2D.Double(rpc(), rpc(), -1, -1),
+ new Ellipse2D.Double(rpc(), rpc(), rd(), rd()),
+ new Ellipse2D.Double(rnc(), rnc(), rd(), rd()),
+ new Arc2D.Double(Arc2D.OPEN),
+ new Arc2D.Double(Arc2D.CHORD),
+ new Arc2D.Double(Arc2D.PIE),
+ new Arc2D.Double(rpc(), rpc(), -1, -1, rt(), rt(), Arc2D.OPEN),
+ new Arc2D.Double(rpc(), rpc(), -1, -1, rt(), rt(), Arc2D.CHORD),
+ new Arc2D.Double(rpc(), rpc(), -1, -1, rt(), rt(), Arc2D.PIE),
+ new Arc2D.Double(rpc(), rpc(), rd(), rd(), rt(), rt(), Arc2D.OPEN),
+ new Arc2D.Double(rpc(), rpc(), rd(), rd(), rt(), rt(), Arc2D.CHORD),
+ new Arc2D.Double(rpc(), rpc(), rd(), rd(), rt(), rt(), Arc2D.PIE),
+ new Arc2D.Double(rnc(), rnc(), rd(), rd(), rt(), rt(), Arc2D.OPEN),
+ new Arc2D.Double(rnc(), rnc(), rd(), rd(), rt(), rt(), Arc2D.CHORD),
+ new Arc2D.Double(rnc(), rnc(), rd(), rd(), rt(), rt(), Arc2D.PIE),
+ new RoundRectangle2D.Double(),
+ new RoundRectangle2D.Double(rpc(), rpc(), -1, -1, ra(), ra()),
+ new RoundRectangle2D.Double(rpc(), rpc(), rd(), rd(), ra(), ra()),
+ new RoundRectangle2D.Double(rnc(), rnc(), rd(), rd(), ra(), ra()),
+ new QuadCurve2D.Double(),
+ new QuadCurve2D.Double(rpc(), rpc(), rpc(), rpc(), rpc(), rpc()),
+ new QuadCurve2D.Double(rnc(), rnc(), rnc(), rnc(), rnc(), rnc()),
+ new CubicCurve2D.Double(),
+ new CubicCurve2D.Double(rpc(), rpc(), rpc(), rpc(),
+ rpc(), rpc(), rpc(), rpc()),
+ new CubicCurve2D.Double(rnc(), rnc(), rnc(), rnc(),
+ rnc(), rnc(), rnc(), rnc()),
+ makeGeneralPath(WIND_NON_ZERO, 1.0),
+ makeGeneralPath(WIND_EVEN_ODD, 1.0),
+ makeGeneralPath(WIND_NON_ZERO, -1.0),
+ makeGeneralPath(WIND_EVEN_ODD, -1.0),
+ };
+
+ int types[] = new int[100];
+ int i = 0;
+ types[i++] = PathIterator.SEG_MOVETO;
+ types[i++] = PathIterator.SEG_LINETO;
+ types[i++] = PathIterator.SEG_QUADTO;
+ types[i++] = PathIterator.SEG_CUBICTO;
+ types[i++] = PathIterator.SEG_CLOSE;
+ int shortlen = i;
+ int prevt = types[i-1];
+ while (i < types.length) {
+ int t;
+ do {
+ t = (int) (Math.random() * 5);
+ } while (t == prevt &&
+ (t == PathIterator.SEG_MOVETO ||
+ t == PathIterator.SEG_CLOSE));
+ types[i++] = t;
+ prevt = t;
+ }
+
+ int numcoords = 0;
+ int numshortcoords = 0;
+ for (i = 0; i < types.length; i++) {
+ if (i == shortlen) {
+ numshortcoords = numcoords;
+ }
+ numcoords += CoordsForType[types[i]];
+ }
+ double coords[] = new double[numcoords];
+ for (i = 0; i < coords.length; i++) {
+ coords[i] = rpc();
+ }
+ ShortSampleNonZero = new SampleShape(WIND_NON_ZERO,
+ types, coords,
+ shortlen, numshortcoords);
+ ShortSampleEvenOdd = new SampleShape(WIND_EVEN_ODD,
+ types, coords,
+ shortlen, numshortcoords);
+ LongSampleNonZero = new SampleShape(WIND_NON_ZERO,
+ types, coords,
+ types.length, numcoords);
+ LongSampleEvenOdd = new SampleShape(WIND_EVEN_ODD,
+ types, coords,
+ types.length, numcoords);
+ }
+
+ public static GeneralPath makeGeneralPath(int windingrule, double sign) {
+ GeneralPath gp = new GeneralPath(windingrule);
+ gp.moveTo((float) (sign * rpc()), (float) (sign * rpc()));
+ gp.lineTo((float) (sign * rpc()), (float) (sign * rpc()));
+ gp.quadTo((float) (sign * rpc()), (float) (sign * rpc()),
+ (float) (sign * rpc()), (float) (sign * rpc()));
+ gp.curveTo((float) (sign * rpc()), (float) (sign * rpc()),
+ (float) (sign * rpc()), (float) (sign * rpc()),
+ (float) (sign * rpc()), (float) (sign * rpc()));
+ gp.closePath();
+ return gp;
+ }
+
+ // Due to odd issues with the sizes of errors when the values
+ // being manipulated are near zero, we try to avoid values
+ // near zero by ensuring that both the rpc (positive coords)
+ // stay away from zero and also by ensuring that the rpc+rd
+ // (positive coords + dimensions) stay away from zero. We
+ // also ensure that rnc+rd (negative coords + dimension) stay
+ // suitably negative without approaching zero.
+
+ // Random positive coordinate (10 -> 110)
+ // rpc + rd gives a total range of (30 -> 170)
+ public static double rpc() {
+ return (Math.random() * 100.0) + 10.0;
+ }
+
+ // Random negative coordinate (-200 -> -100)
+ // rnc + rd gives a total range of (-180 -> -40)
+ public static double rnc() {
+ return (Math.random() * 100.0) - 200.0;
+ }
+
+ // Random dimension (20 -> 60)
+ public static double rd() {
+ return (Math.random() * 40.0) + 20.0;
+ }
+
+ // Random arc width/height (0.1 -> 5.1)
+ public static double ra() {
+ return (Math.random() * 5.0) + 0.1;
+ }
+
+ // Random arc angle (theta) (PI/4 => 5PI/4)
+ public static double rt() {
+ return (Math.random() * Math.PI) + Math.PI/4;
+ }
+
+ public static int fltulpdiff(double v1, double v2) {
+ if (v1 == v2) {
+ return 0;
+ }
+ float vf1 = (float) v1;
+ float vf2 = (float) v2;
+ if (vf1 == vf2) {
+ return 0;
+ }
+ float diff = Math.abs(vf1-vf2);
+ //float ulp = Math.ulp((float) ((vf1 + vf2)/2f));
+ float ulp = Math.max(Math.ulp(vf1), Math.ulp(vf2));
+ if (verbose && diff > ulp) {
+ System.out.println("v1 = "+vf1+", ulp = "+Math.ulp(vf1));
+ System.out.println("v2 = "+vf2+", ulp = "+Math.ulp(vf2));
+ System.out.println((diff/ulp)+" ulps");
+ }
+ return (int) (diff/ulp);
+ }
+
+ public static int fltulpless(double v1, double v2) {
+ if (v1 >= v2) {
+ return 0;
+ }
+ float vf1 = (float) v1;
+ float vf2 = (float) v2;
+ if (vf1 >= vf2) {
+ return 0;
+ }
+ float diff = Math.abs(vf1-vf2);
+ //float ulp = Math.ulp((float) ((vf1 + vf2)/2f));
+ float ulp = Math.max(Math.ulp(vf1), Math.ulp(vf2));
+ if (verbose && diff > ulp) {
+ System.out.println("v1 = "+vf1+", ulp = "+Math.ulp(vf1));
+ System.out.println("v2 = "+vf2+", ulp = "+Math.ulp(vf2));
+ System.out.println((diff/ulp)+" ulps");
+ }
+ return (int) (diff/ulp);
+ }
+
+ public static int dblulpdiff(double v1, double v2) {
+ if (v1 == v2) {
+ return 0;
+ }
+ double diff = Math.abs(v1-v2);
+ //double ulp = Math.ulp((v1 + v2)/2.0);
+ double ulp = Math.max(Math.ulp(v1), Math.ulp(v2));
+ if (verbose && diff > ulp) {
+ System.out.println("v1 = "+v1+", ulp = "+Math.ulp(v1));
+ System.out.println("v2 = "+v2+", ulp = "+Math.ulp(v2));
+ System.out.println((diff/ulp)+" ulps");
+ }
+ return (int) (diff/ulp);
+ }
+
+ public static abstract class Creator {
+ public abstract Path2D makePath();
+ public abstract Path2D makePath(int windingrule);
+ public abstract Path2D makePath(int windingrule, int capacity);
+ public abstract Path2D makePath(Shape s);
+ public abstract Path2D makePath(Shape s, AffineTransform at);
+
+ public abstract boolean supportsFloatCompose();
+ public abstract int getRecommendedTxMaxUlp();
+
+ public abstract void compare(PathIterator testpi,
+ PathIterator refpi,
+ AffineTransform at,
+ int maxulp);
+ }
+
+ public static class FltCreator extends Creator {
+ public Path2D makePath() {
+ return new Path2D.Float();
+ }
+ public Path2D makePath(int windingrule) {
+ return new Path2D.Float(windingrule);
+ }
+ public Path2D makePath(int windingrule, int capacity) {
+ return new Path2D.Float(windingrule, capacity);
+ }
+ public Path2D makePath(Shape s) {
+ return new Path2D.Float(s);
+ }
+ public Path2D makePath(Shape s, AffineTransform at) {
+ return new Path2D.Float(s, at);
+ }
+
+ public boolean supportsFloatCompose() {
+ return true;
+ }
+ public int getRecommendedTxMaxUlp() {
+ return 5;
+ }
+
+ public void compare(PathIterator testpi,
+ PathIterator refpi,
+ AffineTransform at,
+ int maxulp)
+ {
+ if (testpi.getWindingRule() != refpi.getWindingRule()) {
+ throw new RuntimeException("wrong winding rule");
+ }
+ float testcoords[] = new float[6];
+ float refcoords[] = new float[6];
+ while (!testpi.isDone()) {
+ if (refpi.isDone()) {
+ throw new RuntimeException("too many segments");
+ }
+ int testtype = testpi.currentSegment(testcoords);
+ int reftype = refpi.currentSegment(refcoords);
+ if (testtype != reftype) {
+ throw new RuntimeException("different segment types");
+ }
+ if (at != null) {
+ at.transform(refcoords, 0, refcoords, 0,
+ CoordsForType[reftype]/2);
+ }
+ for (int i = 0; i < CoordsForType[testtype]; i++) {
+ int ulps = fltulpdiff(testcoords[i], refcoords[i]);
+ if (ulps > maxulp) {
+ throw new RuntimeException("coords are different: "+
+ testcoords[i]+" != "+
+ refcoords[i]+
+ " ("+ulps+" ulps)");
+ }
+ }
+ testpi.next();
+ refpi.next();
+ }
+ if (!refpi.isDone()) {
+ throw new RuntimeException("not enough segments");
+ }
+ }
+ }
+
+ public static class DblCreator extends Creator {
+ public Path2D makePath() {
+ return new Path2D.Double();
+ }
+ public Path2D makePath(int windingrule) {
+ return new Path2D.Double(windingrule);
+ }
+ public Path2D makePath(int windingrule, int capacity) {
+ return new Path2D.Double(windingrule, capacity);
+ }
+ public Path2D makePath(Shape s) {
+ return new Path2D.Double(s);
+ }
+ public Path2D makePath(Shape s, AffineTransform at) {
+ return new Path2D.Double(s, at);
+ }
+
+ public boolean supportsFloatCompose() {
+ return false;
+ }
+ public int getRecommendedTxMaxUlp() {
+ return 3;
+ }
+
+ public void compare(PathIterator testpi,
+ PathIterator refpi,
+ AffineTransform at,
+ int maxulp)
+ {
+ if (testpi.getWindingRule() != refpi.getWindingRule()) {
+ throw new RuntimeException("wrong winding rule");
+ }
+ double testcoords[] = new double[6];
+ double refcoords[] = new double[6];
+ while (!testpi.isDone()) {
+ if (refpi.isDone()) {
+ throw new RuntimeException("too many segments");
+ }
+ int testtype = testpi.currentSegment(testcoords);
+ int reftype = refpi.currentSegment(refcoords);
+ if (testtype != reftype) {
+ throw new RuntimeException("different segment types");
+ }
+ if (at != null) {
+ at.transform(refcoords, 0, refcoords, 0,
+ CoordsForType[reftype]/2);
+ }
+ for (int i = 0; i < CoordsForType[testtype]; i++) {
+ int ulps = dblulpdiff(testcoords[i], refcoords[i]);
+ if (ulps > maxulp) {
+ throw new RuntimeException("coords are different: "+
+ testcoords[i]+" != "+
+ refcoords[i]+
+ " ("+ulps+" ulps)");
+ }
+ }
+ testpi.next();
+ refpi.next();
+ }
+ if (!refpi.isDone()) {
+ throw new RuntimeException("not enough segments");
+ }
+ }
+
+ }
+
+ public static class GPCreator extends FltCreator {
+ public Path2D makePath() {
+ return new GeneralPath();
+ }
+ public Path2D makePath(int windingrule) {
+ return new GeneralPath(windingrule);
+ }
+ public Path2D makePath(int windingrule, int capacity) {
+ return new GeneralPath(windingrule, capacity);
+ }
+ public Path2D makePath(Shape s) {
+ return new GeneralPath(s);
+ }
+ public Path2D makePath(Shape s, AffineTransform at) {
+ GeneralPath gp = new GeneralPath();
+ PathIterator pi = s.getPathIterator(at);
+ gp.setWindingRule(pi.getWindingRule());
+ gp.append(pi, false);
+ return gp;
+ }
+
+ public boolean supportsFloatCompose() {
+ return true;
+ }
+ }
+
+ public static class EmptyShape implements Shape {
+ private int windingrule;
+
+ public EmptyShape(int windingrule) {
+ this.windingrule = windingrule;
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle();
+ }
+ public Rectangle2D getBounds2D() {
+ return new Rectangle();
+ }
+ public boolean contains(double x, double y) {
+ return false;
+ }
+ public boolean contains(Point2D p) {
+ return false;
+ }
+ public boolean intersects(double x, double y, double w, double h) {
+ return false;
+ }
+ public boolean intersects(Rectangle2D r) {
+ return false;
+ }
+ public boolean contains(double x, double y, double w, double h) {
+ return false;
+ }
+ public boolean contains(Rectangle2D r) {
+ return false;
+ }
+ public PathIterator getPathIterator(AffineTransform at) {
+ return new PathIterator() {
+ public int getWindingRule() {
+ return windingrule;
+ }
+ public boolean isDone() {
+ return true;
+ }
+ public void next() {}
+ public int currentSegment(float[] coords) {
+ throw new NoSuchElementException();
+ }
+ public int currentSegment(double[] coords) {
+ throw new NoSuchElementException();
+ }
+ };
+ }
+ public PathIterator getPathIterator(AffineTransform at,
+ double flatness)
+ {
+ return getPathIterator(at);
+ }
+ }
+
+ public static class SampleShape implements Shape {
+ int windingrule;
+ int theTypes[];
+ double theCoords[];
+ int numTypes;
+ int numCoords;
+
+ public SampleShape(int windingrule,
+ int types[], double coords[],
+ int numtypes, int numcoords)
+ {
+ this.windingrule = windingrule;
+ this.theTypes = types;
+ this.theCoords = coords;
+ this.numTypes = numtypes;
+ this.numCoords = numcoords;
+ }
+
+ private Shape testshape;
+
+ public Shape getTestShape() {
+ if (testshape == null) {
+ testshape = new Area(this);
+ }
+ return testshape;
+ }
+
+ private Rectangle2D cachedBounds;
+ public Rectangle2D getCachedBounds2D() {
+ if (cachedBounds == null) {
+ double xmin, ymin, xmax, ymax;
+ int ci = 0;
+ xmin = xmax = theCoords[ci++];
+ ymin = ymax = theCoords[ci++];
+ while (ci < numCoords) {
+ double c = theCoords[ci++];
+ if (xmin > c) xmin = c;
+ if (xmax < c) xmax = c;
+ c = theCoords[ci++];
+ if (ymin > c) ymin = c;
+ if (ymax < c) ymax = c;
+ }
+ cachedBounds = new Rectangle2D.Double(xmin, ymin,
+ xmax - xmin,
+ ymax - ymin);
+ }
+ return cachedBounds;
+ }
+
+ public Rectangle getBounds() {
+ return getCachedBounds2D().getBounds();
+ }
+ public Rectangle2D getBounds2D() {
+ return getCachedBounds2D().getBounds2D();
+ }
+ public boolean contains(double x, double y) {
+ return getTestShape().contains(x, y);
+ }
+ public boolean contains(Point2D p) {
+ return getTestShape().contains(p);
+ }
+ public boolean intersects(double x, double y, double w, double h) {
+ return getTestShape().intersects(x, y, w, h);
+ }
+ public boolean intersects(Rectangle2D r) {
+ return getTestShape().intersects(r);
+ }
+ public boolean contains(double x, double y, double w, double h) {
+ return getTestShape().contains(x, y, w, h);
+ }
+ public boolean contains(Rectangle2D r) {
+ return getTestShape().contains(r);
+ }
+ public PathIterator getPathIterator(final AffineTransform at) {
+ return new PathIterator() {
+ int tindex;
+ int cindex;
+ public int getWindingRule() {
+ return windingrule;
+ }
+ public boolean isDone() {
+ return (tindex >= numTypes);
+ }
+ public void next() {
+ cindex += CoordsForType[theTypes[tindex]];
+ tindex++;
+ }
+ public int currentSegment(float[] coords) {
+ int t = theTypes[tindex];
+ int n = CoordsForType[t];
+ if (n > 0) {
+ // Cast to float first, then transform
+ // to match accuracy of float paths
+ for (int i = 0; i < n; i++) {
+ coords[i] = (float) theCoords[cindex+i];
+ }
+ if (at != null) {
+ at.transform(coords, 0, coords, 0, n/2);
+ }
+ }
+ return t;
+ }
+ public int currentSegment(double[] coords) {
+ int t = theTypes[tindex];
+ int n = CoordsForType[t];
+ if (n > 0) {
+ if (at == null) {
+ System.arraycopy(theCoords, cindex,
+ coords, 0, n);
+ } else {
+ at.transform(theCoords, cindex,
+ coords, 0, n/2);
+ }
+ }
+ return t;
+ }
+ };
+ }
+ public PathIterator getPathIterator(AffineTransform at,
+ double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ public String toString() {
+ Rectangle2D r2d = getBounds2D();
+ double xmin = r2d.getMinX();
+ double ymin = r2d.getMinY();
+ double xmax = r2d.getMaxX();
+ double ymax = r2d.getMaxY();
+ return ("SampleShape["+
+ (windingrule == WIND_NON_ZERO
+ ? "NonZero"
+ : "EvenOdd")+
+ ", nsegments = "+numTypes+
+ ", ncoords = "+numCoords+
+ ", bounds["+(r2d.getMinX()+", "+r2d.getMinY()+", "+
+ r2d.getMaxX()+", "+r2d.getMaxY())+"]"+
+ "]");
+ }
+
+ public Path2D makeFloatPath(Creator c) {
+ Path2D.Float p2df = (Path2D.Float) c.makePath(windingrule);
+ int ci = 0;
+ for (int i = 0; i < numTypes; i++) {
+ int t = theTypes[i];
+ switch (t) {
+ case PathIterator.SEG_MOVETO:
+ p2df.moveTo((float) theCoords[ci++],
+ (float) theCoords[ci++]);
+ break;
+ case PathIterator.SEG_LINETO:
+ p2df.lineTo((float) theCoords[ci++],
+ (float) theCoords[ci++]);
+ break;
+ case PathIterator.SEG_QUADTO:
+ p2df.quadTo((float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++]);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ p2df.curveTo((float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++],
+ (float) theCoords[ci++]);
+ break;
+ case PathIterator.SEG_CLOSE:
+ p2df.closePath();
+ break;
+ default:
+ throw new InternalError("unrecognized path type: "+t);
+ }
+ if (t != PathIterator.SEG_CLOSE) {
+ Point2D curpnt = p2df.getCurrentPoint();
+ if (((float) curpnt.getX()) != ((float) theCoords[ci-2]) ||
+ ((float) curpnt.getY()) != ((float) theCoords[ci-1]))
+ {
+ throw new RuntimeException("currentpoint failed");
+ }
+ }
+ }
+ if (ci != numCoords) {
+ throw new InternalError("numcoords did not match");
+ }
+ return p2df;
+ }
+
+ public Path2D makeDoublePath(Creator c) {
+ Path2D p2d = c.makePath(windingrule);
+ int ci = 0;
+ for (int i = 0; i < numTypes; i++) {
+ int t = theTypes[i];
+ switch (t) {
+ case PathIterator.SEG_MOVETO:
+ p2d.moveTo(theCoords[ci++], theCoords[ci++]);
+ break;
+ case PathIterator.SEG_LINETO:
+ p2d.lineTo(theCoords[ci++], theCoords[ci++]);
+ break;
+ case PathIterator.SEG_QUADTO:
+ p2d.quadTo(theCoords[ci++], theCoords[ci++],
+ theCoords[ci++], theCoords[ci++]);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ p2d.curveTo(theCoords[ci++], theCoords[ci++],
+ theCoords[ci++], theCoords[ci++],
+ theCoords[ci++], theCoords[ci++]);
+ break;
+ case PathIterator.SEG_CLOSE:
+ p2d.closePath();
+ break;
+ default:
+ throw new InternalError("unrecognized path type: "+t);
+ }
+ if (t != PathIterator.SEG_CLOSE) {
+ Point2D curpnt = p2d.getCurrentPoint();
+ if (((float) curpnt.getX()) != ((float) theCoords[ci-2]) ||
+ ((float) curpnt.getY()) != ((float) theCoords[ci-1]))
+ {
+ throw new RuntimeException("currentpoint failed");
+ }
+ }
+ }
+ if (ci != numCoords) {
+ throw new InternalError("numcoords did not match");
+ }
+ return p2d;
+ }
+ }
+
+ public static class AppendedShape implements Shape {
+ Shape s1;
+ Shape s2;
+ boolean connect;
+
+ public AppendedShape(Shape s1, Shape s2, boolean connect) {
+ this.s1 = s1;
+ this.s2 = s2;
+ this.connect = connect;
+ }
+
+ public Rectangle getBounds() {
+ return getBounds2D().getBounds();
+ }
+
+ public Rectangle2D getBounds2D() {
+ return s1.getBounds2D().createUnion(s2.getBounds2D());
+ }
+
+ private Shape testshape;
+ private Shape getTestShape() {
+ if (testshape == null) {
+ testshape = new GeneralPath(this);
+ }
+ return testshape;
+ }
+
+ public boolean contains(double x, double y) {
+ return getTestShape().contains(x, y);
+ }
+
+ public boolean contains(Point2D p) {
+ return getTestShape().contains(p);
+ }
+
+ public boolean intersects(double x, double y, double w, double h) {
+ return getTestShape().intersects(x, y, w, h);
+ }
+
+ public boolean intersects(Rectangle2D r) {
+ return getTestShape().intersects(r);
+ }
+
+ public boolean contains(double x, double y, double w, double h) {
+ return getTestShape().contains(x, y, w, h);
+ }
+
+ public boolean contains(Rectangle2D r) {
+ return getTestShape().contains(r);
+ }
+
+ public PathIterator getPathIterator(final AffineTransform at) {
+ return new AppendingPathIterator(s1, s2, connect, at);
+ }
+
+ public PathIterator getPathIterator(AffineTransform at,
+ double flatness)
+ {
+ return new FlatteningPathIterator(getPathIterator(at), flatness);
+ }
+
+ public static class AppendingPathIterator implements PathIterator {
+ AffineTransform at;
+ PathIterator pi;
+ Shape swaiting;
+ int windingrule;
+ boolean connectrequested;
+ boolean canconnect;
+ boolean converttoline;
+
+ public AppendingPathIterator(Shape s1, Shape s2,
+ boolean connect,
+ AffineTransform at)
+ {
+ this.at = at;
+ this.pi = s1.getPathIterator(at);
+ this.swaiting = s2;
+ this.windingrule = pi.getWindingRule();
+ this.connectrequested = connect;
+
+ if (pi.isDone()) {
+ chain();
+ }
+ }
+
+ public void chain() {
+ if (swaiting != null) {
+ pi = swaiting.getPathIterator(at);
+ swaiting = null;
+ converttoline = (connectrequested && canconnect);
+ }
+ }
+
+ public int getWindingRule() {
+ return windingrule;
+ }
+
+ public boolean isDone() {
+ return (pi.isDone());
+ }
+
+ public void next() {
+ converttoline = false;
+ pi.next();
+ if (pi.isDone()) {
+ chain();
+ }
+ canconnect = true;
+ }
+
+ public int currentSegment(float[] coords) {
+ int type = pi.currentSegment(coords);
+ if (converttoline) {
+ type = SEG_LINETO;
+ }
+ return type;
+ }
+
+ public int currentSegment(double[] coords) {
+ int type = pi.currentSegment(coords);
+ if (converttoline) {
+ type = SEG_LINETO;
+ }
+ return type;
+ }
+ }
+ }
+
+ public static void checkEmpty(Path2D p2d, int windingrule) {
+ checkEmpty2(p2d, windingrule);
+ p2d.setWindingRule(PathIterator.WIND_NON_ZERO);
+ checkEmpty2(p2d, PathIterator.WIND_NON_ZERO);
+ p2d.setWindingRule(PathIterator.WIND_EVEN_ODD);
+ checkEmpty2(p2d, PathIterator.WIND_EVEN_ODD);
+ }
+
+ public static void checkEmpty2(Path2D p2d, int windingrule) {
+ if (p2d.getWindingRule() != windingrule) {
+ throw new RuntimeException("wrong winding rule in Path2D");
+ }
+ PathIterator pi = p2d.getPathIterator(null);
+ if (pi.getWindingRule() != windingrule) {
+ throw new RuntimeException("wrong winding rule in iterator");
+ }
+ if (!pi.isDone()) {
+ throw new RuntimeException("path not empty");
+ }
+ }
+
+ public static void compare(Creator c, Path2D p2d, Shape ref, int maxulp) {
+ compare(c, p2d, (Shape) p2d.clone(), null, 0);
+ compare(c, p2d, ref, null, 0);
+ compare(c, p2d, ref, TxIdentity, 0);
+ p2d.transform(TxIdentity);
+ compare(c, p2d, ref, null, 0);
+ compare(c, p2d, ref, TxIdentity, 0);
+ Shape s2 = p2d.createTransformedShape(TxIdentity);
+ compare(c, s2, ref, null, 0);
+ compare(c, s2, ref, TxIdentity, 0);
+ s2 = p2d.createTransformedShape(TxComplex);
+ compare(c, s2, ref, TxComplex, maxulp);
+ p2d.transform(TxComplex);
+ compare(c, p2d, (Shape) p2d.clone(), null, 0);
+ compare(c, p2d, ref, TxComplex, maxulp);
+ }
+
+ public static void compare(Creator c,
+ Shape p2d, Shape s,
+ AffineTransform at, int maxulp)
+ {
+ c.compare(p2d.getPathIterator(null), s.getPathIterator(at),
+ null, maxulp);
+ c.compare(p2d.getPathIterator(null), s.getPathIterator(null),
+ at, maxulp);
+ }
+
+ public static void checkBounds(Shape stest, Shape sref) {
+ checkBounds(stest.getBounds2D(), sref.getBounds2D(),
+ "2D bounds too small");
+ /*
+ checkBounds(stest.getBounds(), sref.getBounds(),
+ "int bounds too small");
+ */
+ checkBounds(stest.getBounds(), stest.getBounds2D(),
+ "int bounds too small for 2D bounds");
+ }
+
+ public static void checkBounds(Rectangle2D tBounds,
+ Rectangle2D rBounds,
+ String faildesc)
+ {
+ if (rBounds.isEmpty()) {
+ if (!tBounds.isEmpty()) {
+ throw new RuntimeException("bounds not empty");
+ }
+ return;
+ } else if (tBounds.isEmpty()) {
+ throw new RuntimeException("bounds empty");
+ }
+ double rxmin = rBounds.getMinX();
+ double rymin = rBounds.getMinY();
+ double rxmax = rBounds.getMaxX();
+ double rymax = rBounds.getMaxY();
+ double txmin = tBounds.getMinX();
+ double tymin = tBounds.getMinY();
+ double txmax = tBounds.getMaxX();
+ double tymax = tBounds.getMaxY();
+ if (txmin > rxmin || tymin > rymin ||
+ txmax < rxmax || tymax < rymax)
+ {
+ if (verbose) System.out.println("test bounds = "+tBounds);
+ if (verbose) System.out.println("ref bounds = "+rBounds);
+ // Allow fudge room of a couple of single precision ulps
+ double ltxmin = txmin - 5 * Math.max(Math.ulp((float) rxmin),
+ Math.ulp((float) txmin));
+ double ltymin = tymin - 5 * Math.max(Math.ulp((float) rymin),
+ Math.ulp((float) tymin));
+ double ltxmax = txmax + 5 * Math.max(Math.ulp((float) rxmax),
+ Math.ulp((float) txmax));
+ double ltymax = tymax + 5 * Math.max(Math.ulp((float) rymax),
+ Math.ulp((float) tymax));
+ if (ltxmin > rxmin || ltymin > rymin ||
+ ltxmax < rxmax || ltymax < rymax)
+ {
+ if (!verbose) System.out.println("test bounds = "+tBounds);
+ if (!verbose) System.out.println("ref bounds = "+rBounds);
+ System.out.println("xmin: "+
+ txmin+" + "+fltulpless(txmin, rxmin)+" = "+
+ rxmin+" + "+fltulpless(rxmin, txmin));
+ System.out.println("ymin: "+
+ tymin+" + "+fltulpless(tymin, rymin)+" = "+
+ rymin+" + "+fltulpless(rymin, tymin));
+ System.out.println("xmax: "+
+ txmax+" + "+fltulpless(txmax, rxmax)+" = "+
+ rxmax+" + "+fltulpless(rxmax, txmax));
+ System.out.println("ymax: "+
+ tymax+" + "+fltulpless(tymax, rymax)+" = "+
+ rymax+" + "+fltulpless(rymax, tymax));
+ System.out.println("flt tbounds = ["+
+ ((float) txmin)+", "+((float) tymin)+", "+
+ ((float) txmax)+", "+((float) tymax)+"]");
+ System.out.println("flt rbounds = ["+
+ ((float) rxmin)+", "+((float) rymin)+", "+
+ ((float) rxmax)+", "+((float) rymax)+"]");
+ System.out.println("xmin ulp = "+fltulpless(rxmin, txmin));
+ System.out.println("ymin ulp = "+fltulpless(rymin, tymin));
+ System.out.println("xmax ulp = "+fltulpless(txmax, rxmax));
+ System.out.println("ymax ulp = "+fltulpless(tymax, rymax));
+ throw new RuntimeException(faildesc);
+ }
+ }
+ }
+
+ public static void checkHits(Shape stest, Shape sref) {
+ for (int i = 0; i < 10; i++) {
+ double px = Math.random() * 500 - 250;
+ double py = Math.random() * 500 - 250;
+ Point2D pnt = new Point2D.Double(px, py);
+
+ double rw = Math.random()*10+0.4;
+ double rh = Math.random()*10+0.4;
+ double rx = px - rw/2;
+ double ry = py - rh/2;
+ Rectangle2D rect = new Rectangle2D.Double(rx, ry, rw, rh);
+ Rectangle2D empty = new Rectangle2D.Double(rx, ry, 0, 0);
+
+ if (!rect.contains(pnt)) {
+ throw new InternalError("test point not inside test rect!");
+ }
+
+ if (stest.contains(rx, ry, 0, 0)) {
+ throw new RuntimeException("contains 0x0 rect");
+ }
+ if (stest.contains(empty)) {
+ throw new RuntimeException("contains empty rect");
+ }
+ if (stest.intersects(rx, ry, 0, 0)) {
+ throw new RuntimeException("intersects 0x0 rect");
+ }
+ if (stest.intersects(empty)) {
+ throw new RuntimeException("intersects empty rect");
+ }
+
+ boolean tContainsXY = stest.contains(px, py);
+ boolean tContainsPnt = stest.contains(pnt);
+ boolean tContainsXYWH = stest.contains(rx, ry, rw, rh);
+ boolean tContainsRect = stest.contains(rect);
+ boolean tIntersectsXYWH = stest.intersects(rx, ry, rw, rh);
+ boolean tIntersectsRect = stest.intersects(rect);
+
+ if (tContainsXY != tContainsPnt) {
+ throw new RuntimeException("contains(x,y) != "+
+ "contains(pnt)");
+ }
+ if (tContainsXYWH != tContainsRect) {
+ throw new RuntimeException("contains(x,y,w,h) != "+
+ "contains(rect)");
+ }
+ if (tIntersectsXYWH != tIntersectsRect) {
+ throw new RuntimeException("intersects(x,y,w,h) != "+
+ "intersects(rect)");
+ }
+
+ boolean uContainsXY =
+ Path2D.contains(stest.getPathIterator(null), px, py);
+ boolean uContainsXYWH =
+ Path2D.contains(stest.getPathIterator(null), rx, ry, rw, rh);
+ boolean uIntersectsXYWH =
+ Path2D.intersects(stest.getPathIterator(null), rx, ry, rw, rh);
+
+ if (tContainsXY != uContainsXY) {
+ throw new RuntimeException("contains(x,y) "+
+ "does not match utility");
+ }
+ if (tContainsXYWH != uContainsXYWH) {
+ throw new RuntimeException("contains(x,y,w,h) "+
+ "does not match utility");
+ }
+ if (tIntersectsXYWH != uIntersectsXYWH) {
+ throw new RuntimeException("intersects(x,y,w,h) "+
+ "does not match utility");
+ }
+
+ // Make rect slightly smaller to be more conservative for rContains
+ double srx = rx + 0.1;
+ double sry = ry + 0.1;
+ double srw = rw - 0.2;
+ double srh = rh - 0.2;
+ Rectangle2D srect = new Rectangle2D.Double(srx, sry, srw, srh);
+ // Make rect slightly larger to be more liberal for rIntersects
+ double lrx = rx - 0.1;
+ double lry = ry - 0.1;
+ double lrw = rw + 0.2;
+ double lrh = rh + 0.2;
+ Rectangle2D lrect = new Rectangle2D.Double(lrx, lry, lrw, lrh);
+
+ if (srect.isEmpty()) {
+ throw new InternalError("smaller rect too small (empty)");
+ }
+ if (!lrect.contains(rect)) {
+ throw new InternalError("test rect not inside larger rect!");
+ }
+ if (!rect.contains(srect)) {
+ throw new InternalError("smaller rect not inside test rect!");
+ }
+
+ boolean rContainsSmaller;
+ boolean rIntersectsLarger;
+ boolean rContainsPnt;
+
+ if (sref instanceof SampleShape ||
+ sref instanceof QuadCurve2D ||
+ sref instanceof CubicCurve2D)
+ {
+ // REMIND
+ // Some of the source shapes are not proving reliable
+ // enough to do reference verification of the hit
+ // testing results.
+ // Quad/CubicCurve2D have spaghetti test methods that could
+ // very likely contain some bugs. They return a conflicting
+ // answer in maybe 1 out of 20,000 tests.
+ // Area causes a conflicting answer maybe 1 out of
+ // 100 to 1000 runs and it infinite loops maybe 1
+ // out of 10,000 runs or so.
+ // So, we use some conservative "safe" answers for
+ // these shapes and avoid their hit testing methods.
+ rContainsSmaller = tContainsRect;
+ rIntersectsLarger = tIntersectsRect;
+ rContainsPnt = tContainsPnt;
+ } else {
+ rContainsSmaller = sref.contains(srect);
+ rIntersectsLarger = sref.intersects(lrect);
+ rContainsPnt = sref.contains(px, py);
+ }
+
+ if (tIntersectsRect) {
+ if (tContainsRect) {
+ if (!tContainsPnt) {
+ System.out.println("reference shape = "+sref);
+ System.out.println("pnt = "+pnt);
+ System.out.println("rect = "+rect);
+ System.out.println("tbounds = "+stest.getBounds2D());
+ throw new RuntimeException("test contains rect, "+
+ "but not center point");
+ }
+ }
+ // Note: (tContainsPnt || tContainsRect) is same as
+ // tContainsPnt because of the test above...
+ if (tContainsPnt) {
+ if (!rIntersectsLarger) {
+ System.out.println("reference shape = "+sref);
+ System.out.println("pnt = "+pnt);
+ System.out.println("rect = "+rect);
+ System.out.println("lrect = "+lrect);
+ System.out.println("tbounds = "+stest.getBounds2D());
+ System.out.println("rbounds = "+sref.getBounds2D());
+ throw new RuntimeException("test claims containment, "+
+ "but no ref intersection");
+ }
+ }
+ } else {
+ if (tContainsRect) {
+ throw new RuntimeException("test contains rect, "+
+ "with no intersection");
+ }
+ if (tContainsPnt) {
+ System.out.println("reference shape = "+sref);
+ System.out.println("rect = "+rect);
+ throw new RuntimeException("test contains point, "+
+ "with no intersection");
+ }
+ if (rContainsPnt || rContainsSmaller) {
+ System.out.println("pnt = "+pnt);
+ System.out.println("rect = "+rect);
+ System.out.println("srect = "+lrect);
+ throw new RuntimeException("test did not intersect, "+
+ "but ref claims containment");
+ }
+ }
+ }
+ }
+
+ public static void test(Creator c) {
+ testConstructors(c);
+ testPathConstruction(c);
+ testAppend(c);
+ testBounds(c);
+ testHits(c);
+ }
+
+ public static void testConstructors(Creator c) {
+ checkEmpty(c.makePath(), WIND_NON_ZERO);
+ checkEmpty(c.makePath(WIND_NON_ZERO), WIND_NON_ZERO);
+ checkEmpty(c.makePath(WIND_EVEN_ODD), WIND_EVEN_ODD);
+ checkEmpty(c.makePath(EmptyShapeNonZero), WIND_NON_ZERO);
+ checkEmpty(c.makePath(EmptyShapeNonZero, null), WIND_NON_ZERO);
+ checkEmpty(c.makePath(EmptyShapeNonZero, TxIdentity), WIND_NON_ZERO);
+ checkEmpty(c.makePath(EmptyShapeEvenOdd), WIND_EVEN_ODD);
+ checkEmpty(c.makePath(EmptyShapeEvenOdd, null), WIND_EVEN_ODD);
+ checkEmpty(c.makePath(EmptyShapeEvenOdd, TxIdentity), WIND_EVEN_ODD);
+ try {
+ c.makePath(null);
+ throw new RuntimeException(c+" allowed null Shape in constructor");
+ } catch (NullPointerException npe) {
+ // passes
+ }
+ try {
+ c.makePath(null, TxIdentity);
+ throw new RuntimeException(c+" allowed null Shape in constructor");
+ } catch (NullPointerException npe) {
+ // passes
+ }
+
+ for (int i = 0; i < TestShapes.length; i++) {
+ Shape sref = TestShapes[i];
+ if (verbose) System.out.println("construct testing "+sref);
+ compare(c, c.makePath(sref), sref, null, 0);
+ compare(c, c.makePath(sref), sref, TxIdentity, 0);
+ compare(c, c.makePath(sref, null), sref, null, 0);
+ compare(c, c.makePath(sref, null), sref, TxIdentity, 0);
+ compare(c, c.makePath(sref, TxIdentity), sref, null, 0);
+ compare(c, c.makePath(sref, TxIdentity), sref, TxIdentity, 0);
+ compare(c, c.makePath(sref, TxComplex), sref, TxComplex,
+ c.getRecommendedTxMaxUlp());
+ }
+ }
+
+ public static void testPathConstruction(Creator c) {
+ testPathConstruction(c, LongSampleNonZero);
+ testPathConstruction(c, LongSampleEvenOdd);
+ }
+
+ public static void testPathConstruction(Creator c, SampleShape ref) {
+ if (c.supportsFloatCompose()) {
+ compare(c, ref.makeFloatPath(c), ref, c.getRecommendedTxMaxUlp());
+ }
+ compare(c, ref.makeDoublePath(c), ref, c.getRecommendedTxMaxUlp());
+ }
+
+ public static void testAppend(Creator c) {
+ for (int i = 0; i < TestShapes.length; i++) {
+ Shape sref = TestShapes[i];
+ if (verbose) System.out.println("append testing "+sref);
+ PathIterator spi = sref.getPathIterator(null);
+ Path2D stest = c.makePath(spi.getWindingRule());
+ stest.append(spi, false);
+ compare(c, stest, sref, null, 0);
+ stest.reset();
+ stest.append(sref, false);
+ compare(c, stest, sref, null, 0);
+ stest.reset();
+ stest.append(sref.getPathIterator(TxComplex), false);
+ compare(c, stest, sref, TxComplex, 0);
+ // multiple shape append testing...
+ if (sref.getBounds2D().isEmpty()) {
+ // If the first shape is empty, then we really
+ // are not testing multiple appended shapes,
+ // we are just testing appending the AppendShape
+ // to a null path over and over.
+ // Also note that some empty shapes will spit out
+ // a single useless SEG_MOVETO that has no affect
+ // on the outcome, but it makes duplicating the
+ // behavior that Path2D has in that case difficult
+ // when the AppenedShape utility class has to
+ // iterate the exact same segments. So, we will
+ // just ignore all empty shapes here.
+ continue;
+ }
+ stest.reset();
+ stest.append(sref, false);
+ stest.append(AppendShape, false);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, false),
+ null, 0);
+ stest.reset();
+ stest.append(sref, false);
+ stest.append(AppendShape, true);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, true),
+ null, 0);
+ stest.reset();
+ stest.append(sref.getPathIterator(null), false);
+ stest.append(AppendShape.getPathIterator(null), false);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, false),
+ null, 0);
+ stest.reset();
+ stest.append(sref.getPathIterator(null), false);
+ stest.append(AppendShape.getPathIterator(null), true);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, true),
+ null, 0);
+ stest.reset();
+ stest.append(sref.getPathIterator(TxComplex), false);
+ stest.append(AppendShape.getPathIterator(TxComplex), false);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, false),
+ TxComplex, 0);
+ stest.reset();
+ stest.append(sref.getPathIterator(TxComplex), false);
+ stest.append(AppendShape.getPathIterator(TxComplex), true);
+ compare(c, stest,
+ new AppendedShape(sref, AppendShape, true),
+ TxComplex, 0);
+ }
+ }
+
+ public static void testBounds(Creator c) {
+ for (int i = 0; i < TestShapes.length; i++) {
+ Shape sref = TestShapes[i];
+ if (verbose) System.out.println("bounds testing "+sref);
+ Shape stest = c.makePath(sref);
+ checkBounds(c.makePath(sref), sref);
+ }
+ testBounds(c, ShortSampleNonZero);
+ testBounds(c, ShortSampleEvenOdd);
+ testBounds(c, LongSampleNonZero);
+ testBounds(c, LongSampleEvenOdd);
+ }
+
+ public static void testBounds(Creator c, SampleShape ref) {
+ if (verbose) System.out.println("bounds testing "+ref);
+ if (c.supportsFloatCompose()) {
+ checkBounds(ref.makeFloatPath(c), ref);
+ }
+ checkBounds(ref.makeDoublePath(c), ref);
+ }
+
+ public static void testHits(Creator c) {
+ for (int i = 0; i < TestShapes.length; i++) {
+ Shape sref = TestShapes[i];
+ if (verbose) System.out.println("hit testing "+sref);
+ Shape stest = c.makePath(sref);
+ checkHits(c.makePath(sref), sref);
+ }
+ testHits(c, ShortSampleNonZero);
+ testHits(c, ShortSampleEvenOdd);
+ // These take too long to construct the Area for reference testing
+ //testHits(c, LongSampleNonZero);
+ //testHits(c, LongSampleEvenOdd);
+ }
+
+ public static void testHits(Creator c, SampleShape ref) {
+ if (verbose) System.out.println("hit testing "+ref);
+ if (c.supportsFloatCompose()) {
+ checkHits(ref.makeFloatPath(c), ref);
+ }
+ checkHits(ref.makeDoublePath(c), ref);
+ }
+
+ public static void main(String argv[]) {
+ int limit = (argv.length > 0) ? 10000 : 1;
+ verbose = (argv.length > 1);
+ for (int i = 0; i < limit; i++) {
+ if (limit > 1) {
+ System.out.println("loop #"+(i+1));
+ }
+ init();
+ test(new GPCreator());
+ test(new FltCreator());
+ test(new DblCreator());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/QuadCurve2D/Quad2DContainsTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2003, 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 4682078
+ * @summary QuadCurve2D contains() returns true for far away point
+ */
+
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+
+public class Quad2DContainsTest {
+
+ static Object[][] trues = {
+ {
+ new QuadCurve2D.Double(0, 0, 50, 200, 100, 0),
+ new Point2D.Double(50, 50)
+ },
+ {
+ new QuadCurve2D.Double(0, 100, 100, 100, 100, 0),
+ new Point2D.Double(50, 50)
+ }
+ };
+ static Object[][] falses = {
+ {
+ new QuadCurve2D.Double(0, 0, 50, 200, 100, 0),
+ new Point2D.Double(0, 50)
+ },
+ {
+ new QuadCurve2D.Double(0, 0, 50, 200, 100, 0),
+ new Point2D.Double(100, 50)
+ },
+ {
+ new QuadCurve2D.Double(0, 0, 0, 100, 100, 100),
+ new Point2D.Double(0, 100)
+ },
+ {
+ new QuadCurve2D.Double(0, 0, 60, 60, 100, 100),
+ new Point2D.Double(30, 30)
+ }
+ };
+
+ public static void main(String[] args) {
+
+ for (int i = 0; i < trues.length; i++) {
+ checkPair((QuadCurve2D)trues[i][0], (Point2D)trues[i][1], true);
+ }
+
+ for (int i = 0; i < falses.length; i++) {
+ checkPair((QuadCurve2D)falses[i][0], (Point2D)falses[i][1], false);
+ }
+ }
+
+ public static void checkPair(QuadCurve2D q, Point2D p, boolean expect) {
+
+ if (q.contains(p.getX(), p.getY()) != expect) {
+ String errMsg = "QuadCurve2D " +
+ "p1 = (" + q.getX1() + ", " + q.getY1() + ") " +
+ "p2 = (" + q.getX2() + ", " + q.getY2() + ") " +
+ "control = (" + q.getCtrlX() + ", " +
+ q.getCtrlY() + ") " +
+ "should " + (expect ? "" : "not ") +
+ "contain the point (" +
+ p.getX() + ", " + p.getY() + "), " +
+ "but method returns wrong value!";
+ throw new RuntimeException(errMsg);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Rectangle2D/CreateIntersectBug.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001, 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 4374642
+ * @summary Verifies that the Rectangle2D.createIntersection method produces
+ * an empty result rectangle if the two source rects did not intersect
+ */
+
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.Rectangle2D;
+
+public class CreateIntersectBug extends Canvas {
+ public static boolean showresults = false;
+
+ public static RuntimeException t = null;
+
+ public static void main(String[] args) {
+ showresults = (args.length > 0);
+ test(50, 50, 20, 20, 100, 100, 100, 100);
+ test(-100, -100, 50, 50, 100, 100, 50, 50);
+ if (t != null) {
+ throw t;
+ }
+ }
+
+ public static void test(int x1, int y1, int w1, int h1,
+ int x2, int y2, int w2, int h2)
+ {
+ Rectangle2D r1 = new Rectangle2D.Double(x1, y1, w1, h1);
+ Rectangle2D r2 = new Rectangle2D.Double(x2, y2, w2, h2);
+
+ write(r1, "R1");
+ write(r2, "R2");
+ if (r1.intersects(r2)) {
+ System.out.println("r1 and r2 intersect");
+ } else {
+ System.out.println("r1 and r2 don't intersect");
+ }
+ Rectangle2D r3 = r1.createIntersection(r2);
+ write(r3, "intersect");
+
+ Rectangle2D r4 = r1.createUnion(r2);
+ write(r4, "union");
+
+ if (showresults) {
+ new CreateIntersectBug(r1, r2, r3, r4);
+ }
+ if (!r1.intersects(r2) && !r3.isEmpty()) {
+ String s = ("Intersection of non-intersecting "+
+ "rectangles is not empty!");
+ t = new RuntimeException(s);
+ System.out.println(s);
+ }
+ }
+
+ private Rectangle2D r1, r2, r3, r4;
+
+ public CreateIntersectBug(Rectangle2D r1, Rectangle2D r2,
+ Rectangle2D r3, Rectangle2D r4)
+ {
+ this.r1 = r1;
+ this.r2 = r2;
+ this.r3 = r3;
+ this.r4 = r4;
+
+ Frame f = new Frame();
+ f.add(this);
+ f.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {System.exit(0);}
+ });
+ f.pack();
+ f.show();
+ }
+
+ public Dimension getPreferredSize() {
+ return new Dimension(500, 500);
+ }
+
+
+ public void paint(Graphics g){
+ Graphics2D g2 = (Graphics2D) g;
+
+ // graphic aids to understanding - these have no
+ // effect on the problem.
+ if (!r1.intersects(r2) && !r3.isEmpty()) {
+ g2.setColor(Color.red);
+ } else {
+ g2.setColor(Color.green);
+ }
+ g2.draw(r3);
+ g2.setColor(Color.yellow);
+ g2.draw(r4);
+ g2.setColor(Color.blue);
+ g2.draw(r1);
+ g2.draw(r2);
+ }
+
+ public static void write(Rectangle2D r, String s) {
+ System.out.println(s + ": (" +
+ (int)r.getX() + "," + (int)r.getY() + ","
+ + (int)r.getWidth() + "," + (int)r.getHeight() +
+ ")");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/Rectangle2D/IntersectsLineHang.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2000, 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 4320890
+ * @summary Verifies that the Rectangle2D.intersectsLine method does not hang
+ * or return bad results due to inaccuracies in the outcode methods
+ * @run main/timeout=5 IntersectsLineHang
+ */
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+
+public class IntersectsLineHang {
+ static public void main(String args[]) {
+ Rectangle r = new Rectangle(0x70000000, 0x70000000,
+ 0x20000000, 0x0f000000);
+ double v = 0x78000000;
+ System.out.println("Point alpha");
+ boolean result = r.intersectsLine(v, v, v+v, v+v);
+ System.out.println(result);
+ Rectangle2D rect = new Rectangle2D.Float(29.790712356567383f,
+ 362.3290710449219f,
+ 267.40679931640625f,
+ 267.4068298339844f);
+ System.out.println("Point A");
+ System.out.println(rect.intersectsLine(431.39777, 551.3534,
+ 26.391, 484.71542));
+ System.out.println("Point A2");
+ System.out.println(rect.intersectsLine(431.39777, 551.3534,
+ 268.391, 484.71542));
+ System.out.println("Point B: Never gets here!");
+ if (!result) {
+ // failure of integer rectangle intersection test
+ throw new RuntimeException("integer rectangle "+
+ "failed intersection test");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/geom/SerialTest.java Tue May 22 17:33:31 2018 -0700
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2005, 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 4263142 4172661
+ * @summary First run verifies that objects serialize and deserialize
+ * correctly against the current release.
+ * Second run verifies that objects from previous releases
+ * still deserialize correctly. The serial_1_6.out file was
+ * created using the "write" option under release 1.6.
+ * The test was modified after fixing 4172661 to add testing
+ * of Path2D serialization (and to recut the test file with
+ * the new serialVersionUID of GeneralPath).
+ * @run main SerialTest
+ * @run main SerialTest read serial_1_6.out
+ */
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+public class SerialTest {
+ public static Object testobjects[] = {
+ // non-shapes...
+ new Point2D.Float(37, 42),
+ new Point2D.Double(85, 63),
+ new AffineTransform(10, 20, 30, 40, 50, 60),
+
+ // shapes...
+ new QuadCurve2D.Float(10f, 10f, 50f, 50f, 100f, 10f),
+ new QuadCurve2D.Double(20f, 20f, 50f, 50f, 100f, 20f),
+ new CubicCurve2D.Float(10f, 10f, 50f, 10f, 10f, 50f, 50f, 50f),
+ new CubicCurve2D.Double(0.0, 0.0, 50.0, 0.0, 0.0, 50.0, 50.0, 50.0),
+ new GeneralPath(),
+ new GeneralPath(PathIterator.WIND_NON_ZERO),
+ new GeneralPath(PathIterator.WIND_EVEN_ODD),
+ makeGeneralPath(PathIterator.WIND_NON_ZERO, 5f),
+ makeGeneralPath(PathIterator.WIND_EVEN_ODD, 23f),
+ new Line2D.Float(20f, 20f, 25f, 50f),
+ new Line2D.Double(20.0, 20.0, 35.0, 50.0),
+ new Rectangle2D.Float(100f, 100f, 50f, 25f),
+ new Rectangle2D.Double(200.0, 200.0, 75.0, 35.0),
+ new RoundRectangle2D.Float(120f, 120f, 50f, 35f, 5f, 7f),
+ new RoundRectangle2D.Double(220.0, 220.0, 85.0, 45.0, 3.0, 9.0),
+ new Ellipse2D.Float(110f, 110f, 50f, 55f),
+ new Ellipse2D.Double(210.0, 210.0, 75.0, 45.0),
+ new Arc2D.Float(10f, 10f, 50f, 40f, 45f, 72f, Arc2D.OPEN),
+ new Arc2D.Float(10f, 10f, 40f, 50f, 135f, 72f, Arc2D.PIE),
+ new Arc2D.Float(10f, 10f, 40f, 60f, 225f, 72f, Arc2D.CHORD),
+ new Arc2D.Double(10.0, 20.0, 50.0, 40.0, 45.0, 72.0, Arc2D.OPEN),
+ new Arc2D.Double(10.0, 20.0, 40.0, 50.0, 135.0, 72.0, Arc2D.PIE),
+ new Arc2D.Double(10.0, 20.0, 40.0, 60.0, 225.0, 72.0, Arc2D.CHORD),
+
+ // Paths
+ new Path2D.Float(),
+ new Path2D.Float(PathIterator.WIND_NON_ZERO),
+ new Path2D.Float(PathIterator.WIND_EVEN_ODD),
+ makePath2DFloat(PathIterator.WIND_NON_ZERO, 5f),
+ makePath2DFloat(PathIterator.WIND_EVEN_ODD, 23f),
+ new Path2D.Double(),
+ new Path2D.Double(PathIterator.WIND_NON_ZERO),
+ new Path2D.Double(PathIterator.WIND_EVEN_ODD),
+ makePath2DDouble(PathIterator.WIND_NON_ZERO, 5f),
+ makePath2DDouble(PathIterator.WIND_EVEN_ODD, 23f),
+ };
+
+ public static Shape makeGeneralPath(int winding, float off) {
+ return fill(new GeneralPath(winding), off);
+ }
+
+ public static Shape makePath2DFloat(int winding, float off) {
+ return fill(new Path2D.Float(winding), off);
+ }
+
+ public static Shape makePath2DDouble(int winding, float off) {
+ return fill(new Path2D.Double(winding), off);
+ }
+
+ public static Path2D fill(Path2D p2d, float off) {
+ p2d.moveTo(off+10, off+10);
+ p2d.lineTo(off+100, off+50);
+ p2d.quadTo(off+50, off+100, off+200, off+100);
+ p2d.curveTo(off+400, off+20, off+20, off+400, off+100, off+100);
+ p2d.closePath();
+ return p2d;
+ }
+
+ static int numerrors;
+
+ public static void error(Object o1, Object o2, String reason) {
+ System.err.println("Failed comparing: "+o1+" to "+o2);
+ System.err.println(reason);
+ numerrors++;
+ }
+
+ public static void usage(int exitcode) {
+ System.err.println("usage: java SerialTest [read|write] <filename>");
+ System.exit(exitcode);
+ }
+
+ public static void main(String argv[]) {
+ if (argv.length > 0) {
+ if (argv.length < 2) {
+ usage(1);
+ }
+
+ String arg = argv[0].toLowerCase();
+ if (arg.equals("write")) {
+ serializeTo(argv[1]);
+ } else if (arg.equals("read")) {
+ testFrom(argv[1]);
+ } else {
+ usage(1);
+ }
+ } else {
+ testSerial();
+ }
+ }
+
+ public static File makeFile(String filename) {
+ return new File(System.getProperty("test.src", "."), filename);
+ }
+
+ public static void serializeTo(String filename) {
+ FileOutputStream fos;
+ try {
+ fos = new FileOutputStream(makeFile(filename));
+ } catch (IOException ioe) {
+ throw new InternalError("bad output filename: "+filename);
+ }
+ serializeTo(fos);
+ }
+
+ public static void testFrom(String filename) {
+ FileInputStream fis;
+ try {
+ fis = new FileInputStream(makeFile(filename));
+ } catch (IOException ioe) {
+ throw new InternalError("bad input filename: "+filename);
+ }
+ testFrom(fis);
+ }
+
+ public static void testSerial() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ serializeTo(baos);
+
+ byte buf[] = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+
+ testFrom(bais);
+ }
+
+ public static void serializeTo(OutputStream os) {
+ try {
+ ObjectOutputStream oos = new ObjectOutputStream(os);
+
+ for (Object o1: testobjects) {
+ oos.writeObject(o1);
+ }
+
+ oos.close();
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ public static void testFrom(InputStream is) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream(is);
+
+ for (Object o1: testobjects) {
+ Object o2 = ois.readObject();
+ if (o1 instanceof Shape) {
+ compareShapes((Shape) o1, (Shape) o2);
+ } else {
+ if (!o1.equals(o2)) {
+ error(o1, o2, "objects not equal");
+ }
+ }
+ }
+
+ try {
+ ois.readObject();
+ throw new RuntimeException("extra data in stream");
+ } catch (IOException ioe2) {
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ } catch (ClassNotFoundException cnfe) {
+ throw new RuntimeException(cnfe);
+ }
+ }
+
+ public static void compareShapes(Shape s1, Shape s2) {
+ PathIterator pi1 = s1.getPathIterator(null);
+ PathIterator pi2 = s2.getPathIterator(null);
+
+ if (pi1.getWindingRule() != pi2.getWindingRule()) {
+ error(s1, s2, "winding rules are different");
+ }
+
+ double coords1[] = new double[6];
+ double coords2[] = new double[6];
+
+ while (!pi1.isDone()) {
+ if (pi2.isDone()) {
+ error(s1, s2, "Shape 2 ended prematurely");
+ return;
+ }
+
+ int t1 = pi1.currentSegment(coords1);
+ int t2 = pi2.currentSegment(coords2);
+
+ if (t1 != t2) {
+ error(s1, s2, "different segment types");
+ }
+
+ int ncoords;
+ switch (t1) {
+ case PathIterator.SEG_MOVETO: ncoords = 2; break;
+ case PathIterator.SEG_LINETO: ncoords = 2; break;
+ case PathIterator.SEG_QUADTO: ncoords = 4; break;
+ case PathIterator.SEG_CUBICTO: ncoords = 6; break;
+ case PathIterator.SEG_CLOSE: ncoords = 0; break;
+
+ default:
+ throw new RuntimeException("unknown segment type");
+ }
+
+ for (int i = 0; i < ncoords; i++) {
+ if (coords1[i] != coords2[i]) {
+ error(s1, s2, "coordinates differ");
+ }
+ }
+ pi1.next();
+ pi2.next();
+ }
+
+ if (!pi2.isDone()) {
+ error(s1, s2, "Shape 1 ended prematurely");
+ }
+ }
+}
Binary file test/jdk/java/awt/geom/serial_1_6.out has changed