1 /*
   2  * Copyright (c) 2015, 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 6430601
  27  * @summary Verifies that copyArea() works properly when the
  28  * destination parameters are outside the destination bounds.
  29  * @run main/othervm CopyAreaOOB
  30  * @run main/othervm -Dsun.java2d.opengl=True CopyAreaOOB
  31  * @author campbelc
  32  */
  33 
  34 import java.awt.*;
  35 import java.awt.image.*;
  36 
  37 public class CopyAreaOOB extends Canvas {
  38 
  39     private static boolean done;
  40 
  41     public void paint(Graphics g) {
  42         synchronized (this) {
  43             if (done) {
  44                 return;
  45             }
  46         }
  47 
  48         int w = getWidth();
  49         int h = getHeight();
  50 
  51         Graphics2D g2d = (Graphics2D)g;
  52         g2d.setColor(Color.black);
  53         g2d.fillRect(0, 0, w, h);
  54 
  55         g2d.setColor(Color.green);
  56         g2d.fillRect(0, 0, w, 10);
  57 
  58         g2d.setColor(Color.red);
  59         g2d.fillRect(0, 10, 50, h-10);
  60 
  61         // copy the region such that part of it goes below the bottom of the
  62         // destination surface
  63         g2d.copyArea(0, 10, 50, h-10, 60, 10);
  64 
  65         Toolkit.getDefaultToolkit().sync();
  66 
  67         synchronized (this) {
  68             done = true;
  69             notifyAll();
  70         }
  71     }
  72 
  73     public Dimension getPreferredSize() {
  74         return new Dimension(400, 400);
  75     }
  76 
  77     private static void testRegion(BufferedImage bi, String name,
  78                                    int x1, int y1, int x2, int y2,
  79                                    int expected)
  80     {
  81         for (int y = y1; y < y2; y++) {
  82             for (int x = x1; x < x2; x++) {
  83                 int actual = bi.getRGB(x, y);
  84                 if (actual != expected) {
  85                     throw new RuntimeException("Test failed for " + name +
  86                                                        " region at x="+x+" y="+y+
  87                                                        " (expected="+
  88                                                        Integer.toHexString(expected) +
  89                                                        " actual="+
  90                                                        Integer.toHexString(actual) +
  91                                                        ")");
  92                 }
  93             }
  94         }
  95     }
  96 
  97     public static void main(String[] args) {
  98         boolean show = (args.length == 1) && ("-show".equals(args[0]));
  99 
 100         CopyAreaOOB test = new CopyAreaOOB();
 101         Frame frame = new Frame();
 102         frame.setUndecorated(true);
 103         frame.add(test);
 104         frame.pack();
 105         frame.setLocationRelativeTo(null);
 106         frame.setVisible(true);
 107 
 108         // Wait until the component's been painted
 109         synchronized (test) {
 110             while (!done) {
 111                 try {
 112                     test.wait();
 113                 } catch (InterruptedException e) {
 114                     throw new RuntimeException("Failed: Interrupted");
 115                 }
 116             }
 117         }
 118 
 119         try {
 120             Thread.sleep(2000);
 121         } catch (InterruptedException ex) {}
 122 
 123         // Grab the screen region
 124         BufferedImage capture = null;
 125         try {
 126             Robot robot = new Robot();
 127             Point pt1 = test.getLocationOnScreen();
 128             Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400);
 129             capture = robot.createScreenCapture(rect);
 130         } catch (Exception e) {
 131             throw new RuntimeException("Problems creating Robot");
 132         } finally {
 133             if (!show) {
 134                 frame.dispose();
 135             }
 136         }
 137 
 138         // Test pixels
 139         testRegion(capture, "green",          0,   0, 400,  10, 0xff00ff00);
 140         testRegion(capture, "original red",   0,  10,  50, 400, 0xffff0000);
 141         testRegion(capture, "background",    50,  10,  60, 400, 0xff000000);
 142         testRegion(capture, "in-between",    60,  10, 110,  20, 0xff000000);
 143         testRegion(capture, "copied red",    60,  20, 110, 400, 0xffff0000);
 144         testRegion(capture, "background",   110,  10, 400, 400, 0xff000000);
 145     }
 146 }