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 import java.awt.Color; 24 import java.awt.Font; 25 import java.awt.Graphics2D; 26 import java.awt.RenderingHints; 27 import java.awt.image.BufferedImage; 28 import java.io.IOException; 29 30 /** 31 * @test 32 * @bug 8015070 33 * @summary Tests for artifacts around the edges of anti-aliased text. 34 */ 35 public class AADrawStringArtifact { 36 /* Image dimensions */ 37 static final int TEST_IMAGE_WIDTH = 200; 38 static final int TEST_IMAGE_HEIGHT = 100; 39 40 public AADrawStringArtifact() throws IOException { 41 /* Create a Graphics2D object from a BufferedImage */ 42 BufferedImage testImg = new BufferedImage(TEST_IMAGE_WIDTH, 43 TEST_IMAGE_HEIGHT, 44 BufferedImage.TYPE_INT_ARGB); 45 Graphics2D graphics = (Graphics2D) testImg.getGraphics(); 46 47 /* Fill the image with translucent color */ 48 graphics.setColor(new Color(127, 127, 127, 127)); 49 graphics.fillRect(0, 0, TEST_IMAGE_WIDTH, TEST_IMAGE_HEIGHT); 50 51 /* Drawstring with Antialiasing hint */ 52 graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 53 RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 54 Font font = new Font("Verdana" , Font.PLAIN, 60); 55 graphics.setFont(font); 56 graphics.setColor(new Color(255, 0, 0)); 57 graphics.drawString("Save", 30, 65); 58 graphics.dispose(); 59 60 /* Check for artifacts */ 61 checkArtifacts(testImg); 62 } 63 64 void checkArtifacts(BufferedImage testImage) throws IOException { 65 int componentMask = 0xff; 66 int colorThreshold = 200; 67 int rowIndex = 0; 68 int colIndex = 0; 69 70 /* Loop through every pixel to check for possible artifact */ 71 for (rowIndex = 0; rowIndex < testImage.getHeight(); rowIndex++) { 72 for (colIndex = 0; colIndex < testImage.getWidth(); colIndex++) { 73 /* 74 * API: getRGB(x,y) returns color in INT_ARGB color space. 75 * Extract individual color components with a simple mask. 76 */ 77 int colorValue = testImage.getRGB(colIndex, rowIndex); 78 int colorComponent1 = colorValue & componentMask; 79 int colorComponent2 = (colorValue>>8) & componentMask; 80 int colorComponent3 = (colorValue>>16) & componentMask; 81 82 /* 83 * Artifacts are predominantly a subjective decision based on 84 * the quality of the rendered image content. However, in the 85 * current use-case, the artifacts around the edges of the anti 86 * aliased text appear like spots of white pixels without any 87 * relation to the color of foreground text or the background 88 * translucent shape. 89 * 90 * To identify the artifact pixels, each color component from 91 * the testImage is compared with a constant threshold. The 92 * component threshold has been set based on observation from 93 * different experiments on mulitple Java versions. 94 */ 95 if (colorComponent1 >= colorThreshold 96 && colorComponent2 >= colorThreshold 97 && colorComponent3 >= colorThreshold) { 98 /* Artifact has been noticed. Report error. */ 99 throw new RuntimeException("Test Failed."); 100 } 101 } 102 } 103 } 104 105 public static void main(String[] args) throws IOException { 106 /* Mere instantiating this object will suffice for automated test */ 107 AADrawStringArtifact artifactTest = new AADrawStringArtifact(); 108 } 109 }