< prev index next >

test/sun/java2d/marlin/CrashNaNTest.java

Print this page

        

@@ -19,28 +19,37 @@
  * 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.
  */
 
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
 import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
 import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
 import java.io.File;
 import java.io.IOException;
+import static java.lang.Double.NEGATIVE_INFINITY;
+import static java.lang.Double.POSITIVE_INFINITY;
 import static java.lang.Double.NaN;
+import java.util.Arrays;
 import java.util.Locale;
 import java.util.logging.Handler;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 import javax.imageio.ImageIO;
 
 /**
  * @test
- * @bug 8149338
- * @summary Verifies that Marlin supports NaN coordinates and no JVM crash happens !
+ * @bug 8149338 8144938
+ * @summary Verifies that Marlin supports NaN coordinates (no JVM crash)
+ * but also it skips properly point coordinates with NaN / Infinity values
  * @run main CrashNaNTest
  */
 public class CrashNaNTest {
 
     static final boolean SAVE_IMAGE = false;

@@ -75,27 +84,35 @@
         // enable Marlin logging & internal checks:
         System.setProperty("sun.java2d.renderer.log", "true");
         System.setProperty("sun.java2d.renderer.useLogger", "true");
         System.setProperty("sun.java2d.renderer.doChecks", "true");
 
+        testFillDefaultAt();
+        testDrawComplexAt();
+
+        testPathClosed();
+
+        testStrokedShapes();
+    }
+
+    private static void testFillDefaultAt() {
         final int width = 400;
         final int height = 400;
 
         final BufferedImage image = new BufferedImage(width, height,
-                BufferedImage.TYPE_INT_ARGB);
+                                            BufferedImage.TYPE_INT_ARGB);
 
         final Graphics2D g2d = (Graphics2D) image.getGraphics();
         try {
             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-                    RenderingHints.VALUE_ANTIALIAS_ON);
+                                 RenderingHints.VALUE_ANTIALIAS_ON);
 
             g2d.setBackground(Color.WHITE);
             g2d.clearRect(0, 0, width, height);
 
             final Path2D.Double path = new Path2D.Double();
-            path.moveTo(30, 30);
-            path.lineTo(100, 100);
+            path.moveTo(100, 100);
 
             for (int i = 0; i < 20000; i++) {
                 path.lineTo(110 + 0.01 * i, 110);
                 path.lineTo(111 + 0.01 * i, 100);
             }

@@ -103,41 +120,322 @@
             path.lineTo(NaN, 200);
             path.lineTo(200, 200);
             path.lineTo(200, NaN);
             path.lineTo(300, 300);
             path.lineTo(NaN, NaN);
-            path.lineTo(100, 100);
+            path.lineTo(100, 200);
             path.closePath();
 
             final Path2D.Double path2 = new Path2D.Double();
-            path2.moveTo(0,0);
-            path2.lineTo(width,height);
-            path2.lineTo(10, 10);
+            path2.moveTo(0, 0);
+            path2.lineTo(100, height);
+            path2.lineTo(0, 200);
             path2.closePath();
 
             for (int i = 0; i < 1; i++) {
                 final long start = System.nanoTime();
                 g2d.setColor(Color.BLUE);
                 g2d.fill(path);
-
+                g2d.setColor(Color.GREEN);
                 g2d.fill(path2);
 
+                g2d.setColor(Color.BLACK);
+                g2d.draw(path);
+                g2d.draw(path2);
+
                 final long time = System.nanoTime() - start;
                 System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
             }
 
             if (SAVE_IMAGE) {
                 try {
-                    final File file = new File("CrashNaNTest.png");
+                    final File file = new File("CrashNaNTest-fill.png");
                     System.out.println("Writing file: "
-                            + file.getAbsolutePath());
+                                       + file.getAbsolutePath());
                     ImageIO.write(image, "PNG", file);
                 } catch (IOException ex) {
                     System.out.println("Writing file failure:");
                     ex.printStackTrace();
                 }
             }
+
+            // Check image on few pixels:
+            final Raster raster = image.getData();
+
+            checkPixel(raster, 200, 195, Color.BLUE.getRGB());
+            checkPixel(raster, 105, 195, Color.BLUE.getRGB());
+            checkPixel(raster, 286, 290, Color.BLUE.getRGB());
+
+            checkPixel(raster, 108, 105, Color.WHITE.getRGB());
+            checkPixel(raster, 205, 200, Color.WHITE.getRGB());
+
+            checkPixel(raster, 5, 200, Color.GREEN.getRGB());
+
         } finally {
             g2d.dispose();
         }
     }
+
+    private static void testDrawComplexAt() {
+        final int width = 400;
+        final int height = 400;
+
+        final BufferedImage image = new BufferedImage(width, height,
+                                            BufferedImage.TYPE_INT_ARGB);
+
+        final Graphics2D g2d = (Graphics2D) image.getGraphics();
+        try {
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                 RenderingHints.VALUE_ANTIALIAS_ON);
+            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+                                 RenderingHints.VALUE_STROKE_PURE);
+
+            g2d.setBackground(Color.WHITE);
+            g2d.clearRect(0, 0, width, height);
+
+            final Path2D.Double path = new Path2D.Double();
+            path.moveTo(100, 100);
+
+            for (int i = 0; i < 20000; i++) {
+                path.lineTo(110 + 0.01 * i, 110);
+                path.lineTo(111 + 0.01 * i, 100);
+            }
+
+            path.lineTo(NaN, 200);
+            path.lineTo(200, 200);
+            path.lineTo(200, NaN);
+            path.lineTo(300, 300);
+            path.lineTo(NaN, NaN);
+            path.lineTo(100, 200);
+            path.closePath();
+
+            final Path2D.Double path2 = new Path2D.Double();
+            path2.moveTo(0, 0);
+            path2.lineTo(100, height);
+            path2.lineTo(0, 200);
+            path2.closePath();
+
+            // Define an non-uniform transform:
+            g2d.scale(0.5, 1.0);
+            g2d.rotate(Math.PI / 31);
+
+            for (int i = 0; i < 1; i++) {
+                final long start = System.nanoTime();
+
+                g2d.setColor(Color.BLACK);
+                g2d.draw(path);
+                g2d.draw(path2);
+
+                final long time = System.nanoTime() - start;
+                System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
+            }
+
+            if (SAVE_IMAGE) {
+                try {
+                    final File file = new File("CrashNaNTest-draw.png");
+                    System.out.println("Writing file: "
+                                       + file.getAbsolutePath());
+                    ImageIO.write(image, "PNG", file);
+                } catch (IOException ex) {
+                    System.out.println("Writing file failure:");
+                    ex.printStackTrace();
+                }
+            }
+
+            // Check image on few pixels:
+            final Raster raster = image.getData();
+
+            checkPixelNotWhite(raster, 40, 210);
+            checkPixelNotWhite(raster, 44, 110);
+            checkPixelNotWhite(raster, 60, 120);
+            checkPixelNotWhite(raster, 89, 219);
+            checkPixelNotWhite(raster, 28, 399);
+            checkPixelNotWhite(raster, 134, 329);
+
+        } finally {
+            g2d.dispose();
+        }
+    }
+    private static void testPathClosed() {
+        final int width = 100;
+        final int height = 100;
+
+        final BufferedImage image = new BufferedImage(width, height,
+                                            BufferedImage.TYPE_INT_ARGB);
+
+        final Graphics2D g2d = (Graphics2D) image.getGraphics();
+        try {
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                 RenderingHints.VALUE_ANTIALIAS_ON);
+
+            g2d.setBackground(Color.WHITE);
+            g2d.clearRect(0, 0, width, height);
+
+            final Path2D.Double path = new Path2D.Double();
+            path.moveTo(40, 40);
+            path.lineTo(0,   0);
+            path.lineTo(80, 0);
+            path.closePath();
+            path.lineTo(80, 80);
+            path.lineTo(0, 80);
+            path.closePath();
+
+            for (int i = 0; i < 1; i++) {
+                final long start = System.nanoTime();
+                g2d.setColor(Color.BLUE);
+                g2d.fill(path);
+
+                g2d.setColor(Color.BLACK);
+                g2d.draw(path);
+
+                final long time = System.nanoTime() - start;
+                System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
+            }
+
+            if (SAVE_IMAGE) {
+                try {
+                    final File file = new File("CrashNaNTest-path-closed.png");
+                    System.out.println("Writing file: "
+                                       + file.getAbsolutePath());
+                    ImageIO.write(image, "PNG", file);
+                } catch (IOException ex) {
+                    System.out.println("Writing file failure:");
+                    ex.printStackTrace();
+                }
+            }
+
+            // Check image on few pixels:
+            final Raster raster = image.getData();
+
+            checkPixel(raster, 10, 05, Color.BLUE.getRGB());
+            checkPixel(raster, 70, 05, Color.BLUE.getRGB());
+            checkPixel(raster, 40, 35, Color.BLUE.getRGB());
+
+            checkPixel(raster, 10, 75, Color.BLUE.getRGB());
+            checkPixel(raster, 70, 75, Color.BLUE.getRGB());
+            checkPixel(raster, 40, 45, Color.BLUE.getRGB());
+
+        } finally {
+            g2d.dispose();
+        }
+    }
+
+    private static void testStrokedShapes() {
+        final Stroke stroke = new BasicStroke();
+
+        final Path2D.Double path = new Path2D.Double();
+        Shape s;
+
+        // Check filtering NaN values:
+        path.reset();
+        path.moveTo(100, NaN);
+        path.lineTo(NaN, 100);
+        path.lineTo(NaN, NaN);
+
+        path.quadTo(NaN, 100, NaN, 100);
+        path.quadTo(100, NaN, 100, NaN);
+        path.quadTo(NaN, NaN, NaN, NaN);
+
+        path.curveTo(NaN, 100, NaN, 100, NaN, 100);
+        path.curveTo(100, NaN, 100, NaN, 100, NaN);
+        path.curveTo(NaN, NaN, NaN, NaN, NaN, NaN);
+        path.closePath();
+
+        s = stroke.createStrokedShape(path);
+        checkEmptyPath(s);
+
+        // Check filtering +Infinity values:
+        path.reset();
+        path.moveTo(100, POSITIVE_INFINITY);
+        path.lineTo(POSITIVE_INFINITY, 100);
+        path.lineTo(POSITIVE_INFINITY, POSITIVE_INFINITY);
+
+        path.quadTo(POSITIVE_INFINITY, 100,
+                    POSITIVE_INFINITY, 100);
+        path.quadTo(100, POSITIVE_INFINITY,
+                    100, POSITIVE_INFINITY);
+        path.quadTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
+                    POSITIVE_INFINITY, POSITIVE_INFINITY);
+
+        path.curveTo(POSITIVE_INFINITY, 100,
+                     POSITIVE_INFINITY, 100,
+                     POSITIVE_INFINITY, 100);
+        path.curveTo(100, POSITIVE_INFINITY,
+                     100, POSITIVE_INFINITY,
+                     100, POSITIVE_INFINITY);
+        path.curveTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
+                     POSITIVE_INFINITY, POSITIVE_INFINITY,
+                     POSITIVE_INFINITY, POSITIVE_INFINITY);
+        path.closePath();
+
+        s = stroke.createStrokedShape(path);
+        checkEmptyPath(s);
+
+        // Check filtering -Infinity values:
+        path.reset();
+        path.moveTo(100, NEGATIVE_INFINITY);
+        path.lineTo(NEGATIVE_INFINITY, 100);
+        path.lineTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+
+        path.quadTo(NEGATIVE_INFINITY, 100,
+                    NEGATIVE_INFINITY, 100);
+        path.quadTo(100, NEGATIVE_INFINITY,
+                    100, NEGATIVE_INFINITY);
+        path.quadTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+                    NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+
+        path.curveTo(NEGATIVE_INFINITY, 100,
+                     NEGATIVE_INFINITY, 100,
+                     NEGATIVE_INFINITY, 100);
+        path.curveTo(100, NEGATIVE_INFINITY,
+                     100, NEGATIVE_INFINITY,
+                     100, NEGATIVE_INFINITY);
+        path.curveTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+                     NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+                     NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+        path.closePath();
+
+        s = stroke.createStrokedShape(path);
+        checkEmptyPath(s);
+    }
+
+    private static void checkEmptyPath(final Shape s) {
+        final float[] coords = new float[6];
+        final PathIterator it = s.getPathIterator(null);
+
+        int n = 0;
+        for (; !it.isDone(); it.next()) {
+            int type = it.currentSegment(coords);
+            System.out.println("unexpected segment type= " + type
+                 + " with coords: " + Arrays.toString(coords));
+            n++;
+        }
+        if (n != 0) {
+            System.out.println("path elements = " + n);
+            throw new IllegalStateException("Not empty path: "
+                          + n + " path elements !");
+        }
+    }
+
+    private static void checkPixel(final Raster raster,
+                                   final int x, final int y,
+                                   final int expected) {
+
+        final int[] rgb = (int[]) raster.getDataElements(x, y, null);
+
+        if (rgb[0] != expected) {
+            throw new IllegalStateException("bad pixel at (" + x + ", " + y
+                          + ") = " + rgb[0] + " expected: " + expected);
+        }
+    }
+
+    private static void checkPixelNotWhite(final Raster raster,
+                                           final int x, final int y) {
+
+        final int[] rgb = (int[]) raster.getDataElements(x, y, null);
+
+        if (rgb[0] == Color.WHITE.getRGB()) {
+            throw new IllegalStateException("bad pixel at (" + x + ", " + y
+                          + ") is white (empty)");
+        }
+    }
 }
< prev index next >