1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.awt.Color;
  25 import java.awt.Graphics2D;
  26 import java.awt.RenderingHints;
  27 import java.awt.geom.Path2D;
  28 import java.awt.image.BufferedImage;
  29 import java.io.File;
  30 import java.io.IOException;
  31 import static java.lang.Double.NaN;
  32 import java.util.Locale;
  33 import java.util.logging.Handler;
  34 import java.util.logging.LogRecord;
  35 import java.util.logging.Logger;
  36 import javax.imageio.ImageIO;
  37 
  38 /**
  39  * @test
  40  * @bug 8149338
  41  * @summary Verifies that Marlin supports NaN coordinates and no JVM crash happens !
  42  * @run main CrashNaNTest
  43  */
  44 public class CrashNaNTest {
  45 
  46     static final boolean SAVE_IMAGE = false;
  47 
  48     public static void main(String argv[]) {
  49         Locale.setDefault(Locale.US);
  50 
  51         // initialize j.u.l Looger:
  52         final Logger log = Logger.getLogger("sun.java2d.marlin");
  53         log.addHandler(new Handler() {
  54             @Override
  55             public void publish(LogRecord record) {
  56                 Throwable th = record.getThrown();
  57                 // detect any Throwable:
  58                 if (th != null) {
  59                     System.out.println("Test failed:\n" + record.getMessage());
  60                     th.printStackTrace(System.out);
  61 
  62                     throw new RuntimeException("Test failed: ", th);
  63                 }
  64             }
  65 
  66             @Override
  67             public void flush() {
  68             }
  69 
  70             @Override
  71             public void close() throws SecurityException {
  72             }
  73         });
  74 
  75         // enable Marlin logging & internal checks:
  76         System.setProperty("sun.java2d.renderer.log", "true");
  77         System.setProperty("sun.java2d.renderer.useLogger", "true");
  78         System.setProperty("sun.java2d.renderer.doChecks", "true");
  79 
  80         final int width = 400;
  81         final int height = 400;
  82 
  83         final BufferedImage image = new BufferedImage(width, height,
  84                 BufferedImage.TYPE_INT_ARGB);
  85 
  86         final Graphics2D g2d = (Graphics2D) image.getGraphics();
  87         try {
  88             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  89                     RenderingHints.VALUE_ANTIALIAS_ON);
  90 
  91             g2d.setBackground(Color.WHITE);
  92             g2d.clearRect(0, 0, width, height);
  93 
  94             final Path2D.Double path = new Path2D.Double();
  95             path.moveTo(30, 30);
  96             path.lineTo(100, 100);
  97 
  98             for (int i = 0; i < 20000; i++) {
  99                 path.lineTo(110 + 0.01 * i, 110);
 100                 path.lineTo(111 + 0.01 * i, 100);
 101             }
 102 
 103             path.lineTo(NaN, 200);
 104             path.lineTo(200, 200);
 105             path.lineTo(200, NaN);
 106             path.lineTo(300, 300);
 107             path.lineTo(NaN, NaN);
 108             path.lineTo(100, 100);
 109             path.closePath();
 110 
 111             final Path2D.Double path2 = new Path2D.Double();
 112             path2.moveTo(0,0);
 113             path2.lineTo(width,height);
 114             path2.lineTo(10, 10);
 115             path2.closePath();
 116 
 117             for (int i = 0; i < 1; i++) {
 118                 final long start = System.nanoTime();
 119                 g2d.setColor(Color.BLUE);
 120                 g2d.fill(path);
 121 
 122                 g2d.fill(path2);
 123 
 124                 final long time = System.nanoTime() - start;
 125                 System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
 126             }
 127 
 128             if (SAVE_IMAGE) {
 129                 try {
 130                     final File file = new File("CrashNaNTest.png");
 131                     System.out.println("Writing file: "
 132                             + file.getAbsolutePath());
 133                     ImageIO.write(image, "PNG", file);
 134                 } catch (IOException ex) {
 135                     System.out.println("Writing file failure:");
 136                     ex.printStackTrace();
 137                 }
 138             }
 139         } finally {
 140             g2d.dispose();
 141         }
 142     }
 143 }