alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RenderTests.java)

This example Java source code file (RenderTests.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awt, basicstroke, color, context, cubiccurve2d, draw, ellipse2d, fill, geometry, graphics2d, group, gui, image, num_randomcolormask, option, rendertests, string, swing, util, width

The RenderTests.java Java example source code

/*
 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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 Oracle 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.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */


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);
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java RenderTests.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.