/*
 * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package j2dbench.tests;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.AlphaComposite;
import java.awt.Stroke;
import java.awt.BasicStroke;
import java.awt.GradientPaint;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.swing.JComponent;

import j2dbench.Group;
import j2dbench.Node;
import j2dbench.Option;
import j2dbench.TestEnvironment;

public abstract class RenderTests extends GraphicsTests {
    static Group renderroot;
    static Group renderoptroot;
    static Group rendertestroot;
    static Group rendershaperoot;

    static Option paintList;
    static Option doAntialias;
    static Option doAlphaColors;
    static Option sizeList;
    static Option strokeList;

    static final int NUM_RANDOMCOLORS = 4096;
    static final int NUM_RANDOMCOLORMASK = (NUM_RANDOMCOLORS - 1);
    static Color randAlphaColors[];
    static Color randOpaqueColors[];

    static {
        randOpaqueColors = new Color[NUM_RANDOMCOLORS];
        randAlphaColors = new Color[NUM_RANDOMCOLORS];
        for (int i = 0; i < NUM_RANDOMCOLORS; i++) {
            int r = (int) (Math.random() * 255);
            int g = (int) (Math.random() * 255);
            int b = (int) (Math.random() * 255);
            randOpaqueColors[i] = new Color(r, g, b);
            randAlphaColors[i] = makeAlphaColor(randOpaqueColors[i], 32);
        }
    }

    static boolean hasMultiGradient;

    static {
        try {
            hasMultiGradient = (MultipleGradientPaint.class != null);
        } catch (NoClassDefFoundError e) {
        }
    }

    public static void init() {
        renderroot = new Group(graphicsroot, "render", "Rendering Benchmarks");
        renderoptroot = new Group(renderroot, "opts", "Rendering Options");
        rendertestroot = new Group(renderroot, "tests", "Rendering Tests");

        ArrayList paintStrs = new ArrayList();
        ArrayList paintDescs = new ArrayList();
        paintStrs.add("single");
        paintDescs.add("Single Color");
        paintStrs.add("random");
        paintDescs.add("Random Color");
        if (hasGraphics2D) {
            paintStrs.add("gradient2");
            paintDescs.add("2-color GradientPaint");
            if (hasMultiGradient) {
                paintStrs.add("linear2");
                paintDescs.add("2-color LinearGradientPaint");
                paintStrs.add("linear3");
                paintDescs.add("3-color LinearGradientPaint");
                paintStrs.add("radial2");
                paintDescs.add("2-color RadialGradientPaint");
                paintStrs.add("radial3");
                paintDescs.add("3-color RadialGradientPaint");
            }
            paintStrs.add("texture20");
            paintDescs.add("20x20 TexturePaint");
            paintStrs.add("texture32");
            paintDescs.add("32x32 TexturePaint");
        }
        String[] paintStrArr = new String[paintStrs.size()];
        paintStrArr = (String[])paintStrs.toArray(paintStrArr);
        String[] paintDescArr = new String[paintDescs.size()];
        paintDescArr = (String[])paintDescs.toArray(paintDescArr);
        paintList =
            new Option.ObjectList(renderoptroot,
                                  "paint", "Paint Type",
                                  paintStrArr, paintStrArr,
                                  paintStrArr, paintDescArr,
                                  0x1);
        ((Option.ObjectList) paintList).setNumRows(5);

        // add special RandomColorOpt for backwards compatibility with
        // older options files
        new RandomColorOpt();

        if (hasGraphics2D) {
            doAlphaColors =
                new Option.Toggle(renderoptroot, "alphacolor",
                                  "Set the alpha of the paint to 0.125",
                                  Option.Toggle.Off);
            doAntialias =
                new Option.Toggle(renderoptroot, "antialias",
                                  "Render shapes antialiased",
                                  Option.Toggle.Off);
            String strokeStrings[] = {
                "width0",
                "width1",
                "width5",
                "width20",
                "dash0_5",
                "dash1_5",
                "dash5_20",
                "dash20_50",
            };
            String strokeDescriptions[] = {
                "Solid Thin lines",
                "Solid Width 1 lines",
                "Solid Width 5 lines",
                "Solid Width 20 lines",
                "Dashed Thin lines",
                "Dashed Width 1 lines",
                "Dashed Width 5 lines",
                "Dashed Width 20 lines",
            };
            BasicStroke strokeObjects[] = {
                new BasicStroke(0f),
                new BasicStroke(1f),
                new BasicStroke(5f),
                new BasicStroke(20f),
                new BasicStroke(0f, BasicStroke.CAP_SQUARE,
                                BasicStroke.JOIN_MITER, 10f,
                                new float[] { 5f, 5f }, 0f),
                new BasicStroke(1f, BasicStroke.CAP_SQUARE,
                                BasicStroke.JOIN_MITER, 10f,
                                new float[] { 5f, 5f }, 0f),
                new BasicStroke(5f, BasicStroke.CAP_SQUARE,
                                BasicStroke.JOIN_MITER, 10f,
                                new float[] { 20f, 20f }, 0f),
                new BasicStroke(20f, BasicStroke.CAP_SQUARE,
                                BasicStroke.JOIN_MITER, 10f,
                                new float[] { 50f, 50f }, 0f),
            };
            strokeList =
                new Option.ObjectList(renderoptroot,
                                      "stroke", "Stroke Type",
                                      strokeStrings, strokeObjects,
                                      strokeStrings, strokeDescriptions,
                                      0x2);
            ((Option.ObjectList) strokeList).setNumRows(4);
        }

        new DrawDiagonalLines();
        new DrawHorizontalLines();
        new DrawVerticalLines();
        new FillRects();
        new DrawRects();
        new FillOvals();
        new DrawOvals();
        new FillPolys();
        new DrawPolys();

        if (hasGraphics2D) {
            rendershaperoot = new Group(rendertestroot, "shape",
                                        "Shape Rendering Tests");

            new FillCubics();
            new DrawCubics();
            new FillEllipse2Ds();
            new DrawEllipse2Ds();
        }
    }

    /**
     * This "virtual Node" implementation is here to maintain backward
     * compatibility with older J2DBench releases, specifically those
     * options files that were created before we added the gradient/texture
     * paint options in JDK 6.  This class will translate the color settings
     * from the old "randomcolor" option into the new "paint" option.
     */
    private static class RandomColorOpt extends Node {
        public RandomColorOpt() {
            super(renderoptroot, "randomcolor",
                  "Use random colors for each shape");
        }

        public JComponent getJComponent() {
            return null;
        }

        public void restoreDefault() {
            // no-op
        }

        public void write(PrintWriter pw) {
            // no-op (the random/single choice will be saved as part of
            // the new "paint" option added to J2DBench in JDK 6)
        }

        public String setOption(String key, String value) {
            String opts;
            if (value.equals("On")) {
                opts = "random";
            } else if (value.equals("Off")) {
                opts = "single";
            } else if (value.equals("Both")) {
                opts = "random,single";
            } else {
                return "Bad value";
            }
            return ((Option.ObjectList)paintList).setValueFromString(opts);
        }
    }

    public static class Context extends GraphicsTests.Context {
        int colorindex;
        Color colorlist[];
    }

    public RenderTests(Group parent, String nodeName, String description) {
        super(parent, nodeName, description);
        addDependencies(renderoptroot, true);
    }

    public GraphicsTests.Context createContext() {
        return new RenderTests.Context();
    }

    public void initContext(TestEnvironment env, GraphicsTests.Context ctx) {
        super.initContext(env, ctx);
        RenderTests.Context rctx = (RenderTests.Context) ctx;
        boolean alphacolor;

        if (hasGraphics2D) {
            Graphics2D g2d = (Graphics2D) rctx.graphics;
            if (env.isEnabled(doAntialias)) {
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                     RenderingHints.VALUE_ANTIALIAS_ON);
            }
            alphacolor = env.isEnabled(doAlphaColors);
            g2d.setStroke((Stroke) env.getModifier(strokeList));
        } else {
            alphacolor = false;
        }

        String paint = (String)env.getModifier(paintList);
        if (paint.equals("single")) {
            Color c = Color.darkGray;
            if (alphacolor) {
                c = makeAlphaColor(c, 32);
            }
            rctx.graphics.setColor(c);
        } else if (paint.equals("random")) {
            rctx.colorlist = alphacolor ? randAlphaColors : randOpaqueColors;
        } else if (paint.equals("gradient2")) {
            Color[] colors = makeGradientColors(2, alphacolor);
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(new GradientPaint(0.0f, 0.0f, colors[0],
                                           10.0f, 10.0f, colors[1], true));
        } else if (paint.equals("linear2")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeLinear(2, alphacolor));
        } else if (paint.equals("linear3")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeLinear(3, alphacolor));
        } else if (paint.equals("radial2")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeRadial(2, alphacolor));
        } else if (paint.equals("radial3")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeRadial(3, alphacolor));
        } else if (paint.equals("texture20")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeTexturePaint(20, alphacolor));
        } else if (paint.equals("texture32")) {
            Graphics2D g2d = (Graphics2D)rctx.graphics;
            g2d.setPaint(makeTexturePaint(32, alphacolor));
        } else {
            throw new InternalError("Invalid paint mode");
        }
    }

    private Color[] makeGradientColors(int numColors, boolean alpha) {
        Color[] colors = new Color[] {Color.red, Color.blue,
                                      Color.green, Color.yellow};
        Color[] ret = new Color[numColors];
        for (int i = 0; i < numColors; i++) {
            ret[i] = alpha ? makeAlphaColor(colors[i], 32) : colors[i];
        }
        return ret;
    }

    private LinearGradientPaint makeLinear(int numColors, boolean alpha) {
        float interval = 1.0f / (numColors - 1);
        float[] fractions = new float[numColors];
        for (int i = 0; i < fractions.length; i++) {
            fractions[i] = i * interval;
        }
        Color[] colors = makeGradientColors(numColors, alpha);
        return new LinearGradientPaint(0.0f, 0.0f,
                                       10.0f, 10.0f,
                                       fractions, colors,
                                       CycleMethod.REFLECT);
    }

    private RadialGradientPaint makeRadial(int numColors, boolean alpha) {
        float interval = 1.0f / (numColors - 1);
        float[] fractions = new float[numColors];
        for (int i = 0; i < fractions.length; i++) {
            fractions[i] = i * interval;
        }
        Color[] colors = makeGradientColors(numColors, alpha);
        return new RadialGradientPaint(0.0f, 0.0f, 10.0f,
                                       fractions, colors,
                                       CycleMethod.REFLECT);
    }

    private TexturePaint makeTexturePaint(int size, boolean alpha) {
        int s2 = size / 2;
        int type =
            alpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
        BufferedImage img = new BufferedImage(size, size, type);
        Color[] colors = makeGradientColors(4, alpha);
        Graphics2D g2d = img.createGraphics();
        g2d.setComposite(AlphaComposite.Src);
        g2d.setColor(colors[0]);
        g2d.fillRect(0, 0, s2, s2);
        g2d.setColor(colors[1]);
        g2d.fillRect(s2, 0, s2, s2);
        g2d.setColor(colors[3]);
        g2d.fillRect(0, s2, s2, s2);
        g2d.setColor(colors[2]);
        g2d.fillRect(s2, s2, s2, s2);
        g2d.dispose();
        Rectangle2D bounds = new Rectangle2D.Float(0, 0, size, size);
        return new TexturePaint(img, bounds);
    }

    public static class DrawDiagonalLines extends RenderTests {
        public DrawDiagonalLines() {
            super(rendertestroot, "drawLine", "Draw Diagonal Lines");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            return Math.max(ctx.outdim.width, ctx.outdim.height);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x + size, y + size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x + size, y + size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class DrawHorizontalLines extends RenderTests {
        public DrawHorizontalLines() {
            super(rendertestroot, "drawLineHoriz",
                  "Draw Horizontal Lines");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            return ctx.outdim.width;
        }

        public Dimension getOutputSize(int w, int h) {
            return new Dimension(w, 1);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x + size, y);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x + size, y);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class DrawVerticalLines extends RenderTests {
        public DrawVerticalLines() {
            super(rendertestroot, "drawLineVert",
                  "Draw Vertical Lines");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            return ctx.outdim.height;
        }

        public Dimension getOutputSize(int w, int h) {
            return new Dimension(1, h);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x, y + size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawLine(x, y, x, y + size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class FillRects extends RenderTests {
        public FillRects() {
            super(rendertestroot, "fillRect", "Fill Rectangles");
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.fillRect(x, y, size, size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.fillRect(x, y, size, size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class DrawRects extends RenderTests {
        public DrawRects() {
            super(rendertestroot, "drawRect", "Draw Rectangles");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            int w = ctx.outdim.width;
            int h = ctx.outdim.height;
            if (w < 2 || h < 2) {
                // If one dimension is less than 2 then there is no
                // gap in the middle, so we get a solid filled rectangle.
                return w * h;
            }
            return (w * 2) + ((h - 2) * 2);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawRect(x, y, size, size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawRect(x, y, size, size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class FillOvals extends RenderTests {
        public FillOvals() {
            super(rendertestroot, "fillOval", "Fill Ellipses");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            // Approximated
            double xaxis = ctx.outdim.width / 2.0;
            double yaxis = ctx.outdim.height / 2.0;
            return (int) (xaxis * yaxis * Math.PI);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.fillOval(x, y, size, size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.fillOval(x, y, size, size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class DrawOvals extends RenderTests {
        public DrawOvals() {
            super(rendertestroot, "drawOval", "Draw Ellipses");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            /*
             * Approximation: We figured that the vertical chord connecting
             * the +45 deg and -45 deg points on the ellipse is about
             * height/sqrt(2) pixels long.  Likewise, the horizontal chord
             * connecting the +45 deg and +135 deg points on the ellipse is
             * about width/sqrt(2) pixels long.  Each of these chords has
             * a parallel on the opposite side of the respective axis (there
             * are two horizontal chords and two vertical chords).  Altogether
             * this gives a reasonable approximation of the total number of
             * pixels touched by the ellipse, so we have:
             *     2*(w/sqrt(2)) + 2*(h/sqrt(2))
             *  == (2/sqrt(2))*(w+h)
             *  == (sqrt(2))*(w+h)
             */
            return (int)(Math.sqrt(2.0)*(ctx.outdim.width+ctx.outdim.height));
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            if (rctx.animate) {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawOval(x, y, size, size);
                    if ((x -= 3) < 0) x += rctx.maxX;
                    if ((y -= 1) < 0) y += rctx.maxY;
                } while (--numReps > 0);
            } else {
                do {
                    if (rCArray != null) {
                        g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                    }
                    g.drawOval(x, y, size, size);
                } while (--numReps > 0);
            }
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class FillPolys extends RenderTests {
        public FillPolys() {
            super(rendertestroot, "fillPoly", "Fill Hexagonal Polygons");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            /*
             * The polygon is a hexagon inscribed inside the square but
             * missing a triangle at each of the four corners of size
             * (w/4) by (h/2).
             *
             * Putting 2 of these triangles together gives a rectangle
             * of size (w/4) by (h/2).
             *
             * Putting 2 of these rectangles together gives a total
             * missing rectangle size of (w/2) by (h/2).
             *
             * Thus, exactly one quarter of the whole square is not
             * touched by the filled polygon.
             */
            int size = ctx.outdim.width * ctx.outdim.height;
            return size - (size / 4);
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            int size = rctx.size;
            int x = rctx.initX;
            int y = rctx.initY;
            int hexaX[] = new int[6];
            int hexaY[] = new int[6];
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            do {
                hexaX[0] = x;
                hexaX[1] = hexaX[5] = x+size/4;
                hexaX[2] = hexaX[4] = x+size-size/4;
                hexaX[3] = x+size;
                hexaY[1] = hexaY[2] = y;
                hexaY[0] = hexaY[3] = y+size/2;
                hexaY[4] = hexaY[5] = y+size;

                if (rCArray != null) {
                    g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                g.fillPolygon(hexaX, hexaY, 6);
                if ((x -= 3) < 0) x += rctx.maxX;
                if ((y -= 1) < 0) y += rctx.maxY;
            } while (--numReps > 0);
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class DrawPolys extends RenderTests {
        public DrawPolys() {
            super(rendertestroot, "drawPoly", "Draw Hexagonal Polygons");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            /*
             * The two horizontal segments have exactly two pixels per column.
             * Since the diagonals are more vertical than horizontal, using
             * h*2 would be a good way to count the pixels in those sections.
             * We then have to figure out the size of the remainder of the
             * horizontal lines at top and bottom to get the answer:
             *
             *     (diagonals less endpoints)*2 + (horizontals)*2
             *
             *  or:
             *
             *     (h-2)*2 + ((x+w-1-w/4)-(x+w/4)+1)*2
             *
             *  since (w == h == size), we then have:
             *
             *     (size - size/4 - 1) * 4
             */
            int size = ctx.size;
            if (size <= 1) {
                return 1;
            } else {
                return (size - (size / 4) - 1) * 4;
            }
        }

        public void runTest(Object ctx, int numReps) {
            RenderTests.Context rctx = (RenderTests.Context) ctx;
            // subtract 1 to account for the fact that lines are drawn to
            // and including the final coordinate...
            int size = rctx.size - 1;
            int x = rctx.initX;
            int y = rctx.initY;
            int hexaX[] = new int[6];
            int hexaY[] = new int[6];
            Graphics g = rctx.graphics;
            g.translate(rctx.orgX, rctx.orgY);
            Color rCArray[] = rctx.colorlist;
            int ci = rctx.colorindex;
            do {
                hexaX[0] = x;
                hexaX[1] = hexaX[5] = x+size/4;
                hexaX[2] = hexaX[4] = x+size-size/4;
                hexaX[3] = x+size;
                hexaY[1] = hexaY[2] = y;
                hexaY[0] = hexaY[3] = y+size/2;
                hexaY[4] = hexaY[5] = y+size;

                if (rCArray != null) {
                    g.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                g.drawPolygon(hexaX, hexaY, 6);
                if ((x -= 3) < 0) x += rctx.maxX;
                if ((y -= 1) < 0) y += rctx.maxY;
            } while (--numReps > 0);
            rctx.colorindex = ci;
            g.translate(-rctx.orgX, -rctx.orgY);
        }
    }

    public static class FillCubics extends RenderTests {
        static final double relTmax = .5 - Math.sqrt(3) / 6;
        static final double relYmax = ((6*relTmax - 9)*relTmax + 3)*relTmax;

        public FillCubics() {
            super(rendershaperoot, "fillCubic", "Fill Bezier Curves");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            /*
             * The cubic only touches 2 quadrants in the square, thus
             * at least half of the square is unfilled.  The integrals
             * to figure out the exact area are not trivial so for the
             * other 2 quadrants, I'm going to guess that the cubic only
             * encloses somewhere between 1/2 and 3/4ths of the pixels
             * in those quadrants - we will say 5/8ths.  Thus only
             * 5/16ths of the total square is filled.
             */
            // Note: 2x2 ends up hitting exactly 1 pixel...
            int size = ctx.size;
            if (size < 2) size = 2;
            return size * size * 5 / 16;
        }

        public static class Context extends RenderTests.Context {
            CubicCurve2D curve = new CubicCurve2D.Float();
        }

        public GraphicsTests.Context createContext() {
            return new FillCubics.Context();
        }

        public void runTest(Object ctx, int numReps) {
            FillCubics.Context cctx = (FillCubics.Context) ctx;
            int size = cctx.size;
            // Note: 2x2 ends up hitting exactly 1 pixel...
            if (size < 2) size = 2;
            int x = cctx.initX;
            int y = cctx.initY;
            int cpoffset = (int) (size/relYmax/2);
            CubicCurve2D curve = cctx.curve;
            Graphics2D g2d = (Graphics2D) cctx.graphics;
            g2d.translate(cctx.orgX, cctx.orgY);
            Color rCArray[] = cctx.colorlist;
            int ci = cctx.colorindex;
            do {
                curve.setCurve(x, y+size/2.0,
                               x+size/2.0, y+size/2.0-cpoffset,
                               x+size/2.0, y+size/2.0+cpoffset,
                               x+size, y+size/2.0);

                if (rCArray != null) {
                    g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                g2d.fill(curve);
                if ((x -= 3) < 0) x += cctx.maxX;
                if ((y -= 1) < 0) y += cctx.maxY;
            } while (--numReps > 0);
            cctx.colorindex = ci;
            g2d.translate(-cctx.orgX, -cctx.orgY);
        }
    }

    public static class DrawCubics extends RenderTests {
        static final double relTmax = .5 - Math.sqrt(3) / 6;
        static final double relYmax = ((6*relTmax - 9)*relTmax + 3)*relTmax;

        public DrawCubics() {
            super(rendershaperoot, "drawCubic", "Draw Bezier Curves");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            // Gross approximation
            int size = ctx.size;
            if (size < 2) size = 2;
            return size;
        }

        public static class Context extends RenderTests.Context {
            CubicCurve2D curve = new CubicCurve2D.Float();
        }

        public GraphicsTests.Context createContext() {
            return new DrawCubics.Context();
        }

        public void runTest(Object ctx, int numReps) {
            DrawCubics.Context cctx = (DrawCubics.Context) ctx;
            int size = cctx.size;
            // Note: 2x2 ends up hitting exactly 1 pixel...
            if (size < 2) size = 2;
            int x = cctx.initX;
            int y = cctx.initY;
            int cpoffset = (int) (size/relYmax/2);
            CubicCurve2D curve = cctx.curve;
            Graphics2D g2d = (Graphics2D) cctx.graphics;
            g2d.translate(cctx.orgX, cctx.orgY);
            Color rCArray[] = cctx.colorlist;
            int ci = cctx.colorindex;
            do {
                curve.setCurve(x, y+size/2.0,
                               x+size/2.0, y+size/2.0-cpoffset,
                               x+size/2.0, y+size/2.0+cpoffset,
                               x+size, y+size/2.0);

                if (rCArray != null) {
                    g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                g2d.draw(curve);
                if ((x -= 3) < 0) x += cctx.maxX;
                if ((y -= 1) < 0) y += cctx.maxY;
            } while (--numReps > 0);
            cctx.colorindex = ci;
            g2d.translate(-cctx.orgX, -cctx.orgY);
        }
    }

    public static class FillEllipse2Ds extends RenderTests {
        public FillEllipse2Ds() {
            super(rendershaperoot, "fillEllipse2D", "Fill Ellipse2Ds");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            // Approximated (copied from FillOvals.pixelsTouched())
            double xaxis = ctx.outdim.width / 2.0;
            double yaxis = ctx.outdim.height / 2.0;
            return (int) (xaxis * yaxis * Math.PI);
        }

        public static class Context extends RenderTests.Context {
            Ellipse2D ellipse = new Ellipse2D.Float();
        }

        public GraphicsTests.Context createContext() {
            return new FillEllipse2Ds.Context();
        }

        public void runTest(Object ctx, int numReps) {
            FillEllipse2Ds.Context cctx = (FillEllipse2Ds.Context) ctx;
            int size = cctx.size;
            int x = cctx.initX;
            int y = cctx.initY;
            Ellipse2D ellipse = cctx.ellipse;
            Graphics2D g2d = (Graphics2D) cctx.graphics;
            g2d.translate(cctx.orgX, cctx.orgY);
            Color rCArray[] = cctx.colorlist;
            int ci = cctx.colorindex;
            do {
                if (rCArray != null) {
                    g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                ellipse.setFrame(x, y, size, size);
                g2d.fill(ellipse);
                if ((x -= 3) < 0) x += cctx.maxX;
                if ((y -= 1) < 0) y += cctx.maxY;
            } while (--numReps > 0);
            cctx.colorindex = ci;
            g2d.translate(-cctx.orgX, -cctx.orgY);
        }
    }

    public static class DrawEllipse2Ds extends RenderTests {
        public DrawEllipse2Ds() {
            super(rendershaperoot, "drawEllipse2D", "Draw Ellipse2Ds");
        }

        public int pixelsTouched(GraphicsTests.Context ctx) {
            // Approximated (copied from DrawOvals.pixelsTouched())
            return (int)(Math.sqrt(2.0)*(ctx.outdim.width+ctx.outdim.height));
        }

        public static class Context extends RenderTests.Context {
            Ellipse2D ellipse = new Ellipse2D.Float();
        }

        public GraphicsTests.Context createContext() {
            return new DrawEllipse2Ds.Context();
        }

        public void runTest(Object ctx, int numReps) {
            DrawEllipse2Ds.Context cctx = (DrawEllipse2Ds.Context) ctx;
            int size = cctx.size;
            int x = cctx.initX;
            int y = cctx.initY;
            Ellipse2D ellipse = cctx.ellipse;
            Graphics2D g2d = (Graphics2D) cctx.graphics;
            g2d.translate(cctx.orgX, cctx.orgY);
            Color rCArray[] = cctx.colorlist;
            int ci = cctx.colorindex;
            do {
                if (rCArray != null) {
                    g2d.setColor(rCArray[ci++ & NUM_RANDOMCOLORMASK]);
                }
                ellipse.setFrame(x, y, size, size);
                g2d.draw(ellipse);
                if ((x -= 3) < 0) x += cctx.maxX;
                if ((y -= 1) < 0) y += cctx.maxY;
            } while (--numReps > 0);
            cctx.colorindex = ci;
            g2d.translate(-cctx.orgX, -cctx.orgY);
        }
    }
}
