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