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.AlphaComposite; 25 import java.awt.Color; 26 import java.awt.Graphics2D; 27 import java.awt.GraphicsConfiguration; 28 import java.awt.GraphicsEnvironment; 29 import java.awt.Image; 30 import java.awt.Rectangle; 31 import java.awt.Shape; 32 import java.awt.geom.AffineTransform; 33 import java.awt.geom.Ellipse2D; 34 import java.awt.image.BufferedImage; 35 import java.awt.image.VolatileImage; 36 import java.io.File; 37 import java.io.IOException; 38 39 import javax.imageio.ImageIO; 40 41 import static java.awt.geom.Rectangle2D.Double; 42 43 /** 44 * @test 45 * @bug 8041644 46 * @summary Tests drawing volatile image to BI using different clip. 47 * Results of the blit compatibleImage to BI used for comparison. 48 * @author Sergey Bylokhov 49 */ 50 public final class IncorrectClipSurface2SW { 51 52 private static int[] SCALES = {1, 2, 4}; 53 private static int[] SIZES = {127, 3, 2, 1}; 54 private static final Shape[] SHAPES = {new Rectangle(0, 0, 0, 0), 55 new Rectangle(0, 0, 1, 1), 56 new Rectangle(0, 1, 1, 1), 57 new Rectangle(1, 0, 1, 1), 58 new Rectangle(1, 1, 1, 1), 59 60 new Ellipse2D.Double(0, 0, 1, 1), 61 new Ellipse2D.Double(0, 1, 1, 1), 62 new Ellipse2D.Double(1, 0, 1, 1), 63 new Ellipse2D.Double(1, 1, 1, 1), 64 new Ellipse2D.Double(.25, .25, .5, 65 .5), 66 67 new Double(0, 0, 0.5, 0.5), 68 new Double(0, 0.5, 0.5, 0.5), 69 new Double(0.5, 0, 0.5, 0.5), 70 new Double(0.5, 0.5, 0.5, 0.5), 71 new Double(0.25, 0.25, 0.5, 0.5), 72 new Double(0, 0.25, 1, 0.5), 73 new Double(0.25, 0, 0.5, 1), 74 75 new Double(.10, .10, .20, .20), 76 new Double(.75, .75, .20, .20), 77 new Double(.75, .10, .20, .20), 78 new Double(.10, .75, .20, .20),}; 79 80 public static void main(final String[] args) throws IOException { 81 GraphicsEnvironment ge = GraphicsEnvironment 82 .getLocalGraphicsEnvironment(); 83 GraphicsConfiguration gc = ge.getDefaultScreenDevice() 84 .getDefaultConfiguration(); 85 AffineTransform at; 86 for (final int size : SIZES) { 87 for (final int scale : SCALES) { 88 final int sw = size * scale; 89 at = AffineTransform.getScaleInstance(sw, sw); 90 for (Shape clip : SHAPES) { 91 clip = at.createTransformedShape(clip); 92 for (Shape to : SHAPES) { 93 to = at.createTransformedShape(to); 94 // Prepare test images 95 VolatileImage vi = getVolatileImage(gc, size); 96 BufferedImage bi = getBufferedImage(sw); 97 // Prepare gold images 98 BufferedImage goldvi = getCompatibleImage(gc, size); 99 BufferedImage goldbi = getBufferedImage(sw); 100 draw(clip, to, vi, bi, scale); 101 draw(clip, to, goldvi, goldbi, scale); 102 validate(bi, goldbi); 103 } 104 } 105 } 106 } 107 } 108 109 private static void draw(Shape clip, Shape to, Image vi, BufferedImage bi, 110 int scale) { 111 Graphics2D big = bi.createGraphics(); 112 big.setComposite(AlphaComposite.Src); 113 big.setClip(clip); 114 Rectangle toBounds = to.getBounds(); 115 int x1 = toBounds.x; 116 117 int y1 = toBounds.y; 118 int x2 = x1 + toBounds.width; 119 int y2 = y1 + toBounds.height; 120 big.drawImage(vi, x1, y1, x2, y2, 0, 0, toBounds.width / scale, 121 toBounds.height / scale, null); 122 big.dispose(); 123 vi.flush(); 124 } 125 126 private static BufferedImage getBufferedImage(int sw) { 127 BufferedImage bi = new BufferedImage(sw, sw, 128 BufferedImage.TYPE_INT_ARGB); 129 Graphics2D g2d = bi.createGraphics(); 130 g2d.setColor(Color.RED); 131 g2d.fillRect(0, 0, sw, sw); 132 return bi; 133 } 134 135 private static VolatileImage getVolatileImage(GraphicsConfiguration gc, 136 int size) { 137 VolatileImage vi = gc.createCompatibleVolatileImage(size, size); 138 Graphics2D g2d = vi.createGraphics(); 139 g2d.setColor(Color.GREEN); 140 g2d.fillRect(0, 0, size, size); 141 return vi; 142 } 143 144 private static BufferedImage getCompatibleImage(GraphicsConfiguration gc, 145 int size) { 146 BufferedImage image = gc.createCompatibleImage(size, size); 147 Graphics2D g2d = image.createGraphics(); 148 g2d.setColor(Color.GREEN); 149 g2d.fillRect(0, 0, size, size); 150 return image; 151 } 152 153 private static void validate(BufferedImage bi, BufferedImage goldbi) 154 throws IOException { 155 for (int x = 0; x < bi.getWidth(); ++x) { 156 for (int y = 0; y < bi.getHeight(); ++y) { 157 if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) { 158 ImageIO.write(bi, "png", new File("actual.png")); 159 ImageIO.write(goldbi, "png", new File("expected.png")); 160 throw new RuntimeException("Test failed."); 161 } 162 } 163 } 164 } 165 }