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