Path: blob/master/test/jdk/sun/java2d/marlin/TextClipErrorTest.java
41149 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.awt.BasicStroke;24import java.awt.Color;25import java.awt.Font;26import java.awt.Graphics2D;27import java.awt.RenderingHints;28import java.awt.Shape;29import java.awt.font.FontRenderContext;30import java.awt.font.GlyphVector;31import java.awt.geom.AffineTransform;32import java.awt.geom.Line2D;33import java.awt.geom.Path2D;34import java.awt.geom.PathIterator;35import static java.awt.geom.PathIterator.SEG_CLOSE;36import static java.awt.geom.PathIterator.SEG_CUBICTO;37import static java.awt.geom.PathIterator.SEG_LINETO;38import static java.awt.geom.PathIterator.SEG_MOVETO;39import static java.awt.geom.PathIterator.SEG_QUADTO;40import java.awt.image.BufferedImage;41import java.io.File;42import java.io.IOException;43import java.util.ArrayList;44import java.util.Arrays;45import java.util.Locale;46import java.util.logging.Handler;47import java.util.logging.LogRecord;48import java.util.logging.Logger;49import javax.imageio.ImageIO;5051/**52* @test53* @bug 814471854* @summary Check the Stroker.drawBezApproxForArc() bug (stoke with round55* joins): if cosext2 > 0.5, it generates curves with NaN coordinates56* @run main TextClipErrorTest57*/58public class TextClipErrorTest {5960static final boolean SAVE_IMAGE = false;61static final boolean SERIALIZE = false;6263public static void main(String[] args) {64Locale.setDefault(Locale.US);6566// initialize j.u.l Looger:67final Logger log = Logger.getLogger("sun.java2d.marlin");68log.addHandler(new Handler() {69@Override70public void publish(LogRecord record) {71Throwable th = record.getThrown();72// detect any Throwable:73if (th != null) {74System.out.println("Test failed:\n" + record.getMessage());75th.printStackTrace(System.out);7677throw new RuntimeException("Test failed: ", th);78}79}8081@Override82public void flush() {83}8485@Override86public void close() throws SecurityException {87}88});8990log.info("TextClipErrorTest: start");9192// enable Marlin logging & internal checks:93System.setProperty("sun.java2d.renderer.log", "true");94System.setProperty("sun.java2d.renderer.useLogger", "true");95System.setProperty("sun.java2d.renderer.doChecks", "true");9697BufferedImage image = new BufferedImage(256, 256,98BufferedImage.TYPE_INT_ARGB);99100Graphics2D g2d = image.createGraphics();101g2d.setColor(Color.red);102try {103g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,104RenderingHints.VALUE_ANTIALIAS_ON);105106Font font = g2d.getFont();107FontRenderContext frc = new FontRenderContext(108new AffineTransform(), true, true);109110g2d.setStroke(new BasicStroke(4.0f,111BasicStroke.CAP_ROUND,112BasicStroke.JOIN_ROUND));113114final Shape badShape;115if (SERIALIZE) {116final GlyphVector gv1 = font.createGlyphVector(frc, "\u00d6");117final Shape textShape = gv1.getOutline();118119final AffineTransform at1 = AffineTransform.getTranslateInstance(120-2091202.554154681, 5548.601436981691);121badShape = at1.createTransformedShape(textShape);122serializeShape(badShape);123} else {124badShape = deserializeShape();125}126127g2d.draw(badShape);128129// Draw anything within bounds and it fails:130g2d.draw(new Line2D.Double(10, 20, 30, 40));131132if (SAVE_IMAGE) {133final File file = new File("TextClipErrorTest.png");134System.out.println("Writing file: " + file.getAbsolutePath());135ImageIO.write(image, "PNG", file);136}137} catch (IOException ex) {138ex.printStackTrace();139} finally {140g2d.dispose();141log.info("TextClipErrorTest: end");142}143}144145private static void serializeShape(Shape shape) {146final double[] coords = new double[6];147148final int len = 32;149final ArrayList<Integer> typeList = new ArrayList<Integer>(len);150final ArrayList<double[]> coordsList = new ArrayList<double[]>(len);151152for (PathIterator pi = shape.getPathIterator(null);153!pi.isDone(); pi.next())154{155switch (pi.currentSegment(coords)) {156case SEG_MOVETO:157typeList.add(SEG_MOVETO);158coordsList.add(Arrays.copyOf(coords, 2));159break;160case SEG_LINETO:161typeList.add(SEG_LINETO);162coordsList.add(Arrays.copyOf(coords, 2));163break;164case SEG_QUADTO:165typeList.add(SEG_QUADTO);166coordsList.add(Arrays.copyOf(coords, 4));167break;168case SEG_CUBICTO:169typeList.add(SEG_CUBICTO);170coordsList.add(Arrays.copyOf(coords, 6));171break;172case SEG_CLOSE:173typeList.add(SEG_CLOSE);174coordsList.add(null);175break;176default:177}178}179180final StringBuilder sb = new StringBuilder(1024);181// types:182sb.append("private static final int[] SHAPE_TYPES = new int[]{\n");183for (Integer i : typeList) {184sb.append(i).append(",\n");185}186sb.append("};\n");187188// coords:189sb.append("private static final double[][] SHAPE_COORDS = new double[][]{\n");190for (double[] c : coordsList) {191if (c == null) {192sb.append("null,\n");193} else {194sb.append("new double[]{");195for (int i = 0; i < c.length; i++) {196sb.append(c[i]).append(",");197}198sb.append("},\n");199}200}201sb.append("};\n");202203System.out.println("Shape size: " + typeList.size());204System.out.println("Serialized shape:\n" + sb.toString());205}206207private static Shape deserializeShape() {208final Path2D.Double path = new Path2D.Double();209210for (int i = 0; i < SHAPE_TYPES.length; i++) {211double[] coords = SHAPE_COORDS[i];212213switch (SHAPE_TYPES[i]) {214case SEG_MOVETO:215path.moveTo(coords[0], coords[1]);216break;217case SEG_LINETO:218path.lineTo(coords[0], coords[1]);219break;220case SEG_QUADTO:221path.quadTo(coords[0], coords[1],222coords[2], coords[3]);223break;224case SEG_CUBICTO:225path.curveTo(coords[0], coords[1],226coords[2], coords[3],227coords[4], coords[5]);228break;229case SEG_CLOSE:230path.closePath();231break;232default:233}234}235236return path;237}238239// generated code:240private static final int[] SHAPE_TYPES = new int[]{2410,2422,2432,2442,2452,2462,2472,2482,2492,2504,2510,2522,2532,2542,2552,2562,2572,2582,2592,2604,2610,2621,2631,2641,2651,2664,2670,2681,2691,2701,2711,2724,273};274275private static final double[][] SHAPE_COORDS = new double[][]{276new double[]{-2091197.819779681, 5540.648311981691,},277new double[]{-2091199.116654681, 5540.648311981691, -2091199.874467181, 5541.609249481691,},278new double[]{-2091200.632279681, 5542.570186981691, -2091200.632279681, 5544.242061981691,},279new double[]{-2091200.632279681, 5545.882686981691, -2091199.874467181, 5546.843624481691,},280new double[]{-2091199.116654681, 5547.804561981691, -2091197.819779681, 5547.804561981691,},281new double[]{-2091196.538529681, 5547.804561981691, -2091195.780717181, 5546.843624481691,},282new double[]{-2091195.022904681, 5545.882686981691, -2091195.022904681, 5544.242061981691,},283new double[]{-2091195.022904681, 5542.570186981691, -2091195.780717181, 5541.609249481691,},284new double[]{-2091196.538529681, 5540.648311981691, -2091197.819779681, 5540.648311981691,},285null,286new double[]{-2091197.819779681, 5539.695186981691,},287new double[]{-2091195.991654681, 5539.695186981691, -2091194.890092181, 5540.929561981691,},288new double[]{-2091193.788529681, 5542.163936981691, -2091193.788529681, 5544.242061981691,},289new double[]{-2091193.788529681, 5546.304561981691, -2091194.890092181, 5547.538936981691,},290new double[]{-2091195.991654681, 5548.773311981691, -2091197.819779681, 5548.773311981691,},291new double[]{-2091199.663529681, 5548.773311981691, -2091200.772904681, 5547.538936981691,},292new double[]{-2091201.882279681, 5546.304561981691, -2091201.882279681, 5544.242061981691,},293new double[]{-2091201.882279681, 5542.163936981691, -2091200.772904681, 5540.929561981691,},294new double[]{-2091199.663529681, 5539.695186981691, -2091197.819779681, 5539.695186981691,},295null,296new double[]{-2091197.210404681, 5537.835811981691,},297new double[]{-2091196.022904681, 5537.835811981691,},298new double[]{-2091196.022904681, 5539.023311981691,},299new double[]{-2091197.210404681, 5539.023311981691,},300new double[]{-2091197.210404681, 5537.835811981691,},301null,302new double[]{-2091199.632279681, 5537.835811981691,},303new double[]{-2091198.444779681, 5537.835811981691,},304new double[]{-2091198.444779681, 5539.023311981691,},305new double[]{-2091199.632279681, 5539.023311981691,},306new double[]{-2091199.632279681, 5537.835811981691,},307null,308};309310}311312313