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