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