1 /*
   2  * Copyright (c) 2011, 2013, 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  * @summary Builds on testcase Polys02, adding XOR and LiveResize into the mix.
  27  * @summary <rdar://problem/4969413> [JavaJDK15] g.fillPolygon + resize -> CGContextGetClipBoundingBox: invalid context
  28  * @summary com.apple.junit.java.graphics.images
  29  * @library ../../regtesthelpers
  30  * @build LiveResizeAction MovingPoints
  31  * @run junit PolysStress
  32  */
  33 
  34 import test.java.awt.regtesthelpers.LiveResizeAction;
  35 import test.java.awt.regtesthelpers.MovingPoints;
  36 import junit.framework.*;
  37 import javax.swing.*;
  38 import java.awt.*;
  39 import java.util.*;
  40 import java.util.Timer;
  41 
  42 
  43 public class PolysStress extends TestCase {
  44     static boolean TESTXOR = true;
  45     static boolean RUNLONG = false;
  46     static final Random rand = new Random( 0x20406 );
  47     Timer ticktock = new Timer();
  48 
  49     //
  50     //  Constants controlling the scene
  51     //
  52     static Rectangle rect = new Rectangle( 40, 40, 350, 400 );
  53     static final int SLOP = 120;
  54     static final int kPolys = 5;
  55 
  56     //
  57     // An animator class so the scene is vaguely interesting
  58     //
  59     abstract protected class ActivePolygon extends MovingPoints {
  60         protected Color color = null;
  61         // Some initial conditions
  62 
  63         public ActivePolygon(Rectangle r) {
  64             super(r, Math.max(3, rand.nextInt(5) + rand.nextInt(5) + rand.nextInt(5)));
  65             color = new Color(rand.nextInt(0xFF), rand.nextInt(0xFF), rand.nextInt(0xFF));
  66         }
  67 
  68         abstract public void render(Graphics g);
  69     }
  70 
  71     //
  72     // A polygon that draws via setColor
  73     //
  74     class NormalPolygon extends ActivePolygon {
  75 
  76         public NormalPolygon(Rectangle r) {
  77             super(r);
  78         }
  79 
  80         public void render(Graphics g) {
  81             g.setColor(color);
  82             g.fillPolygon(new Polygon(getXs(), getYs(), getNumVertices()));
  83         }
  84     }
  85 
  86     //
  87     // A polygon that draws via setXORMode
  88     //
  89     class XorPolygon extends ActivePolygon {
  90 
  91         public XorPolygon(Rectangle r) {
  92             super(r);
  93         }
  94 
  95         public void render(Graphics g) {
  96             g.setXORMode(color);
  97             g.fillPolygon(new Polygon(getXs(), getYs(), getNumVertices()));
  98         }
  99     }
 100 
 101     /*
 102      */
 103 
 104     class AnimatedWindow extends Frame {
 105         volatile   ActivePolygon[] polys = new ActivePolygon[kPolys];
 106         Rectangle rect = null;
 107         TimerTask renderer;
 108 
 109         public AnimatedWindow( Rectangle rect ) throws Exception {
 110             super( "AnimatingFrame" );
 111             this.rect = rect;
 112             setBounds( rect );
 113 
 114             int peX = -SLOP;
 115             int peY = -SLOP;
 116             int peW = rect.width+SLOP;
 117             int peH = rect.height+SLOP;
 118             Rectangle polyedges = new Rectangle(  peX, peY, peW, peH);
 119             for (int i = 0; i<polys.length; i++ ) {
 120                 if (TESTXOR && i % 2 == 0) {
 121                     polys[i] = new XorPolygon( polyedges );
 122                 }
 123                 else {
 124                     polys[i] = new NormalPolygon( polyedges );
 125                 }
 126             }
 127 
 128             setVisible(true);
 129 
 130             // Simple animation into a cached graphics object
 131             renderer = new TimerTask() {
 132                 public void run() {
 133                     AnimatedWindow.this.animateOnce();
 134                     AnimatedWindow.this.repaint();
 135                 }
 136             };
 137             ticktock.schedule(renderer, 0L, 50L);
 138         }
 139 
 140         public void animateOnce() {
 141             for (ActivePolygon item : polys) {
 142                 item.move();
 143             }
 144         }
 145 
 146         public void paint( Graphics gg ) {
 147             super.paint(gg );
 148             gg.setColor(Color.cyan);
 149             gg.fillRect(0, 0, rect.width, rect.height);
 150             for (ActivePolygon item : polys) {
 151                 item.render(gg);
 152             }
 153 
 154         }
 155     }
 156 
 157     volatile boolean done = false;
 158 
 159     public void testPolyWithXORandLiveResize() throws Exception {
 160         final AnimatedWindow testWindow = new AnimatedWindow(rect);
 161 
 162         // Attach a resizer to the Frame
 163         //LiveResizeThread lrt = new LiveResizeThread(testWindow, LiveResizeThread.VIARIABLE_MOVE);
 164         //lrt.start();
 165         final LiveResizeAction.VariableMove move = new LiveResizeAction.VariableMove(testWindow, new Robot());
 166         move.run();
 167 
 168         TimerTask stopper = new TimerTask() {
 169             public void run() {
 170                 done = true;
 171             }
 172         };
 173 
 174         if (!RUNLONG) {
 175             ticktock.schedule(stopper, 4250L);
 176         }
 177         else {
 178             ticktock.schedule(stopper, 30000L);
 179         }
 180 
 181         //while(!done || !lrt.isDone()) {
 182         //  Thread.sleep(250);
 183         //}
 184 
 185         testWindow.renderer.cancel();
 186         ticktock.cancel();
 187 
 188         SwingUtilities.invokeLater(new Runnable() {
 189             public void run() {
 190                 testWindow.dispose();
 191             }
 192         });
 193     }
 194 
 195     public static Test suite() {
 196         return new TestSuite( PolysStress.class);
 197     }
 198 
 199     public static void main( String[] args ) {
 200         for (String arg : args) {
 201             if (arg.toLowerCase().equals("-runlong")) {
 202                 RUNLONG=true;
 203             }
 204         }
 205         TestResult tr = junit.textui.TestRunner.run(suite());
 206         if ((tr.errorCount() != 0) || (tr.failureCount() != 0)) {
 207             throw new RuntimeException("### FAILED: unexpected JUnit errors or failures.");
 208         }
 209     }
 210 }
 211 
 212 
 213