1 /* 2 * Copyright (c) 2005, 2010, 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 6244574 27 @bug 6258142 28 @bug 6395165 29 @bug 6588884 30 @summary Tests that source is clipped correctly when blitting 31 different types of images to the screen 32 @author Dmitri.Trembovetski: area=Graphics2D 33 @run main SourceClippingBlitTest 34 */ 35 36 import java.awt.AWTException; 37 import java.awt.Canvas; 38 import java.awt.Color; 39 import java.awt.Dimension; 40 import java.awt.Frame; 41 import java.awt.Graphics; 42 import java.awt.GraphicsConfiguration; 43 import java.awt.Image; 44 import java.awt.Point; 45 import java.awt.Rectangle; 46 import java.awt.Robot; 47 import java.awt.Toolkit; 48 import java.awt.Transparency; 49 import java.awt.event.ComponentAdapter; 50 import java.awt.event.ComponentEvent; 51 import java.awt.event.WindowAdapter; 52 import java.awt.event.WindowEvent; 53 import java.awt.image.BufferedImage; 54 import java.awt.image.VolatileImage; 55 56 public class SourceClippingBlitTest extends Canvas { 57 static final int TESTW = 300; 58 static final int TESTH = 300; 59 static final int IMAGEW = 50; 60 static final int IMAGEH = 50; 61 62 static final Rectangle IMAGE_BOUNDS = new Rectangle(0, 0, IMAGEW, IMAGEH); 63 static Robot robot; 64 static private boolean showErrors; 65 66 private static final Object lock = new Object(); 67 private static volatile boolean done = false; 68 69 BufferedImage grabbedBI; 70 71 public static void main(String[] args) { 72 // allow user to override the properties if needed 73 if (System.getProperty("sun.java2d.pmoffscreen") == null) { 74 System.setProperty("sun.java2d.pmoffscreen", "true"); 75 } 76 77 if (args.length > 0 && args[0].equals("-showerrors")) { 78 showErrors = true; 79 } 80 81 try { 82 robot = new Robot(); 83 } catch (AWTException e) { 84 throw new RuntimeException(e); 85 } 86 87 Frame f = new Frame(SourceClippingBlitTest.class.getName()); 88 final SourceClippingBlitTest test = new SourceClippingBlitTest(); 89 f.add(test); 90 f.addWindowListener(new WindowAdapter() { 91 public void windowActivated(WindowEvent e) { 92 if (!done) { 93 test.runTests(); 94 } 95 } 96 97 }); 98 f.pack(); 99 f.setLocation(100, 100); 100 f.setVisible(true); 101 synchronized (lock) { 102 while (!done) { 103 try { 104 lock.wait(); 105 } catch (InterruptedException ex) { 106 ex.printStackTrace(); 107 } 108 } 109 } 110 if (!showErrors) { 111 f.dispose(); 112 } 113 } 114 115 public Dimension getPreferredSize() { 116 return new Dimension(TESTW, TESTH); 117 } 118 119 public void paint(Graphics g) { 120 if (showErrors && done && grabbedBI != null) { 121 g.drawImage(grabbedBI, 0, 0, null); 122 } 123 } 124 125 public void runTests() { 126 GraphicsConfiguration gc = getGraphicsConfiguration(); 127 for (Image srcIm : 128 new Image[] { 129 getBufferedImage(gc, IMAGEW, IMAGEH, 130 BufferedImage.TYPE_INT_RGB, true), 131 getBufferedImage(gc, IMAGEW, IMAGEH, 132 BufferedImage.TYPE_INT_RGB, false), 133 // commented out due to 6593406 134 // getBMImage(gc, IMAGEW, IMAGEH), 135 // getBufferedImage(gc, IMAGEW, IMAGEH, 136 // BufferedImage.TYPE_INT_ARGB, true), 137 // getBufferedImage(gc, IMAGEW, IMAGEH, 138 // BufferedImage.TYPE_INT_ARGB, false), 139 getVImage(gc, IMAGEW, IMAGEH), 140 }) 141 { 142 System.out.println("Testing source: " + srcIm); 143 // wiggle the source and dest rectangles 144 try { 145 for (int locationVar = -10; locationVar < 20; locationVar += 10) 146 { 147 for (int sizeVar = -10; sizeVar < 20; sizeVar += 10) { 148 Rectangle srcRect = (Rectangle)IMAGE_BOUNDS.clone(); 149 srcRect.translate(locationVar, locationVar); 150 srcRect.grow(sizeVar, sizeVar); 151 152 Rectangle dstRect = 153 new Rectangle(sizeVar, sizeVar, 154 srcRect.width, srcRect.height); 155 System.out.println("testing blit rect src: " + srcRect); 156 System.out.println(" dst: " + dstRect); 157 render(getGraphics(), srcIm, srcRect, dstRect); 158 test(srcRect, dstRect); 159 } 160 } 161 System.out.println("Test passed."); 162 } finally { 163 synchronized (lock) { 164 done = true; 165 lock.notifyAll(); 166 } 167 } 168 } 169 } 170 171 public void render(Graphics g, Image image, 172 Rectangle srcRect, Rectangle dstRect) 173 { 174 int w = getWidth(); 175 int h = getHeight(); 176 g.setColor(Color.green); 177 g.fillRect(0, 0, w, h); 178 179 int bltWidth = srcRect.width; 180 int bltHeight = srcRect.height; 181 VolatileImage vi = null; 182 if (image instanceof VolatileImage) { 183 vi = (VolatileImage)image; 184 } 185 do { 186 if (vi != null) { 187 GraphicsConfiguration gc = getGraphicsConfiguration(); 188 if (vi.validate(gc) != VolatileImage.IMAGE_OK) { 189 initImage(gc, vi); 190 } 191 } 192 g.drawImage(image, 193 dstRect.x, dstRect.y, 194 dstRect.x + bltWidth, dstRect.y + bltHeight, 195 srcRect.x, srcRect.y, 196 srcRect.x + bltWidth, srcRect.y + bltHeight, 197 Color.red, 198 null); 199 } while (vi != null && vi.contentsLost()); 200 } 201 202 203 public void test(Rectangle srcRect, Rectangle dstRect) { 204 int w = getWidth(); 205 int h = getHeight(); 206 Toolkit.getDefaultToolkit().sync(); 207 try { 208 Thread.sleep(2000); 209 } catch (InterruptedException ex) {} 210 Point p = getLocationOnScreen(); 211 grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h)); 212 213 // calculate the destination rectangle 214 Rectangle srcBounds = srcRect.intersection(IMAGE_BOUNDS); 215 int trX = dstRect.x - srcRect.x; 216 int trY = dstRect.y - srcRect.y; 217 Rectangle newDstRect = (Rectangle)dstRect.clone(); 218 newDstRect.translate(-trX, -trY); 219 Rectangle.intersect(newDstRect, srcBounds, newDstRect); 220 newDstRect.translate(trX, trY); 221 Rectangle.intersect(newDstRect, new Rectangle(0, 0, w, h), newDstRect); 222 223 System.out.println("calculated dest rect:" + newDstRect); 224 225 // we do implicit clipping of the destination surface 226 // by only checking pixels within its bounds 227 for (int y = 0; y < h; y++) { 228 for (int x = 0; x < w; x++) { 229 int rgb = 0; 230 if (newDstRect.contains(x, y)) { 231 rgb = Color.red.getRGB(); 232 } else { 233 rgb = Color.green.getRGB(); 234 } 235 if (grabbedBI.getRGB(x, y) != rgb) { 236 String msg1 = "Test failed at x="+x+" y="+y; 237 System.out.println(msg1); 238 System.out.println(" expected: "+Integer.toHexString(rgb)+ 239 " got:"+Integer.toHexString(grabbedBI.getRGB(x, y))); 240 throw new RuntimeException(msg1); 241 } 242 } 243 } 244 System.out.println("subtest passed"); 245 } 246 247 static VolatileImage dstImage; 248 static void initImage(GraphicsConfiguration gc, Image image) { 249 Graphics g = image.getGraphics(); 250 g.setColor(Color.RED); 251 int w = image.getWidth(null); 252 int h = image.getHeight(null); 253 g.fillRect(0, 0, w, h); 254 g.dispose(); 255 256 // need to 'accelerate' the image 257 if (dstImage == null) { 258 dstImage = 259 gc.createCompatibleVolatileImage(TESTW, TESTH, 260 Transparency.OPAQUE); 261 } 262 dstImage.validate(gc); 263 g = dstImage.getGraphics(); 264 g.drawImage(image, 0, 0, null); 265 g.drawImage(image, 0, 0, null); 266 g.drawImage(image, 0, 0, null); 267 } 268 269 static VolatileImage getVImage(GraphicsConfiguration gc, 270 int w, int h) 271 { 272 VolatileImage image = 273 gc.createCompatibleVolatileImage(w, h, Transparency.OPAQUE); 274 image.validate(gc); 275 initImage(gc, image); 276 return image; 277 } 278 279 static Image getBMImage(GraphicsConfiguration gc, 280 int w, int h) 281 { 282 Image image = 283 gc.createCompatibleImage(w, h, Transparency.BITMASK); 284 initImage(gc, image); 285 return image; 286 } 287 288 static Image getBufferedImage(GraphicsConfiguration gc, 289 int w, int h, int type, boolean acceleratable) 290 { 291 BufferedImage image = new BufferedImage(w, h, type); 292 if (!acceleratable) { 293 image.setAccelerationPriority(0.0f); 294 } 295 initImage(gc, image); 296 return image; 297 } 298 }