1 /* 2 * Copyright (c) 2007, 2013, 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 /* 25 * @test 26 * @bug 6689025 8023483 27 * @summary Tests that transformed Paints are rendered correctly 28 * @author Dmitri.Trembovetski@sun.com: area=Graphics 29 * @run main/othervm TransformedPaintTest 30 * @run main/othervm -Dsun.java2d.opengl=True TransformedPaintTest 31 */ 32 33 import java.awt.Color; 34 import java.awt.Dimension; 35 import java.awt.EventQueue; 36 import java.awt.GradientPaint; 37 import java.awt.Graphics; 38 import java.awt.Graphics2D; 39 import java.awt.GraphicsConfiguration; 40 import java.awt.GraphicsEnvironment; 41 import java.awt.LinearGradientPaint; 42 import java.awt.MultipleGradientPaint.CycleMethod; 43 import java.awt.Paint; 44 import java.awt.RadialGradientPaint; 45 import java.awt.TexturePaint; 46 import java.awt.geom.Rectangle2D; 47 import java.awt.image.BufferedImage; 48 import java.awt.image.VolatileImage; 49 import java.io.File; 50 import java.io.IOException; 51 import java.lang.reflect.InvocationTargetException; 52 import javax.imageio.ImageIO; 53 import javax.swing.JFrame; 54 import javax.swing.JPanel; 55 56 public class TransformedPaintTest { 57 58 private static enum PaintType { 59 COLOR, 60 GRADIENT, 61 LINEAR_GRADIENT, 62 RADIAL_GRADIENT, 63 TEXTURE 64 }; 65 66 private static final int CELL_SIZE = 100; 67 private static final int R_WIDTH = 3 * CELL_SIZE; 68 private static final int R_HEIGHT = PaintType.values().length * CELL_SIZE; 69 70 private Paint createPaint(PaintType type, int startx, int starty, 71 int w, int h) 72 { 73 // make sure that the blue color doesn't show up when filling a 74 // w by h rect 75 w++; h++; 76 77 int endx = startx + w; 78 int endy = starty + h; 79 Rectangle2D.Float r = new Rectangle2D.Float(startx, starty, w, h); 80 switch (type) { 81 case COLOR: return Color.red; 82 case GRADIENT: return 83 new GradientPaint(startx, starty, Color.red, 84 endx, endy, Color.green); 85 case LINEAR_GRADIENT: return 86 new LinearGradientPaint(startx, starty, endx, endy, 87 new float[] { 0.0f, 0.999f, 1.0f }, 88 new Color[] { Color.red, Color.green, Color.blue }); 89 case RADIAL_GRADIENT: return 90 new RadialGradientPaint(startx, starty, 91 (float)Math.sqrt(w * w + h * h), 92 new float[] { 0.0f, 0.999f, 1.0f }, 93 new Color[] { Color.red, Color.green, Color.blue }, 94 CycleMethod.NO_CYCLE); 95 case TEXTURE: { 96 BufferedImage bi = 97 new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 98 Graphics2D g = (Graphics2D) bi.getGraphics(); 99 g.setPaint(createPaint(PaintType.LINEAR_GRADIENT, 0, 0, w, h)); 100 g.fillRect(0, 0, w, h); 101 return new TexturePaint(bi, r); 102 } 103 } 104 return Color.green; 105 } 106 107 private void renderLine(PaintType type, Graphics2D g, 108 int startx, int starty, int w, int h) 109 { 110 Paint p = createPaint(type, startx, starty, w, h); 111 g.setPaint(p); 112 113 // first, no transform 114 g.fillRect(startx, starty, w, h); 115 116 // translation only 117 g.translate(w, 0); 118 g.fillRect(startx, starty, w, h); 119 g.translate(-w, 0); 120 121 // complex transform 122 g.translate(startx + w*2, starty); 123 g.rotate(Math.toRadians(90), w/2, h/2); 124 g.translate(-startx, -starty); 125 g.fillRect(startx, starty, w, h); 126 } 127 128 private void render(Graphics2D g, int w, int h) { 129 int paintTypes = PaintType.values().length; 130 int ystep = h / paintTypes; 131 int y = 0; 132 133 for (PaintType type : PaintType.values()) { 134 renderLine(type, (Graphics2D)g.create(), 135 0, y, h / paintTypes, h / paintTypes); 136 y += ystep; 137 } 138 } 139 140 private void checkBI(BufferedImage bi) { 141 for (int y = 0; y < bi.getHeight(); y++) { 142 for (int x = 0; x < bi.getWidth(); x++) { 143 if (bi.getRGB(x, y) == Color.blue.getRGB()) { 144 try { 145 String fileName = "TransformedPaintTest_res.png"; 146 ImageIO.write(bi, "png", new File(fileName)); 147 System.err.println("Dumped image to: " + fileName); 148 } catch (IOException ex) {} 149 throw new RuntimeException("Test failed, blue color found"); 150 } 151 } 152 } 153 } 154 155 private void runTest() { 156 GraphicsConfiguration gc = GraphicsEnvironment. 157 getLocalGraphicsEnvironment().getDefaultScreenDevice(). 158 getDefaultConfiguration(); 159 160 if (gc.getColorModel().getPixelSize() < 16) { 161 System.out.println("8-bit desktop depth found, test passed"); 162 return; 163 } 164 165 VolatileImage vi = gc.createCompatibleVolatileImage(R_WIDTH, R_HEIGHT); 166 BufferedImage bi = null; 167 do { 168 vi.validate(gc); 169 Graphics2D g = vi.createGraphics(); 170 render(g, vi.getWidth(), vi.getHeight()); 171 bi = vi.getSnapshot(); 172 } while (vi.contentsLost()); 173 174 checkBI(bi); 175 System.out.println("Test PASSED."); 176 } 177 178 private static void showFrame(final TransformedPaintTest t) { 179 JFrame f = new JFrame("TransformedPaintTest"); 180 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 181 final BufferedImage bi = 182 new BufferedImage(R_WIDTH, R_HEIGHT, BufferedImage.TYPE_INT_RGB); 183 JPanel p = new JPanel() { 184 @Override 185 protected void paintComponent(Graphics g) { 186 super.paintComponent(g); 187 Graphics2D g2d = (Graphics2D) g; 188 t.render(g2d, R_WIDTH, R_HEIGHT); 189 t.render(bi.createGraphics(), R_WIDTH, R_HEIGHT); 190 g2d.drawImage(bi, R_WIDTH + 5, 0, null); 191 192 g.setColor(Color.black); 193 g.drawString("Rendered to Back Buffer", 10, 20); 194 g.drawString("Rendered to BufferedImage", R_WIDTH + 15, 20); 195 } 196 }; 197 p.setPreferredSize(new Dimension(2 * R_WIDTH + 5, R_HEIGHT)); 198 f.add(p); 199 f.pack(); 200 f.setVisible(true); 201 } 202 203 public static void main(String[] args) throws 204 InterruptedException, InvocationTargetException 205 { 206 boolean show = (args.length > 0 && "-show".equals(args[0])); 207 208 final TransformedPaintTest t = new TransformedPaintTest(); 209 if (show) { 210 EventQueue.invokeAndWait(new Runnable() { 211 public void run() { 212 showFrame(t); 213 } 214 }); 215 } else { 216 t.runTest(); 217 } 218 } 219 }