OSDN Git Service

2006-08-14 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / examples / gnu / classpath / examples / java2d / J2dBenchmark.java
diff --git a/libjava/classpath/examples/gnu/classpath/examples/java2d/J2dBenchmark.java b/libjava/classpath/examples/gnu/classpath/examples/java2d/J2dBenchmark.java
new file mode 100644 (file)
index 0000000..118ae24
--- /dev/null
@@ -0,0 +1,1571 @@
+/* J2dBenchmark.java -- Benchmarking utility for java2d,
+   based on the Aicas AWT benchmarker
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath examples.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA. */
+
+package gnu.classpath.examples.java2d;
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Label;
+import java.awt.MediaTracker;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.TexturePaint;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.QuadCurve2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class J2dBenchmark
+    extends Panel
+{
+  /**
+   * Default number of test-iterations.
+   */
+  protected static final int DEFAULT_TEST_SIZE = 1000;
+
+  /**
+   * Default screen size.
+   */
+  protected static final int DEFAULT_SCREEN_WIDTH = 320;
+
+  protected static final int DEFAULT_SCREEN_HEIGHT = 240;
+
+  /**
+   * Java2D tests.
+   */
+  protected static final int J2DTEST_ARC = 1 << 0;
+
+  protected static final int J2DTEST_CUBICCURVE = 1 << 1;
+
+  protected static final int J2DTEST_ELLIPSE = 1 << 2;
+
+  protected static final int J2DTEST_GENERALPATH = 1 << 3;
+
+  protected static final int J2DTEST_LINE = 1 << 4;
+
+  protected static final int J2DTEST_QUADCURVE = 1 << 5;
+
+  protected static final int J2DTEST_RECTANGLE = 1 << 6;
+
+  protected static final int J2DTEST_ROUNDRECTANGLE = 1 << 7;
+
+  protected static final int J2DTEST_IMAGE = 1 << 8;
+
+  protected static final int J2DTEST_NONE = 0;
+
+  /*
+  private static final int J2DTEST_ALL = J2DTEST_ARC | J2DTEST_CUBICCURVE
+                                         | J2DTEST_ELLIPSE
+                                         | J2DTEST_GENERALPATH | J2DTEST_LINE
+                                         | J2DTEST_QUADCURVE
+                                         | J2DTEST_RECTANGLE
+                                         | J2DTEST_ROUNDRECTANGLE
+                                         | J2DTEST_IMAGE;
+  */
+  private static final int J2DTEST_ALL = J2DTEST_ARC | J2DTEST_CUBICCURVE
+                                         | J2DTEST_ELLIPSE
+                                         | J2DTEST_LINE
+                                         | J2DTEST_QUADCURVE
+                                         | J2DTEST_RECTANGLE
+                                         | J2DTEST_ROUNDRECTANGLE
+                                         | J2DTEST_IMAGE;
+
+  int iterations = 1;
+
+  protected int screenWidth = DEFAULT_SCREEN_WIDTH;
+
+  protected int screenHeight = DEFAULT_SCREEN_HEIGHT;
+
+  protected boolean noClippingFlag = true;
+
+  protected boolean withClippingFlag = true;
+
+  protected boolean zeroClippingFlag = true;
+
+  protected boolean singleBufferFlag = true;
+
+  protected boolean doubleBufferFlag = true;
+
+  protected boolean gradientFlag = false;
+
+  protected String texture = null;
+
+  protected boolean strokeFlag = false;
+
+  protected float composite = 1;
+
+  protected int xtranslate = 0;
+
+  protected int ytranslate = 0;
+
+  protected double xshear = 0;
+
+  protected double yshear = 0;
+
+  protected double rotate = 0;
+
+  protected boolean antialiasFlag = false;
+
+  protected AffineTransform affineTransform = null;
+
+  protected int awtTests = J2DTEST_ALL;
+
+  protected int testSize = DEFAULT_TEST_SIZE;
+
+  private Label testLabel;
+
+  private String testContext = "";
+
+  Logger logger = Logger.getLogger("J2dGraphicsBenchmark");
+
+  private Image pngTestImage;
+
+  private Image gifTestImage;
+
+  protected BufferedImage textureImage;
+
+  protected TestSet testSetMap = new TestSet();
+
+  public String init()
+  {
+    boolean loadError = false;
+    pngTestImage = loadImage("aicas.png");
+    gifTestImage = loadImage("palme.gif");
+
+    if (texture != null)
+      {
+        textureImage = loadBufferedImage(texture);
+
+        if (textureImage == null)
+          {
+            logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "init",
+                        "Unable to load texture - defaulting "
+                            + "to solid colours");
+            texture = null;
+            loadError = true;
+          }
+      }
+
+    setLayout(new BorderLayout());
+    testLabel = new Label();
+    add(testLabel, BorderLayout.NORTH);
+    add(new GraphicsTest(), BorderLayout.CENTER);
+
+    if (loadError)
+      return "Unable to load image";
+    else
+      return null;
+  }
+
+  void setTestContext(String testName)
+  {
+    logger.logp(Level.INFO, "J2dGraphicsBenchmark", "recordTest",
+                "--- Starting new test context: " + testName);
+    testContext = testName;
+    testLabel.setText(testName);
+  }
+
+  private void recordTest(String testName, long time)
+  {
+    logger.logp(Level.INFO, "J2dGraphicsBenchmark", "recordTest",
+                testContext + ": " + testName + " duration (ms): " + time);
+    TestRecorder recorder = testSetMap.getTest(testName);
+    if (recorder == null)
+      {
+        recorder = new TestRecorder(testName);
+        testSetMap.putTest(testName, recorder);
+      }
+    recorder.addRun(time);
+  }
+
+  void printReport()
+  {
+    for (Iterator i = testSetMap.testIterator(); i.hasNext();)
+      {
+        TestRecorder recorder = testSetMap.getTest((String) i.next());
+        System.out.println("TEST " + recorder.getTestName() + ": average "
+                           + recorder.getAverage() + "ms ["
+                           + recorder.getMinTime() + "-"
+                           + recorder.getMaxTime() + "]");
+      }
+  }
+
+  void testComplete()
+  {
+    System.exit(0);
+  }
+
+  public static void main(String[] args)
+  {
+    int awtTests;
+    int i;
+    boolean endOfOptionsFlag;
+    J2dBenchmark speed = new J2dBenchmark();
+
+    // Parse arguments.
+    i = 0;
+    endOfOptionsFlag = false;
+    awtTests = J2DTEST_NONE;
+    while (i < args.length)
+      {
+        if (! endOfOptionsFlag)
+          {
+            if (args[i].equals("--help") || args[i].equals("-help")
+                || args[i].equals("-h"))
+              {
+                System.out.println("Usage: J2dBenchmark [<options>] [<test>  ...]");
+                System.out.println("");
+                System.out.println("Options: -i|--iterations=<n|-1> - number of iterations (-1 is infinite; default "
+                                   + speed.iterations + ")");
+                System.out.println("         -w|--width=<n>         - screen width; default "
+                                   + DEFAULT_SCREEN_WIDTH);
+                System.out.println("         -h|--height=<n>        - screen height; default "
+                                   + DEFAULT_SCREEN_HEIGHT);
+                System.out.println("         -d|--noDoubleBuffer    - disable double-buffering test");
+                System.out.println("         -s|--testsize=<n>      - size of each test; default "
+                                   + DEFAULT_TEST_SIZE);
+                System.out.println("         -c|--noClipping        - disable clipping test");
+                System.out.println("         -z|--noZeroClipping    - disable clipping to zero test");
+                System.out.println("");
+                System.out.println("Additional options:");
+                System.out.println("         --with-gradients       - enable gradients (not compatible with --texture)");
+                System.out.println("         --with-stroking        - enable random stroking");
+                System.out.println("         --texture=<file>       - enable texturing with this file (not compatible with --with-gradients)");
+                System.out.println("         --composite=<n|-1>     - set alpha composite level; -1 for random; default 1.0 (no transparency)");
+                System.out.println("         --anti-alias=<on|off>  - set anti-aliasing hint (not all implementations respect this); default off");
+                System.out.println("         --x-translate=<n>      - set x-axis translation; default 0");
+                System.out.println("         --y-translate=<n>      - set y-axis translation; default 0");
+                System.out.println("         --x-shear=<n>          - set x-axis shear; default 0");
+                System.out.println("         --y-shear=<n>          - set y-axis shear; default 0");
+                System.out.println("         --rotate=<n|-1>        - set rotation (radians); -1 for random; default: 0 (none)");
+                System.out.println("");
+                System.out.println("Tests: arc");
+                System.out.println("       cubiccurve");
+                System.out.println("       ellipse");
+                // System.out.println(" generalpath");
+                System.out.println("       line");
+                System.out.println("       quadcurve");
+                System.out.println("       rectangle");
+                System.out.println("       roundrectangle");
+                System.out.println("       image");
+                System.exit(1);
+              }
+            else if ((args[i].startsWith("-i=") || args[i].startsWith("--iterations=")))
+              {
+                speed.iterations = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if ((args[i].equals("-i") || args[i].equals("--iterations")))
+              {
+                if ((i + 1) >= args.length)
+                  {
+                    System.err.println("ERROR: No argument given for option '"
+                                       + args[i] + "'!");
+                    System.exit(2);
+                  }
+                speed.iterations = Integer.parseInt(args[i + 1]);
+                i += 2;
+                continue;
+              }
+            else if ((args[i].startsWith("-w=") || args[i].startsWith("--width=")))
+              {
+                speed.screenWidth = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if ((args[i].equals("-w") || args[i].equals("--width")))
+              {
+                if ((i + 1) >= args.length)
+                  {
+                    System.err.println("ERROR: No argument given for option '"
+                                       + args[i] + "'!");
+                    System.exit(2);
+                  }
+                speed.screenWidth = Integer.parseInt(args[i + 1]);
+                i += 2;
+                continue;
+              }
+            else if ((args[i].startsWith("-h=") || args[i].startsWith("--height=")))
+              {
+                speed.screenHeight = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if ((args[i].equals("-h") || args[i].equals("--height")))
+              {
+                if ((i + 1) >= args.length)
+                  {
+                    System.err.println("ERROR: No argument given for option '"
+                                       + args[i] + "'!");
+                    System.exit(2);
+                  }
+                speed.screenHeight = Integer.parseInt(args[i + 1]);
+                i += 2;
+                continue;
+              }
+            else if ((args[i].equals("-d") || args[i].equals("--noDoubleBuffer")))
+              {
+                speed.doubleBufferFlag = false;
+                i += 1;
+                continue;
+              }
+            else if ((args[i].startsWith("-s=") || args[i].startsWith("--testsize=")))
+              {
+                if ((i + 1) >= args.length)
+                  {
+                    System.err.println("ERROR: No argument given for option '"
+                                       + args[i] + "'!");
+                    System.exit(2);
+                  }
+                speed.testSize = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if ((args[i].equals("-s") || args[i].equals("--testsize")))
+              {
+                if ((i + 1) >= args.length)
+                  {
+                    System.err.println("ERROR: No argument given for option '"
+                                       + args[i] + "'!");
+                    System.exit(2);
+                  }
+                speed.testSize = Integer.parseInt(args[i + 1]);
+                i += 2;
+                continue;
+              }
+            else if ((args[i].equals("-c") || args[i].equals("--noClipping")))
+              {
+                speed.noClippingFlag = false;
+                i += 1;
+                continue;
+              }
+            else if ((args[i].equals("-z") || args[i].equals("--noZeroClipping")))
+              {
+                speed.zeroClippingFlag = false;
+                i += 1;
+                continue;
+              }
+            else if (args[i].equals("--with-gradients"))
+              {
+                speed.gradientFlag = true;
+                i += 1;
+                continue;
+              }
+            else if (args[i].equals("--with-stroking"))
+              {
+                speed.strokeFlag = true;
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--texture="))
+              {
+                speed.texture = args[i].substring(args[i].indexOf('=') + 1);
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--composite="))
+              {
+                speed.composite = Float.parseFloat(args[i].substring(args[i].indexOf('=') + 1));
+                if (speed.composite != - 1
+                    && (speed.composite < 0 || speed.composite > 1))
+                  {
+                    System.err.println("ERROR: Invalid value for composite (must be between 0 and 1, or -1 for random)");
+                    System.exit(2);
+                  }
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--anti-alias="))
+              {
+                speed.antialiasFlag = (args[i].substring(args[i].indexOf('=') + 1).equals("on"));
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--x-translate="))
+              {
+                speed.xtranslate = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--y-translate="))
+              {
+                speed.ytranslate = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--x-shear="))
+              {
+                speed.xshear = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--y-shear="))
+              {
+                speed.yshear = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("--rotate="))
+              {
+                speed.rotate = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
+                i += 1;
+                continue;
+              }
+
+            else if (args[i].equals("--"))
+              {
+                endOfOptionsFlag = true;
+                i += 1;
+                continue;
+              }
+            else if (args[i].startsWith("-"))
+              {
+                System.err.println("ERROR: Unknown option '" + args[i] + "'!");
+                System.exit(2);
+              }
+          }
+        StringTokenizer tokenizer = new StringTokenizer(args[i], " +,");
+        while (tokenizer.hasMoreTokens())
+          {
+            String s = tokenizer.nextToken().toLowerCase();
+            if (s.equals("arc"))
+              awtTests |= J2DTEST_ARC;
+            else if (s.equals("cubiccurve"))
+              awtTests |= J2DTEST_CUBICCURVE;
+            else if (s.equals("ellipse"))
+              awtTests |= J2DTEST_ELLIPSE;
+            else if (s.equals("generalpath"))
+              awtTests |= J2DTEST_GENERALPATH;
+            else if (s.equals("line"))
+              awtTests |= J2DTEST_LINE;
+            else if (s.equals("quadcurve"))
+              awtTests |= J2DTEST_QUADCURVE;
+            else if (s.equals("rectangle"))
+              awtTests |= J2DTEST_RECTANGLE;
+            else if (s.equals("roundrectangle"))
+              awtTests |= J2DTEST_ROUNDRECTANGLE;
+            else if (s.equals("image"))
+              awtTests |= J2DTEST_IMAGE;
+            else
+              {
+                System.err.println("Unknown AWT test '" + s + "'!");
+                System.exit(2);
+              }
+          }
+        i += 1;
+      }
+    if (awtTests != J2DTEST_NONE)
+      speed.awtTests = awtTests;
+
+    // Create graphics.
+    speed.init();
+    final Frame frame = new Frame("J2dGraphicsBenchmark");
+
+    frame.addWindowListener(new WindowAdapter()
+    {
+      public void windowClosing(WindowEvent e)
+      {
+        frame.setVisible(false);
+        System.exit(0);
+      }
+    });
+
+    frame.add(speed, BorderLayout.CENTER);
+    frame.setSize(speed.screenWidth, speed.screenHeight);
+    frame.setVisible(true);
+
+    // Insets are correctly set only after the native peer was created.
+    Insets insets = frame.getInsets();
+    // The internal size of the frame should be 320x240.
+    frame.setSize(320 + insets.right + insets.left, 240 + insets.top
+                                                    + insets.bottom);
+  }
+
+  private Image loadImage(String imageName)
+  {
+    Image result = null;
+    logger.logp(Level.INFO, "J2dGraphicsBenchmark", "loadImage",
+                "Loading image: " + imageName);
+    URL url = getClass().getResource(imageName);
+    if (url != null)
+      {
+        result = Toolkit.getDefaultToolkit().getImage(url);
+        prepareImage(result, this);
+      }
+    else
+      {
+        logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "loadImage",
+                    "Could not locate image resource in class path: "
+                        + imageName);
+      }
+    return result;
+  }
+
+  private BufferedImage loadBufferedImage(String imageName)
+  {
+    BufferedImage result = null;
+    logger.logp(Level.INFO, "J2dGraphicsBenchmark", "loadImage",
+                "Loading image: " + imageName);
+
+    // Try to load image out of classpath before trying an absolute filename
+    URL url = getClass().getResource(imageName);
+    Image img;
+    if (url != null)
+      img = Toolkit.getDefaultToolkit().getImage(url);
+    else
+      img = Toolkit.getDefaultToolkit().getImage(imageName);
+
+    if (img != null)
+      {
+        // Wait for image to load
+        try
+          {
+            MediaTracker tracker = new MediaTracker(this);
+            tracker.addImage(img, 1);
+            tracker.waitForAll();
+
+            prepareImage(img, this);
+            result = new BufferedImage(img.getWidth(this), img.getHeight(this),
+                                       BufferedImage.TYPE_INT_RGB);
+            result.createGraphics().drawImage(img, 0, 0, this);
+          }
+        catch (InterruptedException e)
+          {
+          }
+        catch (IllegalArgumentException e)
+          {
+          }
+      }
+
+    if (result == null)
+      {
+        logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "loadBufferedImage",
+                    "Could not locate image resource in class path: "
+                        + imageName);
+      }
+    return result;
+  }
+
+  /**
+   * Executes the test methods.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  void runTestSet(Graphics2D g, Dimension size)
+  {
+    // Any user-specified options (ie set transforms, rendering hints)
+    prepareGraphics((Graphics2D) g);
+
+    if ((awtTests & J2DTEST_ARC) != 0)
+      {
+        test_drawArc(g, size);
+        test_fillArc(g, size);
+      }
+
+    if ((awtTests & J2DTEST_CUBICCURVE) != 0)
+      {
+        test_drawCubicCurve(g, size);
+      }
+
+    if ((awtTests & J2DTEST_ELLIPSE) != 0)
+      {
+        test_drawEllipse(g, size);
+        test_fillEllipse(g, size);
+      }
+
+    if ((awtTests & J2DTEST_GENERALPATH) != 0)
+      {
+        // Current implementation doesn't work
+        test_drawGeneralPath(g, size);
+        test_fillGeneralPath(g, size);
+      }
+
+    if ((awtTests & J2DTEST_LINE) != 0)
+      {
+        test_drawLine(g, size);
+      }
+
+    if ((awtTests & J2DTEST_QUADCURVE) != 0)
+      {
+        test_drawQuadCurve(g, size);
+      }
+
+    if ((awtTests & J2DTEST_RECTANGLE) != 0)
+      {
+        test_drawRectangle(g, size);
+        test_fillRectangle(g, size);
+      }
+
+    if ((awtTests & J2DTEST_ROUNDRECTANGLE) != 0)
+      {
+        test_drawRoundRectangle(g, size);
+        test_fillRoundRectangle(g, size);
+      }
+
+    if ((awtTests & J2DTEST_IMAGE) != 0)
+      {
+        test_drawImage(g, size);
+        test_drawTransparentImage(g, size);
+      }
+  }
+
+  /**
+   * Reset all graphics settings to the standard, default values
+   * 
+   * @param g the object to apply settings to
+   */
+  private void resetGraphics(Graphics2D g)
+  {
+    g.setTransform(new AffineTransform());
+    g.setStroke(new BasicStroke());
+    g.setComposite(AlphaComposite.SrcOut);
+  }
+
+  /**
+   * Sets initial user graphics options
+   * 
+   * @param g the object to apply settings to
+   */
+  private void prepareGraphics(Graphics2D g)
+  {
+    // Transforms
+    if (affineTransform != null)
+      g.setTransform(affineTransform);
+
+    else if (xtranslate != 0 || ytranslate != 0 || xshear != 0 || yshear != 0)
+      {
+        g.translate(xtranslate, ytranslate);
+        g.shear(xshear, yshear);
+      }
+
+    if (rotate > 0)
+      g.rotate(rotate * Math.PI, screenWidth / 2, screenHeight / 2);
+
+    // Composite (transparency)
+    if (composite > 0)
+      {
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
+                                                  composite));
+      }
+
+    // Textures
+    if (texture != null)
+      g.setPaint(new TexturePaint(textureImage,
+                                  new Rectangle(0, 0, textureImage.getWidth(),
+                                                textureImage.getHeight())));
+
+    // Anti-alias setting
+    if (antialiasFlag)
+      g.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
+                                             RenderingHints.VALUE_ANTIALIAS_ON));
+    else
+      g.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
+                                             RenderingHints.VALUE_ANTIALIAS_OFF));
+  }
+
+  /**
+   * Gets new random settings
+   * 
+   * @param g the object to set parameters for
+   * @param size the screen size
+   */
+  private void setRandom(Graphics2D g, Dimension size)
+  {
+    // Set colour / paint
+    if (gradientFlag)
+      {
+        Color c1 = new Color((int) (Math.random() * 254) + 1,
+                             (int) (Math.random() * 254) + 1,
+                             (int) (Math.random() * 254) + 1);
+
+        Color c2 = new Color((int) (Math.random() * 254) + 1,
+                             (int) (Math.random() * 254) + 1,
+                             (int) (Math.random() * 254) + 1);
+
+        g.setPaint(new GradientPaint(0, 0, c1, screenWidth / 5,
+                                     screenHeight / 5, c2, true));
+      }
+
+    else if (texture == null)
+      g.setPaint(new Color((int) (Math.random() * 254) + 1,
+                           (int) (Math.random() * 254) + 1,
+                           (int) (Math.random() * 254) + 1));
+
+    // Set stroke width and options
+    if (strokeFlag)
+      {
+        int cap = (int) (Math.random() * 3 + 1);
+        if (cap == 1)
+          cap = BasicStroke.CAP_SQUARE;
+        else if (cap == 2)
+          cap = BasicStroke.CAP_BUTT;
+        else
+          cap = BasicStroke.CAP_ROUND;
+
+        int join = (int) (Math.random() * 3 + 1);
+        if (join == 1)
+          join = BasicStroke.JOIN_MITER;
+        else if (join == 2)
+          join = BasicStroke.JOIN_BEVEL;
+        else
+          join = BasicStroke.JOIN_ROUND;
+
+        float[] dashes = { 10, 10 };
+        g.setStroke(new BasicStroke((int) (Math.random() * 10), cap, join, 10f,
+                                    dashes, 0));
+      }
+
+    // Composite / transparency
+    if (composite == - 1)
+      {
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
+                                                  (float) Math.random()));
+      }
+
+    // Transformations
+    if (rotate == - 1)
+      g.rotate(Math.random() * Math.PI * 2);
+  }
+
+  /**
+   * Draws random arcs within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawArc(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize;
+    long startTime;
+    long endTime;
+    minSize = 10;
+    startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - minSize + 1));
+        int y = (int) (Math.random() * (size.height - minSize + 1));
+        int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
+        int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
+        int startAngle = (int) (Math.random() * 360);
+        int arcAngle = (int) (Math.random() * 360 - startAngle);
+
+        Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle,
+                                     Arc2D.OPEN);
+        g.draw(arc);
+      }
+    endTime = System.currentTimeMillis();
+    recordTest("draw(Arc2D.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random filled arcs within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_fillArc(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize;
+    long startTime;
+    long endTime;
+    minSize = 10;
+    startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - minSize + 1));
+        int y = (int) (Math.random() * (size.height - minSize + 1));
+        int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
+        int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
+        int startAngle = (int) (Math.random() * 360);
+        int arcAngle = (int) (Math.random() * 360);
+
+        Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle,
+                                     Arc2D.OPEN);
+        g.fill(arc);
+      }
+    endTime = System.currentTimeMillis();
+    recordTest("fill(Arc2D.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random cubic curves within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawCubicCurve(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int xc1 = (int) (Math.random() * (size.width - minSize));
+        int yc1 = (int) (Math.random() * (size.height - minSize));
+        int xc2 = (int) (Math.random() * (size.width - minSize));
+        int yc2 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+
+        CubicCurve2D curve = new CubicCurve2D.Double(x1, y1, xc1, yc1, xc2,
+                                                     yc2, x2, y2);
+        g.draw(curve);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(CubicCurve2D.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random ellipses within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawEllipse(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+        Ellipse2D ellipse = new Ellipse2D.Double(x1, y1, x2, y2);
+        g.draw(ellipse);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(Ellipse.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random ellipses within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_fillEllipse(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+        Ellipse2D ellipse = new Ellipse2D.Double(x1, y1, x2, y2);
+        g.fill(ellipse);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("fill(Ellipse.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  // TODO: fix the GeneralPath methods.
+  /**
+   * Draws random polygons within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawGeneralPath(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    long startTime = System.currentTimeMillis();
+
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int points = (int) (Math.random() * 6) + 2;
+        GeneralPath shape = new GeneralPath();
+        shape.moveTo((float) Math.random() * (size.width),
+                     (float) Math.random() * (size.height));
+        for (int j = 0; j < points; j += 1)
+          {
+            shape.lineTo((float) (Math.random() * (size.width)),
+                         (float) (Math.random() * (size.height)));
+          }
+        g.draw(shape);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(GeneralPath) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random filled polygons within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_fillGeneralPath(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    long startTime = System.currentTimeMillis();
+
+    GeneralPath shape = new GeneralPath();
+    shape.moveTo((float) Math.random() * (size.width), (float) Math.random()
+                                                       * (size.height));
+
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int points = (int) (Math.random() * 6) + 2;
+        for (int j = 0; j < points; j += 1)
+          {
+            shape.lineTo((float) (Math.random() * (size.width)),
+                         (float) (Math.random() * (size.height)));
+          }
+        g.fill(shape);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("fill(GeneralPath) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random lines within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawLine(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+        Line2D line = new Line2D.Double(x1, y1, x2, y2);
+        g.draw(line);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(Line2D.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random quadratic curves within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawQuadCurve(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int xc = (int) (Math.random() * (size.width - minSize));
+        int yc = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+
+        QuadCurve2D curve = new QuadCurve2D.Double(x1, y1, xc, yc, x2, y2);
+        g.draw(curve);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(QuadCurve2D.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random rectangles within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawRectangle(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+        Rectangle2D rect = new Rectangle2D.Double(x1, y1, x2, y2);
+        g.draw(rect);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw(Rectangle.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random rectangles within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_fillRectangle(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize = 10;
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x1 = (int) (Math.random() * (size.width - minSize));
+        int y1 = (int) (Math.random() * (size.height - minSize));
+        int x2 = (int) (Math.random() * (size.width - minSize));
+        int y2 = (int) (Math.random() * (size.height - minSize));
+        Rectangle2D rect = new Rectangle2D.Double(x1, y1, x2, y2);
+        g.fill(rect);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("fill(Rectangle.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random rounded rectangles within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawRoundRectangle(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize;
+    long startTime;
+    long endTime;
+    minSize = 10;
+    startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - minSize + 1));
+        int y = (int) (Math.random() * (size.height - minSize + 1));
+        int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
+        int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
+        int arcWidth = (int) (Math.random() * (width - 1) + 1);
+        int arcHeight = (int) (Math.random() * (height - 1) + 5);
+        RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
+                                                            height, arcWidth,
+                                                            arcHeight);
+        g.draw(rect);
+      }
+    endTime = System.currentTimeMillis();
+    recordTest("draw(RoundRectangle.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random filled rounded rectangles within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_fillRoundRectangle(Graphics2D g, Dimension size)
+  {
+    int maxTests = testSize;
+    int minSize;
+    long startTime;
+    long endTime;
+    minSize = 10;
+    startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - minSize + 1));
+        int y = (int) (Math.random() * (size.height - minSize + 1));
+        int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
+        int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
+        int arcWidth = (int) (Math.random() * (width - 1) + 1);
+        int arcHeight = (int) (Math.random() * (height - 1) + 5);
+        RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
+                                                            height, arcWidth,
+                                                            arcHeight);
+        g.fill(rect);
+      }
+    endTime = System.currentTimeMillis();
+    recordTest("fill(RoundRectangle.Double) " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  /**
+   * Draws random images within the given dimensions.
+   * 
+   * @param g The Graphics2D object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawImage(Graphics2D g, Dimension size)
+  {
+    if (gifTestImage == null)
+      {
+        logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "runTestSet",
+                    "Skipping 'test_drawImage' due to missing resource.");
+        return;
+      }
+
+    int maxTests = testSize / 2;
+    if (maxTests == 0)
+      maxTests = 1;
+    int imageWidth = gifTestImage.getWidth(this);
+    int imageHeight = gifTestImage.getHeight(this);
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - imageWidth + 1));
+        int y = (int) (Math.random() * (size.height - imageHeight + 1));
+        g.drawImage(gifTestImage, x, y, this);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("drawImage " + maxTests + " times", (endTime - startTime));
+  }
+
+  /**
+   * Draws random transparent images within the given dimensions.
+   * 
+   * @param g The Graphics object that is used to paint.
+   * @param size The size of the canvas.
+   */
+  private void test_drawTransparentImage(Graphics2D g, Dimension size)
+  {
+    if (pngTestImage == null)
+      {
+        logger.logp(Level.WARNING, "AicasGraphicsBenchmark", "runTestSet",
+                    "Skipping 'drawTransparentImage' due to missing resource.");
+        return;
+      }
+
+    int maxTests = testSize / 5;
+    if (maxTests == 0)
+      maxTests = 1;
+    int imageWidth = pngTestImage.getWidth(this);
+    int imageHeight = pngTestImage.getHeight(this);
+    long startTime = System.currentTimeMillis();
+    for (int i = 0; i < maxTests; i += 1)
+      {
+        setRandom(g, size);
+        int x = (int) (Math.random() * (size.width - imageWidth + 1));
+        int y = (int) (Math.random() * (size.height - imageHeight + 1));
+        g.drawImage(pngTestImage, x, y, this);
+      }
+    long endTime = System.currentTimeMillis();
+    recordTest("draw transparent image " + maxTests + " times",
+               (endTime - startTime));
+  }
+
+  private class GraphicsTest
+      extends Canvas
+      implements Runnable
+  {
+    Thread paintThread;
+
+    boolean done = false;
+
+    boolean doPaint = false;
+
+    boolean withClipping = false;
+
+    public GraphicsTest()
+    {
+      paintThread = new Thread(this);
+      paintThread.start();
+    }
+
+    public void run()
+    {
+      int runCount = 0;
+      while (! done)
+        {
+          runCount++;
+
+          try
+            {
+              synchronized (this)
+                {
+                  while (! doPaint)
+                    {
+                      try
+                        {
+                          wait(200);
+                        }
+                      catch (InterruptedException exception)
+                        {
+                          return;
+                        }
+                    }
+                }
+
+              // if (iterations != 0)
+              // System.out.println("--- run...("
+              // + runCount
+              // + "/"
+              // + iterations
+              // + ") ------------------------------------------------------");
+
+              Graphics g = getGraphics();
+              Dimension size = getSize();
+
+              if (singleBufferFlag)
+                {
+                  logger.logp(Level.INFO, "J2dGraphicsBenchmark.GraphicsTest",
+                              "run",
+                              "Start testing non-double-buffered drawing");
+
+                  if (noClippingFlag)
+                    runSet_noClipping((Graphics2D) g, size, runCount);
+
+                  if (withClippingFlag)
+                    runSet_withClipping((Graphics2D) g, size, runCount);
+
+                  if (zeroClippingFlag)
+                    runSet_zeroClipping((Graphics2D) g, size, runCount);
+
+                  g.dispose();
+                }
+
+              if (doubleBufferFlag)
+                {
+                  logger.logp(Level.INFO, "J2dGraphicsBenchmark.GraphicsTest",
+                              "run", "Start testing double-buffered drawing");
+                  Graphics canvas = getGraphics();
+                  Image doublebuffer = createImage(size.width, size.height);
+
+                  if (noClippingFlag)
+                    {
+                      g = doublebuffer.getGraphics();
+                      runSet_noClipping((Graphics2D) g, size,
+                                        "double buffering", runCount);
+                      g.dispose();
+                      canvas.drawImage(doublebuffer, 0, 0, this);
+                    }
+
+                  if (withClippingFlag)
+                    {
+                      g = doublebuffer.getGraphics();
+                      runSet_withClipping((Graphics2D) g, size,
+                                          "double buffering", runCount);
+                      g.dispose();
+                      canvas.drawImage(doublebuffer, 0, 0, this);
+                    }
+
+                  if (zeroClippingFlag)
+                    {
+                      g = doublebuffer.getGraphics();
+                      runSet_zeroClipping((Graphics2D) g, size,
+                                          "double buffering", runCount);
+                      g.dispose();
+                      canvas.drawImage(doublebuffer, 0, 0, this);
+                      canvas.dispose();
+                    }
+                }
+
+              printReport();
+
+              if (iterations != 1)
+                {
+                  if (iterations != - 1)
+                    iterations--;
+                }
+              else
+                {
+                  // System.out.println("--- done
+                  // --------------------------------------------------------");
+                  synchronized (this)
+                    {
+                      doPaint = false;
+                    }
+                  done = true;
+                }
+            }
+          catch (Error error)
+            {
+              System.err.println("Error: " + error);
+              System.exit(129);
+            }
+        }
+      testComplete();
+    }
+
+    private void runSet_zeroClipping(Graphics2D g, Dimension size, int runCount)
+    {
+      runSet_zeroClipping(g, size, "", runCount);
+    }
+
+    private void runSet_zeroClipping(Graphics2D g, Dimension size,
+                                     String context, int runCount)
+    {
+      int clipped_width;
+      int clipped_height;
+      int clipped_x;
+      int clipped_y;
+
+      clipped_width = 0;
+      clipped_height = 0;
+      clipped_x = (size.width) / 2;
+      clipped_y = (size.height) / 2;
+
+      // Reset any transforms from past tests
+      resetGraphics(g);
+
+      Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
+      g.setClip(fullWindow);
+      g.setPaint(Color.BLACK);
+      g.fill(fullWindow);
+
+      Rectangle windowBorder = new Rectangle(0, 0, size.width - 1,
+                                             size.width - 1);
+      g.setPaint(Color.WHITE);
+      g.draw(windowBorder);
+
+      Rectangle innerBorder = new Rectangle(clipped_x - 1, clipped_y - 1,
+                                            clipped_width + 2,
+                                            clipped_height + 2);
+      g.fill(innerBorder);
+
+      Rectangle innerBox = new Rectangle(clipped_x, clipped_y, clipped_width,
+                                         clipped_height);
+      g.clip(innerBox);
+      g.setPaint(Color.BLACK);
+      g.fill(fullWindow);
+
+      if (context.equals(""))
+        setTestContext("(" + runCount + ") clipping to zero");
+      else
+        setTestContext("(" + runCount + ") clipping to zero (" + context + ")");
+
+      runTestSet(g, size);
+    }
+
+    private void runSet_withClipping(Graphics2D g, Dimension size, int runCount)
+    {
+      runSet_withClipping(g, size, "", runCount);
+    }
+
+    private void runSet_withClipping(Graphics2D g, Dimension size,
+                                     String context, int runCount)
+    {
+      int clipped_width = 2 * size.width / 3;
+      int clipped_height = 2 * size.height / 3;
+      int clipped_x = (size.width - clipped_width) / 2;
+      int clipped_y = (size.height - clipped_height) / 2;
+
+      // Reset any transforms from past tests
+      resetGraphics(g);
+
+      Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
+      g.setClip(fullWindow);
+
+      g.setPaint(Color.BLACK);
+      g.fill(fullWindow);
+
+      Rectangle windowBorder = new Rectangle(0, 0, size.width - 1,
+                                             size.height - 1);
+      g.setPaint(Color.GREEN);
+      g.draw(windowBorder);
+
+      Rectangle innerBorder = new Rectangle(clipped_x - 1, clipped_y - 1,
+                                            clipped_width + 2,
+                                            clipped_height + 2);
+      g.setPaint(Color.WHITE);
+      g.fill(innerBorder);
+
+      Rectangle innerBox = new Rectangle(clipped_x, clipped_y, clipped_width,
+                                         clipped_height);
+      g.clip(innerBox);
+
+      g.setPaint(Color.BLACK);
+      g.fill(fullWindow);
+
+      if (context.equals(""))
+        setTestContext("(" + runCount + ") with clipping ");
+      else
+        setTestContext("(" + runCount + ") with clipping (" + context + ")");
+
+      runTestSet(g, size);
+    }
+
+    private void runSet_noClipping(Graphics2D g, Dimension size, int runCount)
+    {
+      runSet_noClipping(g, size, "", runCount);
+    }
+
+    private void runSet_noClipping(Graphics2D g, Dimension size,
+                                   String context, int runCount)
+    {
+      // Reset any transforms from past tests
+      resetGraphics(g);
+
+      Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
+      g.setPaint(Color.BLACK);
+      g.fill(fullWindow);
+
+      if (context.equals(""))
+        setTestContext("(" + runCount + ") without clipping");
+      else
+        setTestContext("(" + runCount + ") without clipping (" + context + ")");
+
+      runTestSet(g, size);
+    }
+
+    public void paint(Graphics g)
+    {
+      synchronized (this)
+        {
+          doPaint = true;
+          notify();
+        }
+    }
+  }
+}
+
+class TestContext
+{
+}
+
+class TestSet
+{
+  private Map testsMap = new TreeMap();
+
+  public void putTest(String testName, TestRecorder recoder)
+  {
+    testsMap.put(testName, recoder);
+  }
+
+  public TestRecorder getTest(String testName)
+  {
+    return (TestRecorder) testsMap.get(testName);
+  }
+
+  public Iterator testIterator()
+  {
+    return testsMap.keySet().iterator();
+  }
+}
+
+class TestRecorder
+{
+  String test;
+
+  long totalTime = 0;
+
+  long minTime = Long.MAX_VALUE;
+
+  long maxTime = Long.MIN_VALUE;
+
+  int runCount = 0;
+
+  /**
+   * @return Returns the maxTime.
+   */
+  public final long getMaxTime()
+  {
+    return maxTime;
+  }
+
+  /**
+   * @return Returns the minTime.
+   */
+  public final long getMinTime()
+  {
+    return minTime;
+  }
+
+  /**
+   * @return Returns the test name.
+   */
+  public final String getTestName()
+  {
+    return test;
+  }
+
+  public final long getAverage()
+  {
+    return (totalTime / runCount);
+  }
+
+  public TestRecorder(String testName)
+  {
+    test = testName;
+  }
+
+  public void addRun(long time)
+  {
+    totalTime += time;
+    if (minTime > time)
+      minTime = time;
+    if (maxTime < time)
+      maxTime = time;
+    runCount += 1;
+  }
+}