< prev index next >

test/sun/java2d/marlin/CrashNaNTest.java

Print this page




   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 }


   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.BasicStroke;
  25 import java.awt.Color;
  26 import java.awt.Graphics2D;
  27 import java.awt.RenderingHints;
  28 import java.awt.Shape;
  29 import java.awt.Stroke;
  30 import java.awt.geom.Path2D;
  31 import java.awt.geom.PathIterator;
  32 import java.awt.image.BufferedImage;
  33 import java.awt.image.Raster;
  34 import java.io.File;
  35 import java.io.IOException;
  36 import static java.lang.Double.NEGATIVE_INFINITY;
  37 import static java.lang.Double.POSITIVE_INFINITY;
  38 import static java.lang.Double.NaN;
  39 import java.util.Arrays;
  40 import java.util.Locale;
  41 import java.util.logging.Handler;
  42 import java.util.logging.LogRecord;
  43 import java.util.logging.Logger;
  44 import javax.imageio.ImageIO;
  45 
  46 /**
  47  * @test
  48  * @bug 8149338 8144938
  49  * @summary Verifies that Marlin supports NaN coordinates (no JVM crash)
  50  * but also it skips properly point coordinates with NaN / Infinity values
  51  * @run main CrashNaNTest
  52  */
  53 public class CrashNaNTest {
  54 
  55     static final boolean SAVE_IMAGE = false;
  56 
  57     public static void main(String argv[]) {
  58         Locale.setDefault(Locale.US);
  59 
  60         // initialize j.u.l Looger:
  61         final Logger log = Logger.getLogger("sun.java2d.marlin");
  62         log.addHandler(new Handler() {
  63             @Override
  64             public void publish(LogRecord record) {
  65                 Throwable th = record.getThrown();
  66                 // detect any Throwable:
  67                 if (th != null) {
  68                     System.out.println("Test failed:\n" + record.getMessage());
  69                     th.printStackTrace(System.out);
  70 
  71                     throw new RuntimeException("Test failed: ", th);
  72                 }
  73             }
  74 
  75             @Override
  76             public void flush() {
  77             }
  78 
  79             @Override
  80             public void close() throws SecurityException {
  81             }
  82         });
  83 
  84         // enable Marlin logging & internal checks:
  85         System.setProperty("sun.java2d.renderer.log", "true");
  86         System.setProperty("sun.java2d.renderer.useLogger", "true");
  87         System.setProperty("sun.java2d.renderer.doChecks", "true");
  88 
  89         testFillDefaultAt();
  90         testDrawComplexAt();
  91 
  92         testPathClosed();
  93 
  94         testStrokedShapes();
  95     }
  96 
  97     private static void testFillDefaultAt() {
  98         final int width = 400;
  99         final int height = 400;
 100 
 101         final BufferedImage image = new BufferedImage(width, height,
 102                                             BufferedImage.TYPE_INT_ARGB);
 103 
 104         final Graphics2D g2d = (Graphics2D) image.getGraphics();
 105         try {
 106             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 107                                  RenderingHints.VALUE_ANTIALIAS_ON);
 108 
 109             g2d.setBackground(Color.WHITE);
 110             g2d.clearRect(0, 0, width, height);
 111 
 112             final Path2D.Double path = new Path2D.Double();
 113             path.moveTo(100, 100);

 114 
 115             for (int i = 0; i < 20000; i++) {
 116                 path.lineTo(110 + 0.01 * i, 110);
 117                 path.lineTo(111 + 0.01 * i, 100);
 118             }
 119 
 120             path.lineTo(NaN, 200);
 121             path.lineTo(200, 200);
 122             path.lineTo(200, NaN);
 123             path.lineTo(300, 300);
 124             path.lineTo(NaN, NaN);
 125             path.lineTo(100, 200);
 126             path.closePath();
 127 
 128             final Path2D.Double path2 = new Path2D.Double();
 129             path2.moveTo(0, 0);
 130             path2.lineTo(100, height);
 131             path2.lineTo(0, 200);
 132             path2.closePath();
 133 
 134             for (int i = 0; i < 1; i++) {
 135                 final long start = System.nanoTime();
 136                 g2d.setColor(Color.BLUE);
 137                 g2d.fill(path);
 138                 g2d.setColor(Color.GREEN);
 139                 g2d.fill(path2);
 140 
 141                 g2d.setColor(Color.BLACK);
 142                 g2d.draw(path);
 143                 g2d.draw(path2);
 144 
 145                 final long time = System.nanoTime() - start;
 146                 System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
 147             }
 148 
 149             if (SAVE_IMAGE) {
 150                 try {
 151                     final File file = new File("CrashNaNTest-fill.png");
 152                     System.out.println("Writing file: "
 153                                        + file.getAbsolutePath());
 154                     ImageIO.write(image, "PNG", file);
 155                 } catch (IOException ex) {
 156                     System.out.println("Writing file failure:");
 157                     ex.printStackTrace();
 158                 }
 159             }
 160 
 161             // Check image on few pixels:
 162             final Raster raster = image.getData();
 163 
 164             checkPixel(raster, 200, 195, Color.BLUE.getRGB());
 165             checkPixel(raster, 105, 195, Color.BLUE.getRGB());
 166             checkPixel(raster, 286, 290, Color.BLUE.getRGB());
 167 
 168             checkPixel(raster, 108, 105, Color.WHITE.getRGB());
 169             checkPixel(raster, 205, 200, Color.WHITE.getRGB());
 170 
 171             checkPixel(raster, 5, 200, Color.GREEN.getRGB());
 172 
 173         } finally {
 174             g2d.dispose();
 175         }
 176     }
 177 
 178     private static void testDrawComplexAt() {
 179         final int width = 400;
 180         final int height = 400;
 181 
 182         final BufferedImage image = new BufferedImage(width, height,
 183                                             BufferedImage.TYPE_INT_ARGB);
 184 
 185         final Graphics2D g2d = (Graphics2D) image.getGraphics();
 186         try {
 187             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 188                                  RenderingHints.VALUE_ANTIALIAS_ON);
 189             g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
 190                                  RenderingHints.VALUE_STROKE_PURE);
 191 
 192             g2d.setBackground(Color.WHITE);
 193             g2d.clearRect(0, 0, width, height);
 194 
 195             final Path2D.Double path = new Path2D.Double();
 196             path.moveTo(100, 100);
 197 
 198             for (int i = 0; i < 20000; i++) {
 199                 path.lineTo(110 + 0.01 * i, 110);
 200                 path.lineTo(111 + 0.01 * i, 100);
 201             }
 202 
 203             path.lineTo(NaN, 200);
 204             path.lineTo(200, 200);
 205             path.lineTo(200, NaN);
 206             path.lineTo(300, 300);
 207             path.lineTo(NaN, NaN);
 208             path.lineTo(100, 200);
 209             path.closePath();
 210 
 211             final Path2D.Double path2 = new Path2D.Double();
 212             path2.moveTo(0, 0);
 213             path2.lineTo(100, height);
 214             path2.lineTo(0, 200);
 215             path2.closePath();
 216 
 217             // Define an non-uniform transform:
 218             g2d.scale(0.5, 1.0);
 219             g2d.rotate(Math.PI / 31);
 220 
 221             for (int i = 0; i < 1; i++) {
 222                 final long start = System.nanoTime();
 223 
 224                 g2d.setColor(Color.BLACK);
 225                 g2d.draw(path);
 226                 g2d.draw(path2);
 227 
 228                 final long time = System.nanoTime() - start;
 229                 System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
 230             }
 231 
 232             if (SAVE_IMAGE) {
 233                 try {
 234                     final File file = new File("CrashNaNTest-draw.png");
 235                     System.out.println("Writing file: "
 236                                        + file.getAbsolutePath());
 237                     ImageIO.write(image, "PNG", file);
 238                 } catch (IOException ex) {
 239                     System.out.println("Writing file failure:");
 240                     ex.printStackTrace();
 241                 }
 242             }
 243 
 244             // Check image on few pixels:
 245             final Raster raster = image.getData();
 246 
 247             checkPixelNotWhite(raster, 40, 210);
 248             checkPixelNotWhite(raster, 44, 110);
 249             checkPixelNotWhite(raster, 60, 120);
 250             checkPixelNotWhite(raster, 89, 219);
 251             checkPixelNotWhite(raster, 28, 399);
 252             checkPixelNotWhite(raster, 134, 329);
 253 
 254         } finally {
 255             g2d.dispose();
 256         }
 257     }
 258     private static void testPathClosed() {
 259         final int width = 100;
 260         final int height = 100;
 261 
 262         final BufferedImage image = new BufferedImage(width, height,
 263                                             BufferedImage.TYPE_INT_ARGB);
 264 
 265         final Graphics2D g2d = (Graphics2D) image.getGraphics();
 266         try {
 267             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 268                                  RenderingHints.VALUE_ANTIALIAS_ON);
 269 
 270             g2d.setBackground(Color.WHITE);
 271             g2d.clearRect(0, 0, width, height);
 272 
 273             final Path2D.Double path = new Path2D.Double();
 274             path.moveTo(40, 40);
 275             path.lineTo(0,   0);
 276             path.lineTo(80, 0);
 277             path.closePath();
 278             path.lineTo(80, 80);
 279             path.lineTo(0, 80);
 280             path.closePath();
 281 
 282             for (int i = 0; i < 1; i++) {
 283                 final long start = System.nanoTime();
 284                 g2d.setColor(Color.BLUE);
 285                 g2d.fill(path);
 286 
 287                 g2d.setColor(Color.BLACK);
 288                 g2d.draw(path);
 289 
 290                 final long time = System.nanoTime() - start;
 291                 System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
 292             }
 293 
 294             if (SAVE_IMAGE) {
 295                 try {
 296                     final File file = new File("CrashNaNTest-path-closed.png");
 297                     System.out.println("Writing file: "
 298                                        + file.getAbsolutePath());
 299                     ImageIO.write(image, "PNG", file);
 300                 } catch (IOException ex) {
 301                     System.out.println("Writing file failure:");
 302                     ex.printStackTrace();
 303                 }
 304             }
 305 
 306             // Check image on few pixels:
 307             final Raster raster = image.getData();
 308 
 309             checkPixel(raster, 10, 05, Color.BLUE.getRGB());
 310             checkPixel(raster, 70, 05, Color.BLUE.getRGB());
 311             checkPixel(raster, 40, 35, Color.BLUE.getRGB());
 312 
 313             checkPixel(raster, 10, 75, Color.BLUE.getRGB());
 314             checkPixel(raster, 70, 75, Color.BLUE.getRGB());
 315             checkPixel(raster, 40, 45, Color.BLUE.getRGB());
 316 
 317         } finally {
 318             g2d.dispose();
 319         }
 320     }
 321 
 322     private static void testStrokedShapes() {
 323         final Stroke stroke = new BasicStroke();
 324 
 325         final Path2D.Double path = new Path2D.Double();
 326         Shape s;
 327 
 328         // Check filtering NaN values:
 329         path.reset();
 330         path.moveTo(100, NaN);
 331         path.lineTo(NaN, 100);
 332         path.lineTo(NaN, NaN);
 333 
 334         path.quadTo(NaN, 100, NaN, 100);
 335         path.quadTo(100, NaN, 100, NaN);
 336         path.quadTo(NaN, NaN, NaN, NaN);
 337 
 338         path.curveTo(NaN, 100, NaN, 100, NaN, 100);
 339         path.curveTo(100, NaN, 100, NaN, 100, NaN);
 340         path.curveTo(NaN, NaN, NaN, NaN, NaN, NaN);
 341         path.closePath();
 342 
 343         s = stroke.createStrokedShape(path);
 344         checkEmptyPath(s);
 345 
 346         // Check filtering +Infinity values:
 347         path.reset();
 348         path.moveTo(100, POSITIVE_INFINITY);
 349         path.lineTo(POSITIVE_INFINITY, 100);
 350         path.lineTo(POSITIVE_INFINITY, POSITIVE_INFINITY);
 351 
 352         path.quadTo(POSITIVE_INFINITY, 100,
 353                     POSITIVE_INFINITY, 100);
 354         path.quadTo(100, POSITIVE_INFINITY,
 355                     100, POSITIVE_INFINITY);
 356         path.quadTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
 357                     POSITIVE_INFINITY, POSITIVE_INFINITY);
 358 
 359         path.curveTo(POSITIVE_INFINITY, 100,
 360                      POSITIVE_INFINITY, 100,
 361                      POSITIVE_INFINITY, 100);
 362         path.curveTo(100, POSITIVE_INFINITY,
 363                      100, POSITIVE_INFINITY,
 364                      100, POSITIVE_INFINITY);
 365         path.curveTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
 366                      POSITIVE_INFINITY, POSITIVE_INFINITY,
 367                      POSITIVE_INFINITY, POSITIVE_INFINITY);
 368         path.closePath();
 369 
 370         s = stroke.createStrokedShape(path);
 371         checkEmptyPath(s);
 372 
 373         // Check filtering -Infinity values:
 374         path.reset();
 375         path.moveTo(100, NEGATIVE_INFINITY);
 376         path.lineTo(NEGATIVE_INFINITY, 100);
 377         path.lineTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY);
 378 
 379         path.quadTo(NEGATIVE_INFINITY, 100,
 380                     NEGATIVE_INFINITY, 100);
 381         path.quadTo(100, NEGATIVE_INFINITY,
 382                     100, NEGATIVE_INFINITY);
 383         path.quadTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
 384                     NEGATIVE_INFINITY, NEGATIVE_INFINITY);
 385 
 386         path.curveTo(NEGATIVE_INFINITY, 100,
 387                      NEGATIVE_INFINITY, 100,
 388                      NEGATIVE_INFINITY, 100);
 389         path.curveTo(100, NEGATIVE_INFINITY,
 390                      100, NEGATIVE_INFINITY,
 391                      100, NEGATIVE_INFINITY);
 392         path.curveTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
 393                      NEGATIVE_INFINITY, NEGATIVE_INFINITY,
 394                      NEGATIVE_INFINITY, NEGATIVE_INFINITY);
 395         path.closePath();
 396 
 397         s = stroke.createStrokedShape(path);
 398         checkEmptyPath(s);
 399     }
 400 
 401     private static void checkEmptyPath(final Shape s) {
 402         final float[] coords = new float[6];
 403         final PathIterator it = s.getPathIterator(null);
 404 
 405         int n = 0;
 406         for (; !it.isDone(); it.next()) {
 407             int type = it.currentSegment(coords);
 408             System.out.println("unexpected segment type= " + type
 409                  + " with coords: " + Arrays.toString(coords));
 410             n++;
 411         }
 412         if (n != 0) {
 413             System.out.println("path elements = " + n);
 414             throw new IllegalStateException("Not empty path: "
 415                           + n + " path elements !");
 416         }
 417     }
 418 
 419     private static void checkPixel(final Raster raster,
 420                                    final int x, final int y,
 421                                    final int expected) {
 422 
 423         final int[] rgb = (int[]) raster.getDataElements(x, y, null);
 424 
 425         if (rgb[0] != expected) {
 426             throw new IllegalStateException("bad pixel at (" + x + ", " + y
 427                           + ") = " + rgb[0] + " expected: " + expected);
 428         }
 429     }
 430 
 431     private static void checkPixelNotWhite(final Raster raster,
 432                                            final int x, final int y) {
 433 
 434         final int[] rgb = (int[]) raster.getDataElements(x, y, null);
 435 
 436         if (rgb[0] == Color.WHITE.getRGB()) {
 437             throw new IllegalStateException("bad pixel at (" + x + ", " + y
 438                           + ") is white (empty)");
 439         }
 440     }
 441 }
< prev index next >