< prev index next >

test/sun/java2d/marlin/CrashNaNTest.java

Print this page

        

*** 19,46 **** * 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.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Path2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import static java.lang.Double.NaN; 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 ! * @run main CrashNaNTest */ public class CrashNaNTest { static final boolean SAVE_IMAGE = false; --- 19,55 ---- * 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 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,101 **** // 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"); 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.setBackground(Color.WHITE); g2d.clearRect(0, 0, width, height); final Path2D.Double path = new Path2D.Double(); ! path.moveTo(30, 30); ! path.lineTo(100, 100); for (int i = 0; i < 20000; i++) { path.lineTo(110 + 0.01 * i, 110); path.lineTo(111 + 0.01 * i, 100); } --- 84,118 ---- // 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); 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(100, 100); for (int i = 0; i < 20000; i++) { path.lineTo(110 + 0.01 * i, 110); path.lineTo(111 + 0.01 * i, 100); }
*** 103,143 **** 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.closePath(); final Path2D.Double path2 = new Path2D.Double(); ! path2.moveTo(0,0); ! path2.lineTo(width,height); ! path2.lineTo(10, 10); path2.closePath(); for (int i = 0; i < 1; i++) { final long start = System.nanoTime(); g2d.setColor(Color.BLUE); g2d.fill(path); ! g2d.fill(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"); System.out.println("Writing file: " ! + file.getAbsolutePath()); ImageIO.write(image, "PNG", file); } catch (IOException ex) { System.out.println("Writing file failure:"); ex.printStackTrace(); } } } finally { g2d.dispose(); } } } --- 120,441 ---- 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(); 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-fill.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, 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 >