1 /* 2 * Copyright (c) 2014, 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.Font; 26 import java.awt.Graphics2D; 27 import java.awt.RenderingHints; 28 import java.awt.geom.AffineTransform; 29 import java.awt.image.BufferedImage; 30 import java.io.File; 31 import java.io.IOException; 32 33 import javax.imageio.ImageIO; 34 35 import static java.awt.image.BufferedImage.TYPE_INT_RGB; 36 import static java.lang.Math.toRadians; 37 38 /** 39 * @test 40 * @bug 8065373 41 * @summary Verifies that we get correct direction, when draw rotated string. 42 * @author Sergey Bylokhov 43 * @run main DrawRotatedStringUsingRotatedFont 44 */ 45 public final class DrawRotatedStringUsingRotatedFont { 46 47 private static final int SIZE = 500; 48 private static final String STR = "MMMMMMMMMMMMMMMM"; 49 50 private static AffineTransform[] txs = { 51 AffineTransform.getRotateInstance(toRadians(00)), 52 AffineTransform.getRotateInstance(toRadians(45)), 53 AffineTransform.getRotateInstance(toRadians(-45)), 54 AffineTransform.getRotateInstance(toRadians(90)), 55 AffineTransform.getRotateInstance(toRadians(-90)), 56 AffineTransform.getRotateInstance(toRadians(135)), 57 AffineTransform.getRotateInstance(toRadians(-135)), 58 AffineTransform.getRotateInstance(toRadians(180)), 59 AffineTransform.getRotateInstance(toRadians(-180)), 60 AffineTransform.getRotateInstance(toRadians(225)), 61 AffineTransform.getRotateInstance(toRadians(-225)), 62 AffineTransform.getRotateInstance(toRadians(270)), 63 AffineTransform.getRotateInstance(toRadians(-270)), 64 AffineTransform.getRotateInstance(toRadians(315)), 65 AffineTransform.getRotateInstance(toRadians(-315)), 66 AffineTransform.getRotateInstance(toRadians(360)), 67 AffineTransform.getRotateInstance(toRadians(-360)) 68 }; 69 main(final String[] args)70 public static void main(final String[] args) throws IOException { 71 for (final AffineTransform tx2 : txs) { 72 for (final AffineTransform tx1 : txs) { 73 for (final boolean aa : new boolean[]{true, false}) { 74 final BufferedImage bi1 = createImage(aa, tx1, tx2); 75 final BufferedImage bi2 = createImage(aa, tx2, tx1); 76 compareImage(bi1, bi2); 77 fillTextArea(bi1, tx1, tx2); 78 fillTextArea(bi2, tx2, tx1); 79 checkColors(bi1, bi2); 80 } 81 } 82 } 83 System.out.println("Passed"); 84 } 85 86 /** 87 * Compares two images. 88 */ compareImage(final BufferedImage bi1, final BufferedImage bi2)89 private static void compareImage(final BufferedImage bi1, 90 final BufferedImage bi2) 91 throws IOException { 92 for (int i = 0; i < SIZE; ++i) { 93 for (int j = 0; j < SIZE; ++j) { 94 if (bi1.getRGB(i, j) != bi2.getRGB(i, j)) { 95 ImageIO.write(bi1, "png", new File("image1.png")); 96 ImageIO.write(bi2, "png", new File("image2.png")); 97 throw new RuntimeException("Failed: wrong text location"); 98 } 99 } 100 } 101 } 102 103 /** 104 * Checks an image color. RED and GREEN are allowed only. 105 */ checkColors(final BufferedImage bi1, final BufferedImage bi2)106 private static void checkColors(final BufferedImage bi1, 107 final BufferedImage bi2) 108 throws IOException { 109 for (int i = 0; i < SIZE; ++i) { 110 for (int j = 0; j < SIZE; ++j) { 111 final int rgb1 = bi1.getRGB(i, j); 112 final int rgb2 = bi2.getRGB(i, j); 113 if (rgb1 != rgb2 || rgb1 != 0xFFFF0000 && rgb1 != 0xFF00FF00) { 114 ImageIO.write(bi1, "png", new File("image1.png")); 115 ImageIO.write(bi2, "png", new File("image2.png")); 116 throw new RuntimeException("Failed: wrong text location"); 117 } 118 } 119 } 120 } 121 122 /** 123 * Creates an BufferedImage and draws a text, using two transformations, 124 * one for graphics and one for font. 125 */ createImage(final boolean aa, final AffineTransform gtx, final AffineTransform ftx)126 private static BufferedImage createImage(final boolean aa, 127 final AffineTransform gtx, 128 final AffineTransform ftx) { 129 final BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB); 130 final Graphics2D bg = bi.createGraphics(); 131 bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 132 aa ? RenderingHints.VALUE_ANTIALIAS_ON 133 : RenderingHints.VALUE_ANTIALIAS_OFF); 134 bg.setColor(Color.RED); 135 bg.fillRect(0, 0, SIZE, SIZE); 136 bg.translate(100, 100); 137 bg.transform(gtx); 138 bg.setColor(Color.BLACK); 139 bg.setFont(bg.getFont().deriveFont(20.0f).deriveFont(ftx)); 140 bg.drawString(STR, 0, 0); 141 bg.dispose(); 142 return bi; 143 } 144 145 /** 146 * Fills the area of text using green solid color. 147 */ fillTextArea(final BufferedImage bi, final AffineTransform tx1, final AffineTransform tx2)148 private static void fillTextArea(final BufferedImage bi, 149 final AffineTransform tx1, 150 final AffineTransform tx2) { 151 final Graphics2D bg = bi.createGraphics(); 152 bg.translate(100, 100); 153 bg.transform(tx1); 154 bg.transform(tx2); 155 bg.setColor(Color.GREEN); 156 final Font font = bg.getFont().deriveFont(20.0f); 157 bg.setFont(font); 158 bg.fill(font.getStringBounds(STR, bg.getFontRenderContext())); 159 bg.dispose(); 160 } 161 } 162 163