Package java.awt.geom

Source Code of java.awt.geom.ShapeTestCase$Runner$Point

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package java.awt.geom;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Random;
import java.util.regex.Pattern;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;

import java.awt.Tools;

public abstract class ShapeTestCase extends PathIteratorTestCase {

    final static boolean OUTPUT = System.getProperty("OUTPUT") != null;
   
    final static double SHAPE_DELTA = 0.01;
    final static int RECT_WIDTH = 46;
    final static int RECT_HEIGHT = 34;
    final static int POINT_MIN_COUNT = 10;
    final static int ERROR_MAX_COUNT = 5;
    final static int CHECK_STEP = 8;

    final static Color colorInside = Color.lightGray;
    final static Color colorOutside = Color.white;
    final static Color colorShape = Color.gray;
    final static Color colorGrid = new Color(0xA0, 0xA0, 0xA0);

    final static int cInside = colorInside.getRGB();
    final static int cOutside = colorOutside.getRGB();
    final static int cShape = colorShape.getRGB();
    final static int cGrid = colorGrid.getRGB();

    final static Color errorColor = Color.red;
    final static Color successColor = Color.green;

    final static HashMap<String, Integer> arcTypes = new HashMap<String, Integer>();
    static {       
        arcTypes.put("PIE", Arc2D.PIE);
        arcTypes.put("CHORD", Arc2D.CHORD);
        arcTypes.put("OPEN", Arc2D.OPEN);
    }
   
    static String shapePath = null;
    static String outputPath = null;
   
    protected FilenameFilter filterImage, filterShape;

    abstract static class Runner {

        class TextTokenizer {

            StreamTokenizer t;
            String buf;

            TextTokenizer(String text) {
                t = new StreamTokenizer(new StringReader(text));
                buf = text;
            }

            double getDouble() throws IOException {
                while (t.nextToken() != StreamTokenizer.TT_EOF) {
                    if (t.ttype == StreamTokenizer.TT_NUMBER) {
                        return t.nval;
                    }
                }
                throw new IOException("Double not found");
            }

            String getString() throws IOException {
                while (t.nextToken() != StreamTokenizer.TT_EOF) {
                    if (t.ttype == StreamTokenizer.TT_WORD) {
                        return t.sval;
                    }
                }
                throw new IOException("String not found");
            }

            boolean findString(String substr) {
                int pos = buf.indexOf(substr);
                if (pos != -1) {
                    t = new StreamTokenizer(new StringReader(buf.substring(pos + substr.length())));
                }
                return pos != -1;
            }

        }

        abstract static class Rectangle extends Runner {
           
            static String outputPrefix = "undefined";
           
            static class Contains extends Rectangle {
               
                static {
                    outputPrefix = "cr_";
                }
               
                static boolean[] result = new boolean[] {false, false, true, false};
               
                boolean execute(Shape shape, int x, int y, int width, int height, int expected) {
                    return result[expected] == shape.contains(x, y, width, height);
                }
               
            }
           
            static class Intersects extends Rectangle {
               
                static {
                    outputPrefix = "ir_";
                }
               
                static boolean[] result = new boolean[] {false, false, true, true};
               
                boolean execute(Shape shape, int x, int y, int width, int height, int expected) {
                    return result[expected] == shape.intersects(x, y, width, height);
                }
               
            }
           
            int[] prevRect;
            int[] count;
           
            abstract boolean execute(Shape shape, int x, int y, int width, int height, int expected);
           
            public boolean run(String fileName) {
                boolean error = false;
                try {
                    Shape shape = createShape(fileName);
                    BufferedImage img = Tools.BufferedImage.loadIcon(fileName);
                    int buf[][] = createImageBuffer(img);
                    Graphics g = img.getGraphics();
                    g.setColor(errorColor);

                    count = new int[]{0, 0, 0};
                    prevRect = null;

                    for(int x = 0; x < img.getWidth() - RECT_WIDTH; x++)
                        for(int y = 0; y < img.getHeight() - RECT_HEIGHT; y++) {
                            int rectType = getRectType(null, buf, x, y, RECT_WIDTH, RECT_HEIGHT, true);
                            if (rectType == 0) {
                                // Invalid rectangle
                                continue;
                            }
                            if (!execute(shape, x, y, RECT_WIDTH, RECT_HEIGHT, rectType)) {
                                g.drawRect(x, y, RECT_WIDTH, RECT_HEIGHT);
                                error = true;
                            }
                        }

                    int errCount = 0;
                    Random rnd = new Random();
                    for(int i = 0; i < 1000; i ++) {
                        int rx = (int)(rnd.nextDouble() * (img.getWidth() - RECT_WIDTH));
                        int ry = (int)(rnd.nextDouble() * (img.getHeight() - RECT_HEIGHT));
                        int rw = (int)(rnd.nextDouble() * (img.getWidth() - rx - 1)) + 1;
                        int rh = (int)(rnd.nextDouble() * (img.getHeight() - ry - 1)) + 1;

                        int rectType = getRectType(img, buf, rx, ry, rw, rh, false);
                        if (rectType == 0) {
                            // Invalid rectangle
                            continue;
                        }
                        if (!execute(shape, rx, ry, rw, rh, rectType)) {
                            g.drawRect(rx, ry, rw, rh);
                            error = true;
                            errCount++;
                        }
                        if (errCount > ERROR_MAX_COUNT) {
                            break;
                        }
                    }

                    if (OUTPUT) {
                        Tools.BufferedImage.saveIcon(img, outputPath + outputPrefix + Tools.File.extractFileName(fileName));
                    }
                } catch(Exception e) {
                    e.printStackTrace();
                    fail(e.toString());
                }
                return !error;
            }
           
            int getRectType(BufferedImage img, int buf[][], int rx, int ry, int rw, int rh, boolean usePrev) {

                if ((rx + ry) % 2 == 0) {
                    return 0;
                }

                if (!usePrev) {
                    prevRect = null;
                    count = new int[3];
                }

                int[] newRect = new int[]{rx, ry, rx + rw, ry + rh};
                countRect(buf, prevRect, newRect, count);
                prevRect = newRect;

                if (count[0] > POINT_MIN_COUNT && count[1] == 0 && count[2] == 0) {
                    return 1; // Outside
                }
                if (count[1] > POINT_MIN_COUNT && count[0] == 0 && count[2] == 0) {
                    return 2; // Inside
                }
                if (count[0] > POINT_MIN_COUNT && count[1] > POINT_MIN_COUNT) {
                    return 3; // Both
                }
                return 0; // Invalid rectangle
            }
           
            void countRect(int[][] buf, int[] r1, int[] r2, int[] count) {
                if (r1 != null && (r1[0] > r2[2] || r1[2] < r2[0] || r1[1] > r2[3] || r1[3] < r2[1])) {
                    count[0] = count[1] = count[2] = 0;
                    countRect(buf, null, r2, count);
                    return;
                }

                int x1, y1, x2, y2;
                if (r1 == null) {
                    x1 = r2[0];
                    y1 = r2[1];
                    x2 = r2[2];
                    y2 = r2[3];
                } else {
                    x1 = Math.min(r1[0], r2[0]);
                    y1 = Math.min(r1[1], r2[1]);
                    x2 = Math.max(r1[2], r2[2]);
                    y2 = Math.max(r1[3], r2[3]);
                }
                for(int x = x1; x <= x2; x++)
                    for(int y = y1; y <= y2; y++) {
                        boolean inside1 = r1 != null && r1[0] <= x && x <= r1[2] && r1[1] <= y && y <= r1[3];
                        boolean inside2 = r2 != null && r2[0] <= x && x <= r2[2] && r2[1] <= y && y <= r2[3];

                        if (inside1 ^ inside2) {
                            int index = 3;
                            int color = getColor(buf[x][y]);
                            if (color == colorOutside.getRGB()) {
                                index = 0;
                            } else
                            if (color == colorInside.getRGB()) {
                                index = 1;
                            } else
                            if (color == colorShape.getRGB()) {
                                index = 2;
                            }
                            if (inside1) {
                                count[index]--;
                            } else {
                                count[index]++;
                            }
                        }
                    }
            }
           
        }
       
        static class Point extends Runner {

            public boolean run(String fileName) {
                boolean error = false;
                Shape shape = createShape(fileName);
                BufferedImage img = Tools.BufferedImage.loadIcon(fileName);
                for(int x = 0; x < img.getWidth(); x++)
                    for(int y = 0; y < img.getHeight(); y++) {
                        int color = getColor(img.getRGB(x, y));
                        boolean res = shape.contains(x, y);
                        if ((color == colorInside.getRGB() && !res) ||
                            (color == colorOutside.getRGB() && res))
                        {
                            img.setRGB(x, y, errorColor.getRGB());
                            error = true;
                        }
                    }
                if (OUTPUT) {
                    Tools.BufferedImage.saveIcon(img, outputPath + "cp_" + Tools.File.extractFileName(fileName));
                }
                return !error;
            }
           
        }
       
        static class PathIterator extends Runner {

            public boolean run(String fileName) {
                double flatness = getFlatness(fileName);
                AffineTransform at = createTransform(fileName);
                Shape shape1 = createShape(fileName);
                Shape shape2 = Tools.Shape.load(fileName);
                GeneralPath path = new GeneralPath();
                path.append(flatness < 0.0 ? shape1.getPathIterator(at) : shape1.getPathIterator(at, flatness), false);
                if (OUTPUT) {
                    Tools.Shape.save(path, outputPath + (at == null ? "pi_" : "pia_") + Tools.File.extractFileName(fileName));
                }
                return Tools.PathIterator.equals(
                        path.getPathIterator(null),
                        shape2.getPathIterator(null),
                        SHAPE_DELTA);
            }
           
            double getFlatness(String fileName) {
                try {
                    TextTokenizer t = new TextTokenizer(Tools.File.extractFileName(fileName));
                    if (t.findString("flat(")) {
                        return t.getDouble();
                    }
                } catch(IOException e) {
                    fail("Can't read flatness " + fileName);
                }
                return -1.0;
            }
           
            AffineTransform createTransform(String fileName) {
                AffineTransform at = null;
                try {
                    String fname = Tools.File.extractFileName(fileName);
                    TextTokenizer t = new TextTokenizer(fname);


                    if (t.findString("affine(")) {
        /*
                        String ttype = t.getString();
                        if (ttype.equals("M")) {
                            at.setTransform(AffineTransform.getTranslateInstance(t.getDouble(), t.getDouble()));
                        } else
                        if (ttype.equals("R")) {
                            at.setTransform(AffineTransform.getRotateInstance(t.getDouble()));
                        } else
                        if (ttype.equals("SC")) {
                            at.setTransform(AffineTransform.getScaleInstance(t.getDouble(), t.getDouble()));
                        } else
                        if (ttype.equals("SH")) {
                            at.setTransform(AffineTransform.getShearInstance(t.getDouble(), t.getDouble()));
                        } else
                        if (ttype.equals("F")) {
                            at.setTransform(AffineTransform.getShearInstance(t.getDouble(), t.getDouble()));
                        }
        */
                        at = new AffineTransform(
                                t.getDouble(),
                                t.getDouble(),
                                t.getDouble(),
                                t.getDouble(),
                                t.getDouble(),
                                t.getDouble());
                    }

                } catch (IOException e) {
                    fail("Can't read transform " + fileName);
                }
                return at;
            }

        }
       
        abstract boolean run(String fileName);
       
        Shape createShape(String fileName) {
            Shape shape = null;
            try {
                String fname = Tools.File.extractFileName(fileName);
                TextTokenizer t = new TextTokenizer(fname);
                if (t.findString("rect(")) {
                    shape = new Rectangle2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("ellipse(")) {
                    shape = new Ellipse2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("round(")) {
                    shape = new RoundRectangle2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("arc(")) {
                    shape = new Arc2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            arcTypes.get(t.getString()));
                } else
                if (t.findString("line(")) {
                    shape = new Line2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("quad(")) {
                    shape = new QuadCurve2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("cubic(")) {
                    shape = new CubicCurve2D.Double(
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble(),
                            t.getDouble());
                } else
                if (t.findString("polygon(")) {
                    shape = new Polygon();
                    try {
                        while(true) {
                            ((Polygon)shape).addPoint((int)t.getDouble(), (int)t.getDouble());
                        }
                    } catch(IOException e) {
                    }
                } else {
                    // GeneralPath
                    shape = Tools.Shape.load(Tools.File.changeExt(fileName, ".shape"));
                }

            } catch (IOException e) {
                fail("Can't read shape " + fileName);
            }
            return shape;
        }

        int[][] createImageBuffer(BufferedImage img) {
            int buf[][] = new int[img.getWidth()][img.getHeight()];
            for(int x = 0; x < img.getWidth(); x++)
                for(int y = 0; y < img.getHeight(); y++) {
                    buf[x][y] = img.getRGB(x, y);
                }
            return buf;
        }

        static int getColor(int color) {
            if (color == cInside || color == cOutside || color == cShape) {
                return color;
            }
            int xored = (color ^ cGrid ^ 0xFF808080);
            if (xored == cInside || xored == cOutside || xored == cShape) {
                return xored;
            }
            return color;
        }

    }
   
    public ShapeTestCase(String name) {
        super(name);
        String classPath = "shapes/" + Tools.getClasstPath(this.getClass());
        URL url = ClassLoader.getSystemClassLoader().getResource(classPath);
        assertNotNull("Path not found " + classPath, url);
        shapePath = url.getPath();
        outputPath = shapePath + "output/";
    }

    void print(String text) {
        if (OUTPUT) {
            System.out.println(text);       
        }
    }
   
    public FilenameFilter createFilter(final String include, final String exclude) {
        return new FilenameFilter() {
              public boolean accept(File dir, String name) {
                return
                    (include == null || Pattern.matches(include, name)) &&
                    (exclude == null || !Pattern.matches(exclude, name));
              }
        };
    }

    String [] getTestList(String path, FilenameFilter filter) {
          File folder = new File(path);
          String list[] = folder.list(filter);
          if (list != null) {
              for(int i = 0; i < list.length; i++) {
                list[i] = folder.getAbsolutePath() + File.separator + list[i];
              }
          }
          return list;
    }

    void iterator(String name, FilenameFilter filter, Runner runner) {
        if (filter == null) {
            return; // skip test
        }
        if (OUTPUT) {
            new File(outputPath).mkdirs();
        }
        String tests[] = getTestList(shapePath, filter);
        assertTrue("Shapes not found " + shapePath, tests != null && tests.length > 0);
        for(int i = 0; i < tests.length; i++) {
            boolean result = runner.run(tests[i]);
            assertTrue(tests[i] + " " + Tools.PathIterator.equalsError, result);
        }
    }

    public void testGetPathIterator() {
        iterator(
                "getPathIterator()",
                filterShape,
                new Runner.PathIterator());
    }

    public void testContainsPoint() {
        iterator(
                "contains(double,double)",
                filterImage,
                new Runner.Point());
    }

    public void testContainsRect() {
        iterator(
                "contains(double,double,double,double)",
                filterImage,
                new Runner.Rectangle.Contains());
    }

    public void testIntersectsRect() {
        iterator(
                "intersects(double,double,double,double)",
                filterImage,
                new Runner.Rectangle.Intersects());
    }

}

TOP

Related Classes of java.awt.geom.ShapeTestCase$Runner$Point

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.