You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/10/25 21:01:49 UTC

svn commit: r1402274 [6/31] - in /incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext: ./ awt/ awt/color/ awt/font/ awt/g2d/ awt/geom/ awt/image/ awt/image/codec/ awt/image/codec/jpeg/ awt/image/codec/pn...

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedGeneralPath.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedGeneralPath.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedGeneralPath.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedGeneralPath.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,737 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * The <code>ExtendedGeneralPath</code> class represents a geometric
+ * path constructed from straight lines, quadratic and cubic (Bezier)
+ * curves and elliptical arc. This class delegates lines and curves to
+ * an enclosed <code>GeneralPath</code>. Elliptical arc is implemented
+ * using an <code>Arc2D</code> in float precision.
+ *
+ * <p><b>Warning</b> : An elliptical arc may be composed of several
+ * path segments. For futher details, see the SVG Appendix&nbsp;F.6
+ *
+ * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
+ * @version $Id: ExtendedGeneralPath.java 594018 2007-11-12 04:17:41Z cam $
+ */
+public class ExtendedGeneralPath implements ExtendedShape, Cloneable {
+
+    /** The enclosed general path. */
+    protected GeneralPath path;
+
+    int      numVals = 0;
+    int      numSeg  = 0;
+    float [] values  = null;
+    int   [] types   = null;
+
+    float    mx, my, cx, cy;
+
+   /**
+     * Constructs a new <code>ExtendedGeneralPath</code>.
+     */
+    public ExtendedGeneralPath() {
+        path = new GeneralPath();
+    }
+
+    /**
+     * Constructs a new <code>ExtendedGeneralPath</code> with the
+     * specified winding rule to control operations that require the
+     * interior of the path to be defined.
+     */
+    public ExtendedGeneralPath(int rule) {
+        path = new GeneralPath(rule);
+    }
+
+    /**
+     * Constructs a new <code>ExtendedGeneralPath</code> object with
+     * the specified winding rule and the specified initial capacity
+     * to store path coordinates.
+     */
+    public ExtendedGeneralPath(int rule, int initialCapacity) {
+        path = new GeneralPath(rule, initialCapacity);
+    }
+
+    /**
+     * Constructs a new <code>ExtendedGeneralPath</code> object from
+     * an arbitrary <code>Shape</code> object.
+     */
+    public ExtendedGeneralPath(Shape s) {
+        this();
+        append(s, false);
+    }
+
+    /**
+     * Adds an elliptical arc, defined by two radii, an angle from the
+     * x-axis, a flag to choose the large arc or not, a flag to
+     * indicate if we increase or decrease the angles and the final
+     * point of the arc.
+     *
+     * @param rx the x radius of the ellipse
+     * @param ry the y radius of the ellipse
+     *
+     * @param angle the angle from the x-axis of the current
+     * coordinate system to the x-axis of the ellipse in degrees.
+     *
+     * @param largeArcFlag the large arc flag. If true the arc
+     * spanning less than or equal to 180 degrees is chosen, otherwise
+     * the arc spanning greater than 180 degrees is chosen
+     *
+     * @param sweepFlag the sweep flag. If true the line joining
+     * center to arc sweeps through decreasing angles otherwise it
+     * sweeps through increasing angles
+     *
+     * @param x the absolute x coordinate of the final point of the arc.
+     * @param y the absolute y coordinate of the final point of the arc.
+     */
+    public synchronized void arcTo(float rx, float ry,
+                                   float angle,
+                                   boolean largeArcFlag,
+                                   boolean sweepFlag,
+                                   float x, float y) {
+
+        // Ensure radii are valid
+        if (rx == 0 || ry == 0) {
+            lineTo(x, y);
+            return;
+        }
+
+        checkMoveTo();  // check if prev command was moveto
+
+        // Get the current (x, y) coordinates of the path
+        double x0 = cx;
+        double y0 = cy;
+        if (x0 == x && y0 == y) {
+            // If the endpoints (x, y) and (x0, y0) are identical, then this
+            // is equivalent to omitting the elliptical arc segment entirely.
+            return;
+        }
+
+        Arc2D arc = computeArc(x0, y0, rx, ry, angle,
+                               largeArcFlag, sweepFlag, x, y);
+        if (arc == null) return;
+
+        AffineTransform t = AffineTransform.getRotateInstance
+            (Math.toRadians(angle), arc.getCenterX(), arc.getCenterY());
+        Shape s = t.createTransformedShape(arc);
+        path.append(s, true);
+
+        makeRoom(7);
+        types [numSeg++]  = ExtendedPathIterator.SEG_ARCTO;
+        values[numVals++] = rx;
+        values[numVals++] = ry;
+        values[numVals++] = angle;
+        values[numVals++] = largeArcFlag?1:0;
+        values[numVals++] = sweepFlag?1:0;
+        cx = values[numVals++] = x;
+        cy = values[numVals++] = y;
+    }
+
+
+    /**
+     * This constructs an unrotated Arc2D from the SVG specification of an
+     * Elliptical arc.  To get the final arc you need to apply a rotation
+     * transform such as:
+     *
+     * AffineTransform.getRotateInstance
+     *     (angle, arc.getX()+arc.getWidth()/2, arc.getY()+arc.getHeight()/2);
+     */
+    public static Arc2D computeArc(double x0, double y0,
+                                   double rx, double ry,
+                                   double angle,
+                                   boolean largeArcFlag,
+                                   boolean sweepFlag,
+                                   double x, double y) {
+        //
+        // Elliptical arc implementation based on the SVG specification notes
+        //
+
+        // Compute the half distance between the current and the final point
+        double dx2 = (x0 - x) / 2.0;
+        double dy2 = (y0 - y) / 2.0;
+        // Convert angle from degrees to radians
+        angle = Math.toRadians(angle % 360.0);
+        double cosAngle = Math.cos(angle);
+        double sinAngle = Math.sin(angle);
+
+        //
+        // Step 1 : Compute (x1, y1)
+        //
+        double x1 = (cosAngle * dx2 + sinAngle * dy2);
+        double y1 = (-sinAngle * dx2 + cosAngle * dy2);
+        // Ensure radii are large enough
+        rx = Math.abs(rx);
+        ry = Math.abs(ry);
+        double Prx = rx * rx;
+        double Pry = ry * ry;
+        double Px1 = x1 * x1;
+        double Py1 = y1 * y1;
+        // check that radii are large enough
+        double radiiCheck = Px1/Prx + Py1/Pry;
+        if (radiiCheck > 1) {
+            rx = Math.sqrt(radiiCheck) * rx;
+            ry = Math.sqrt(radiiCheck) * ry;
+            Prx = rx * rx;
+            Pry = ry * ry;
+        }
+
+        //
+        // Step 2 : Compute (cx1, cy1)
+        //
+        double sign = (largeArcFlag == sweepFlag) ? -1 : 1;
+        double sq = ((Prx*Pry)-(Prx*Py1)-(Pry*Px1)) / ((Prx*Py1)+(Pry*Px1));
+        sq = (sq < 0) ? 0 : sq;
+        double coef = (sign * Math.sqrt(sq));
+        double cx1 = coef * ((rx * y1) / ry);
+        double cy1 = coef * -((ry * x1) / rx);
+
+        //
+        // Step 3 : Compute (cx, cy) from (cx1, cy1)
+        //
+        double sx2 = (x0 + x) / 2.0;
+        double sy2 = (y0 + y) / 2.0;
+        double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
+        double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);
+
+        //
+        // Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
+        //
+        double ux = (x1 - cx1) / rx;
+        double uy = (y1 - cy1) / ry;
+        double vx = (-x1 - cx1) / rx;
+        double vy = (-y1 - cy1) / ry;
+        double p, n;
+        // Compute the angle start
+        n = Math.sqrt((ux * ux) + (uy * uy));
+        p = ux; // (1 * ux) + (0 * uy)
+        sign = (uy < 0) ? -1.0 : 1.0;
+        double angleStart = Math.toDegrees(sign * Math.acos(p / n));
+
+        // Compute the angle extent
+        n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
+        p = ux * vx + uy * vy;
+        sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
+        double angleExtent = Math.toDegrees(sign * Math.acos(p / n));
+        if(!sweepFlag && angleExtent > 0) {
+            angleExtent -= 360f;
+        } else if (sweepFlag && angleExtent < 0) {
+            angleExtent += 360f;
+        }
+        angleExtent %= 360f;
+        angleStart %= 360f;
+
+        //
+        // We can now build the resulting Arc2D in double precision
+        //
+        Arc2D.Double arc = new Arc2D.Double();
+        arc.x = cx - rx;
+        arc.y = cy - ry;
+        arc.width = rx * 2.0;
+        arc.height = ry * 2.0;
+        arc.start = -angleStart;
+        arc.extent = -angleExtent;
+
+        return arc;
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void moveTo(float x, float y) {
+        // Don't add moveto to general path unless there is a reason.
+        makeRoom(2);
+        types [numSeg++]  = PathIterator.SEG_MOVETO;
+        cx = mx = values[numVals++] = x;
+        cy = my = values[numVals++] = y;
+
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void lineTo(float x, float y) {
+        checkMoveTo();  // check if prev command was moveto
+        path.lineTo(x, y);
+
+        makeRoom(2);
+        types [numSeg++]  = PathIterator.SEG_LINETO;
+        cx = values[numVals++] = x;
+        cy = values[numVals++] = y;
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void quadTo(float x1, float y1, float x2, float y2) {
+        checkMoveTo();  // check if prev command was moveto
+        path.quadTo(x1, y1, x2, y2);
+
+        makeRoom(4);
+        types [numSeg++]  = PathIterator.SEG_QUADTO;
+        values[numVals++] = x1;
+        values[numVals++] = y1;
+        cx = values[numVals++] = x2;
+        cy = values[numVals++] = y2;
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void curveTo(float x1, float y1,
+                                     float x2, float y2,
+                                     float x3, float y3) {
+        checkMoveTo();   // check if prev command was moveto
+        path.curveTo(x1, y1, x2, y2, x3, y3);
+
+        makeRoom(6);
+        types [numSeg++]  = PathIterator.SEG_CUBICTO;
+        values[numVals++] = x1;
+        values[numVals++] = y1;
+        values[numVals++] = x2;
+        values[numVals++] = y2;
+        cx = values[numVals++] = x3;
+        cy = values[numVals++] = y3;
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void closePath() {
+        // Don't double close path.
+        if ((numSeg != 0) && (types[numSeg-1] == PathIterator.SEG_CLOSE))
+            return;
+
+        // Only close path if the previous command wasn't a moveto
+        if ((numSeg != 0) && (types[numSeg-1] != PathIterator.SEG_MOVETO))
+            path.closePath();
+
+        makeRoom(0);
+        types [numSeg++]  = PathIterator.SEG_CLOSE;
+        cx = mx;
+        cy = my;
+    }
+
+    /**
+     * Checks if previous command was a moveto command,
+     * skipping a close command (if present).
+     */
+    protected void checkMoveTo() {
+        if (numSeg == 0) return;
+
+        switch(types[numSeg-1]) {
+
+        case PathIterator.SEG_MOVETO:
+            path.moveTo(values[numVals-2], values[numVals-1]);
+            break;
+
+        case PathIterator.SEG_CLOSE:
+            if (numSeg == 1) return;
+            if (types[numSeg-2] == PathIterator.SEG_MOVETO)
+                path.moveTo(values[numVals-2], values[numVals-1]);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public void append(Shape s, boolean connect) {
+        append(s.getPathIterator(new AffineTransform()), connect);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public void append(PathIterator pi, boolean connect) {
+        double [] vals = new double[6];
+
+        while (!pi.isDone()) {
+            Arrays.fill( vals, 0 );
+            int type = pi.currentSegment(vals);
+            pi.next();
+            if (connect && (numVals != 0)) {
+                if (type == PathIterator.SEG_MOVETO) {
+                    double x = vals[0];
+                    double y = vals[1];
+                    if ((x != cx) ||
+                        (y != cy)) {
+                        // Change MOVETO to LINETO.
+                        type = PathIterator.SEG_LINETO;
+                    } else {
+                        // Redundent segment (move to current loc) drop it...
+                        if (pi.isDone()) break; // Nothing interesting
+                        type = pi.currentSegment(vals);
+                        pi.next();
+                    }
+                }
+                connect = false;
+            }
+
+            switch(type) {
+            case PathIterator.SEG_CLOSE:   closePath(); break;
+            case PathIterator.SEG_MOVETO:
+                moveTo ((float)vals[0], (float)vals[1]); break;
+            case PathIterator.SEG_LINETO:
+                lineTo ((float)vals[0], (float)vals[1]); break;
+            case PathIterator.SEG_QUADTO:
+                quadTo ((float)vals[0], (float)vals[1],
+                        (float)vals[2], (float)vals[3]); break;
+            case PathIterator.SEG_CUBICTO:
+                curveTo((float)vals[0], (float)vals[1],
+                        (float)vals[2], (float)vals[3],
+                        (float)vals[4], (float)vals[5]); break;
+            }
+        }
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public void append(ExtendedPathIterator epi, boolean connect) {
+        float[] vals = new float[ 7 ];
+        while (!epi.isDone()) {
+            Arrays.fill( vals, 0 );
+            int type = epi.currentSegment(vals);
+            epi.next();
+            if (connect && (numVals != 0)) {
+                if (type == PathIterator.SEG_MOVETO) {
+                    float x = vals[0];
+                    float y = vals[1];
+                    if ((x != cx) ||
+                        (y != cy)) {
+                        // Change MOVETO to LINETO.
+                        type = PathIterator.SEG_LINETO;
+                    } else {
+                        // Redundant segment (move to current loc) drop it...
+                        if (epi.isDone()) break; // Nothing interesting
+                        type = epi.currentSegment(vals);
+                        epi.next();
+                    }
+                }
+                connect = false;
+            }
+
+            switch(type) {
+            case PathIterator.SEG_CLOSE:   closePath(); break;
+            case PathIterator.SEG_MOVETO:
+                moveTo (vals[0], vals[1]); break;
+            case PathIterator.SEG_LINETO:
+                lineTo (vals[0], vals[1]); break;
+            case PathIterator.SEG_QUADTO:
+                quadTo (vals[0], vals[1],
+                        vals[2], vals[3]); break;
+            case PathIterator.SEG_CUBICTO:
+                curveTo(vals[0], vals[1],
+                        vals[2], vals[3],
+                        vals[4], vals[5]); break;
+            case ExtendedPathIterator.SEG_ARCTO:
+                arcTo  (vals[0], vals[1], vals[2],
+                        (vals[3]!=0), (vals[4]!=0),
+                        vals[5], vals[6]); break;
+            }
+        }
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized int getWindingRule() {
+        return path.getWindingRule();
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public void setWindingRule(int rule) {
+        path.setWindingRule(rule);
+    }
+
+    /**
+     * get the current position or <code>null</code>.
+     */
+    public synchronized Point2D getCurrentPoint() {
+        if (numVals == 0) return null;
+        return new Point2D.Double(cx, cy);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized void reset() {
+        path.reset();
+
+        numSeg = 0;
+        numVals = 0;
+        values = null;
+        types = null;
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public void transform(AffineTransform at) {
+        if (at.getType() != AffineTransform.TYPE_IDENTITY)
+            throw new IllegalArgumentException
+                ("ExtendedGeneralPaths can not be transformed");
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized Shape createTransformedShape(AffineTransform at) {
+        return path.createTransformedShape(at);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized Rectangle getBounds() {
+        return path.getBounds();
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public synchronized Rectangle2D getBounds2D() {
+        return path.getBounds2D();
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean contains(double x, double y) {
+        return path.contains(x, y);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean contains(Point2D p) {
+        return path.contains(p);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean contains(double x, double y, double w, double h) {
+        return path.contains(x, y, w, h);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean contains(Rectangle2D r) {
+        return path.contains(r);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean intersects(double x, double y, double w, double h) {
+        return path.intersects(x, y, w, h);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public boolean intersects(Rectangle2D r) {
+        return path.intersects(r);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public PathIterator getPathIterator(AffineTransform at) {
+        return path.getPathIterator(at);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return path.getPathIterator(at, flatness);
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public ExtendedPathIterator getExtendedPathIterator() {
+        return new EPI();
+    }
+
+    class EPI implements ExtendedPathIterator {
+        int segNum = 0;
+        int valsIdx = 0;
+
+        public int currentSegment() {
+            return types[segNum];
+        }
+
+        public int currentSegment(double[] coords) {
+            int ret = types[segNum];
+            switch (ret) {
+            case SEG_CLOSE: break;
+            case SEG_MOVETO:
+            case SEG_LINETO:
+                coords[0] = values[valsIdx];
+                coords[1] = values[valsIdx+1];
+                break;
+            case SEG_QUADTO:
+                coords[0] = values[valsIdx];
+                coords[1] = values[valsIdx+1];
+                coords[2] = values[valsIdx+2];
+                coords[3] = values[valsIdx+3];
+                break;
+            case SEG_CUBICTO:
+                coords[0] = values[valsIdx];
+                coords[1] = values[valsIdx+1];
+                coords[2] = values[valsIdx+2];
+                coords[3] = values[valsIdx+3];
+                coords[4] = values[valsIdx+4];
+                coords[5] = values[valsIdx+5];
+                break;
+            case SEG_ARCTO:
+                coords[0] = values[valsIdx];
+                coords[1] = values[valsIdx+1];
+                coords[2] = values[valsIdx+2];
+                coords[3] = values[valsIdx+3];
+                coords[4] = values[valsIdx+4];
+                coords[5] = values[valsIdx+5];
+                coords[6] = values[valsIdx+6];
+                break;
+            }
+            // System.out.println("Seg: [" + segNum + "] type: " + ret +
+            //                    " vals: [" + coords[0] + ", " + coords[1] +
+            //                    "]");
+            return ret;
+        }
+
+        public int currentSegment(float[] coords) {
+            int ret = types[segNum];
+            switch (ret) {
+            case SEG_CLOSE: break;
+            case SEG_MOVETO:
+            case SEG_LINETO:
+                coords[0] = values[valsIdx];
+                coords[1] = values[valsIdx+1];
+                break;
+            case SEG_QUADTO:
+                System.arraycopy( values, valsIdx, coords, 0, 4 );
+                break;
+            case SEG_CUBICTO:
+                System.arraycopy( values, valsIdx, coords, 0, 6 );
+                break;
+            case SEG_ARCTO:
+                System.arraycopy( values, valsIdx, coords, 0, 7 );
+                break;
+            }
+            return ret;
+        }
+
+        public int getWindingRule() {
+            return path.getWindingRule();
+        }
+        public boolean isDone() {
+            return segNum == numSeg;
+        }
+        public void next() {
+            int type = types[segNum++];
+            switch (type) {
+            case SEG_CLOSE: break;
+            case SEG_MOVETO:                   // fallthrough is intended
+            case SEG_LINETO: valsIdx+=2; break;
+            case SEG_QUADTO: valsIdx+=4; break;
+            case SEG_CUBICTO:valsIdx+=6; break;
+            case SEG_ARCTO:  valsIdx+=7; break;
+            }
+        }
+    }
+
+    /**
+     * Delegates to the enclosed <code>GeneralPath</code>.
+     */
+    public Object clone() {
+        try {
+            ExtendedGeneralPath result = (ExtendedGeneralPath) super.clone();
+            result.path = (GeneralPath) path.clone();
+
+            if ( values != null ){
+                result.values = new float[values.length];
+                System.arraycopy(values, 0, result.values, 0, values.length);
+            }
+            result.numVals = numVals;
+
+            if ( types != null ){
+                result.types = new int[types.length];
+                System.arraycopy(types, 0, result.types, 0, types.length);
+            }
+            result.numSeg = numSeg;
+
+            return result;
+        } catch (CloneNotSupportedException ex) {}
+        return null;
+    }
+
+    /**
+     * Make sure, that the requested number of slots in vales[] are available.
+     * Must be called even for numValues = 0, because it is also
+     * used for initialization of those arrays.
+     *
+     * @param numValues number of requested coordinates
+     */
+    private void makeRoom(int numValues) {
+        if (values == null) {
+            values = new float[2*numValues];
+            types  = new int[2];
+            numVals = 0;
+            numSeg  = 0;
+            return;
+        }
+
+        int newSize = numVals + numValues;
+        if ( newSize > values.length) {
+            int nlen = values.length*2;
+            if ( nlen < newSize )
+                nlen = newSize;
+
+            float [] nvals = new float[nlen];
+            System.arraycopy(values, 0, nvals, 0, numVals);
+            values = nvals;
+        }
+
+        if (numSeg == types.length) {
+            int [] ntypes = new int[types.length*2];
+            System.arraycopy(types, 0, ntypes, 0, types.length);
+            types = ntypes;
+        }
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedGeneralPath.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedPathIterator.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedPathIterator.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedPathIterator.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedPathIterator.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,113 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.geom.PathIterator;
+
+/**
+ * The <code>ExtendedPathIterator</code> class represents a geometric
+ * path constructed from straight lines, quadratic and cubic (Bezier)
+ * curves and elliptical arcs.  This interface is identical to that of
+ * PathIterator except it can return SEG_ARCTO from currentSegment,
+ * also the array of values passed to currentSegment must be of length
+ * 7 or an error will be thrown.
+ * 
+ * This does not extend PathIterator as it would break the interface
+ * contract for that class.
+ *
+ * @author <a href="mailto:deweese@apache.org">Thomas DeWeese</a>
+ * @version $Id: ExtendedPathIterator.java 475477 2006-11-15 22:44:28Z cam $
+ */
+public interface ExtendedPathIterator {
+
+    /**
+     * The segment type constant that specifies that the preceding
+     * subpath should be closed by appending a line segment back to
+     * the point corresponding to the most recent SEG_MOVETO.
+     */
+    int SEG_CLOSE   = PathIterator.SEG_CLOSE;
+
+    /** 
+     * The segment type constant for a point that specifies the end
+     * point of a line to be drawn from the most recently specified
+     * point.  */
+    int SEG_MOVETO  = PathIterator.SEG_MOVETO;
+
+    /**
+     * The segment type constant for a point that specifies the end
+     * point of a line to be drawn from the most recently specified
+     * point.
+     */
+    int SEG_LINETO  = PathIterator.SEG_LINETO;
+
+    /**
+     * The segment type constant for the pair of points that specify a
+     * quadratic parametric curve to be drawn from the most recently
+     * specified point. The curve is interpolated by solving the
+     * parametric control equation in the range (t=[0..1]) using the
+     * most recently specified (current) point (CP), the first control
+     * point (P1), and the final interpolated control point (P2). 
+     */
+    int SEG_QUADTO  = PathIterator.SEG_QUADTO;
+
+    /**
+     * The segment type constant for the set of 3 points that specify
+     * a cubic parametric curve to be drawn from the most recently
+     * specified point. The curve is interpolated by solving the
+     * parametric control equation in the range (t=[0..1]) using the
+     * most recently specified (current) point (CP), the first control
+     * point (P1), the second control point (P2), and the final
+     * interpolated control point (P3).
+     */
+    int SEG_CUBICTO = PathIterator.SEG_CUBICTO;
+
+    /** The segment type constant for an elliptical arc.  This consists of
+     *  Seven values [rx, ry, angle, largeArcFlag, sweepFlag, x, y].
+     *  rx, ry are the radious of the ellipse.
+     *  angle is angle of the x axis of the ellipse.
+     *  largeArcFlag is zero if the smaller of the two arcs are to be used.
+     *  sweepFlag is zero if the 'left' branch is taken one otherwise.
+     *  x and y are the destination for the ellipse.  */
+    int SEG_ARCTO = 4321;
+
+    /** The winding rule constant for specifying an even-odd rule for
+     * determining the interior of a path. The even-odd rule specifies
+     * that a point lies inside the path if a ray drawn in any
+     * direction from that point to infinity is crossed by path
+     * segments an odd number of times.  
+     */ 
+    int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD; 
+
+    /**
+     * The winding rule constant for specifying a non-zero rule for
+     * determining the interior of a path. The non-zero rule specifies
+     * that a point lies inside the path if a ray drawn in any
+     * direction from that point to infinity is crossed by path
+     * segments a different number of times in the counter-clockwise
+     * direction than the clockwise direction.
+     */
+    int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+    int currentSegment();
+    int currentSegment(double[] coords);
+    int currentSegment(float[] coords);
+    int getWindingRule(); 
+    boolean isDone();
+    void next();
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedPathIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedShape.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedShape.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedShape.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedShape.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,36 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.Shape;
+
+/**
+ * The <code>ExtendedShape</code> class represents a geometric
+ * path constructed from straight lines, quadratic and cubic (Bezier)
+ * curves and elliptical arcs.
+ * @author <a href="mailto:deweese@apache.org">Thomas DeWeese</a>
+ * @version $Id: ExtendedShape.java 478249 2006-11-22 17:29:37Z dvholten $
+ */
+public interface ExtendedShape extends Shape {
+    /**
+     * Get an extended Path iterator that may return SEG_ARCTO commands
+     */
+    ExtendedPathIterator getExtendedPathIterator();
+
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/ExtendedShape.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Linear.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Linear.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Linear.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Linear.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,279 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * A class representing a linear path segment.
+ *
+ * @version $Id: Linear.java 478249 2006-11-22 17:29:37Z dvholten $
+ */
+public class Linear implements Segment {
+    public Point2D.Double p1, p2;
+
+    public Linear() {
+        p1 = new Point2D.Double();
+        p2 = new Point2D.Double();
+    }
+
+    public Linear(double x1, double y1,
+                  double x2, double y2) {
+        p1 = new Point2D.Double(x1, y1);
+        p2 = new Point2D.Double(x2, y2);
+    }
+
+    public Linear(Point2D.Double p1, Point2D.Double p2) {
+        this.p1 = p1;
+        this.p2 = p2;
+    }
+
+    public Object clone() {
+        return new Linear(new Point2D.Double(p1.x, p1.y),
+                          new Point2D.Double(p2.x, p2.y));
+    }
+
+    public Segment reverse() {
+        return new Linear(new Point2D.Double(p2.x, p2.y),
+                          new Point2D.Double(p1.x, p1.y));
+    }
+
+    public double minX() {
+        if (p1.x < p2.x) return p1.x;
+        return p2.x;
+    }
+    public double maxX() {
+        if (p1.x > p2.x) return p1.x;
+        return p2.x;
+    }
+    public double minY() {
+        if (p1.y < p2.y) return p1.y;
+        return p2.y;
+    }
+    public double maxY() {
+        if (p1.y > p2.y) return p2.y;
+        return p1.y;
+    }
+    public Rectangle2D getBounds2D() {
+        double x, y, w, h;
+        if (p1.x < p2.x) {
+            x = p1.x; w = p2.x-p1.x;
+        } else {
+            x = p2.x; w = p1.x-p2.x;
+        }
+        if (p1.y < p2.y) {
+            y = p1.y; h = p2.y-p1.y;
+        } else {
+            y = p2.y; h = p1.y-p2.y;
+        }
+
+        return new Rectangle2D.Double(x, y, w, h);
+    }
+
+    public Point2D.Double evalDt(double t) {
+        double x = (p2.x-p1.x);
+        double y = (p2.y-p1.y);
+        return new Point2D.Double(x, y);
+    }
+    public Point2D.Double eval(double t)   {
+        double x = p1.x + t*(p2.x-p1.x);
+        double y = p1.y + t*(p2.y-p1.y);
+        return new Point2D.Double(x, y);
+    }
+
+    public Segment.SplitResults split(double y) {
+        if ((y == p1.y) || (y == p2.y)) return null;
+        if ((y <= p1.y) && (y <= p2.y)) return null;
+        if ((y >= p1.y) && (y >= p2.y)) return null;
+
+        // This should be checked for numerical stability.  So you
+        // need to ensure that p2.y-p1.y retains enough bits to be
+        // useful.
+        double t = (y-p1.y)/(p2.y-p1.y);
+
+        Segment [] t0 = {getSegment(0,t)};
+        Segment [] t1 = {getSegment(t,1)};
+
+        if (p2.y < y)
+            return new Segment.SplitResults(t0, t1);
+        return new Segment.SplitResults(t1, t0);
+    }
+
+    public Segment getSegment(double t0, double t1) {
+        Point2D.Double np1 = eval(t0);
+        Point2D.Double np2 = eval(t1);
+        return new Linear(np1, np2);
+    }
+    public Segment splitBefore(double t) {
+        return new Linear(p1, eval(t));
+    }
+    public Segment splitAfter(double t) {
+        return new Linear(eval(t), p2);
+    }
+
+    /**
+     * Subdivides this Linear segment into two segments at t = 0.5.
+     * can be done with getSegment but this is more efficent.
+     * @param s0 if non-null contains portion of curve from  0->.5
+     * @param s1 if non-null contains portion of curve from .5->1
+     */
+    public void subdivide(Segment s0, Segment s1) {
+        Linear l0=null, l1=null;
+        if (s0 instanceof Linear) l0 = (Linear)s0;
+        if (s1 instanceof Linear) l1 = (Linear)s1;
+        subdivide(l0, l1);
+    }
+
+    /**
+     * Subdivides this Linear segment into two segments at given t.
+     * @param s0 if non-null contains portion of curve from 0->t.
+     * @param s1 if non-null contains portion of curve from t->1.
+     */
+    public void subdivide(double t, Segment s0, Segment s1) {
+        Linear l0=null, l1=null;
+        if (s0 instanceof Linear) l0 = (Linear)s0;
+        if (s1 instanceof Linear) l1 = (Linear)s1;
+        subdivide(t, l0, l1);
+    }
+
+    /**
+     * Subdivides this Cubic curve into two curves at t = 0.5.
+     * Can be done with getSegment but this is more efficent.
+     * @param l0 if non-null contains portion of curve from  0->.5
+     * @param l1 if non-null contains portion of curve from .5->1
+     */
+    public void subdivide(Linear l0, Linear l1) {
+        if ((l0 == null) && (l1 == null)) return;
+
+        double x = (p1.x+p2.x)*.5;
+        double y = (p1.y+p2.y)*.5;
+
+        if (l0 != null) {
+            l0.p1.x = p1.x;
+            l0.p1.y = p1.y;
+            l0.p2.x = x;
+            l0.p2.y = y;
+        }
+        if (l1 != null) {
+            l1.p1.x = x;
+            l1.p1.y = y;
+            l1.p2.x = p2.x;
+            l1.p2.y = p2.y;
+        }
+    }
+
+    /**
+     * Subdivides this Cubic curve into two curves.
+     * Can be done with getSegment but this is more efficent.
+     * @param t position to split the curve
+     * @param l0 if non-null contains portion of curve from  0->t
+     * @param l1 if non-null contains portion of curve from t->1
+     */
+    public void subdivide(double t, Linear l0, Linear l1) {
+        if ((l0 == null) && (l1 == null)) return;
+
+        double x = p1.x+t*(p2.x-p1.x);
+        double y = p1.y+t*(p2.y-p1.y);
+
+        if (l0 != null) {
+            l0.p1.x = p1.x;
+            l0.p1.y = p1.y;
+            l0.p2.x = x;
+            l0.p2.y = y;
+        }
+        if (l1 != null) {
+            l1.p1.x = x;
+            l1.p1.y = y;
+            l1.p2.x = p2.x;
+            l1.p2.y = p2.y;
+        }
+    }
+
+    public double getLength() {
+        double dx = p2.x-p1.x;
+        double dy = p2.y-p1.y;
+        return Math.sqrt(dx*dx+dy*dy);
+    }
+    public double getLength(double maxErr) {
+        return getLength();
+    }
+
+    public String toString() {
+        return "M" + p1.x + ',' + p1.y +
+                'L' + p2.x + ',' + p2.y;
+    }
+
+    /*
+    public static  boolean epsEq(double a, double b) {
+        final double eps = 0.000001;
+        return (((a + eps) > b) && ((a-eps) < b));
+    }
+
+    public static void sub(Linear orig, Linear curr,
+                           double t, double inc, int lev) {
+        Linear left=new Linear();
+        Linear right=new Linear();
+        curr.subdivide(left, right);
+        Point2D.Double ptl = left.eval(.5);
+        Point2D.Double ptr = right.eval(.5);
+        Point2D.Double pt1  = orig.eval(t-inc);
+        Point2D.Double pt2  = orig.eval(t+inc);
+        int steps = 100;
+        Point2D.Double l, r, o;
+        for (int i=0; i<=steps; i++) {
+            l = left.eval(i/(double)steps);
+            o = orig.eval(t-(2*inc)*(1-i/(double)steps));
+            if (!epsEq(l.x, o.x) || !epsEq(l.y, o.y))
+                System.err.println("Lf Pt: ["  + l.x + "," + l.y +
+                                   "] Orig: [" + o.x + "," + o.y +"]");
+            r = right.eval(i/(double)steps);
+            o = orig.eval(t+(2*inc*i/(double)steps));
+            if (!epsEq(r.x, o.x) || !epsEq(r.y, o.y))
+                System.err.println("Rt Pt: ["  + r.x + "," + r.y +
+                                   "] Orig: [" + o.x + "," + o.y +"]");
+        }
+        if (lev != 0) {
+            sub(orig, left,  t-inc, inc/2, lev-1);
+            sub(orig, right, t+inc, inc/2, lev-1);
+        }
+    }
+
+    public static void eval(Linear l) {
+        System.err.println("Length    : " + l.getLength());
+    }
+
+
+    public static void main(String args[]) {
+        Linear l;
+
+        l = new Linear(0,0,  30,0);
+        sub(l, l, .5, .25, 3);
+        eval(l);
+
+        l = new Linear(0,0,  0,30);
+        sub(l, l, .5, .25, 3);
+        eval(l);
+
+        l = new Linear(0,0,  20,30);
+        sub(l, l, .5, .25, 3);
+        eval(l);
+    }
+    */
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Linear.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/PathLength.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/PathLength.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/PathLength.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/PathLength.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,604 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.FlatteningPathIterator;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Utilitiy class for length calculations of paths.
+ * <p>
+ *   PathLength is a utility class for calculating the length
+ *   of a path, the location of a point at a particular length
+ *   along the path, and the angle of the tangent to the path
+ *   at a given length.
+ * </p>
+ * <p>
+ *   It uses a FlatteningPathIterator to create a flattened version
+ *   of the Path. This means the values returned are not always
+ *   exact (in fact, they rarely are), but in most cases they
+ *   are reasonably accurate.
+ * </p>
+ *
+ * @author <a href="mailto:dean.jackson@cmis.csiro.au">Dean Jackson</a>
+ * @version $Id: PathLength.java 489226 2006-12-21 00:05:36Z cam $
+ */
+public class PathLength {
+
+    /**
+     * The path to use for calculations.
+     */
+    protected Shape path;
+
+    /**
+     * The list of flattened path segments.
+     */
+    protected List segments;
+
+    /**
+     * Array where the index is the index of the original path segment
+     * and the value is the index of the first of the flattened segments
+     * in {@link #segments} that corresponds to that original path segment.
+     */
+    protected int[] segmentIndexes;
+
+    /**
+     * Cached copy of the path length.
+     */
+    protected float pathLength;
+
+    /**
+     * Whether this path been flattened yet.
+     */
+    protected boolean initialised;
+
+    /**
+     * Creates a new PathLength object for the specified {@link Shape}.
+     * @param path The Path (or Shape) to use.
+     */
+    public PathLength(Shape path) {
+        setPath(path);
+    }
+
+    /**
+     * Returns the path to use for calculations.
+     * @return Path used in calculations.
+     */
+    public Shape getPath() {
+        return path;
+    }
+
+    /**
+     * Sets the path to use for calculations.
+     * @param v Path to be used in calculations.
+     */
+    public void setPath(Shape v) {
+        this.path = v;
+        initialised = false;
+    }
+
+    /**
+     * Returns the length of the path used by this PathLength object.
+     * @return The length of the path.
+     */
+    public float lengthOfPath() {
+        if (!initialised) {
+            initialise();
+        }
+        return pathLength;
+    }
+
+    /**
+     * Flattens the path and determines the path length.
+     */
+    protected void initialise() {
+        pathLength = 0f;
+
+        PathIterator pi = path.getPathIterator(new AffineTransform());
+        SingleSegmentPathIterator sspi = new SingleSegmentPathIterator();
+        segments = new ArrayList(20);
+        List indexes = new ArrayList(20);
+        int index = 0;
+        int origIndex = -1;
+        float lastMoveX = 0f;
+        float lastMoveY = 0f;
+        float currentX = 0f;
+        float currentY = 0f;
+        float[] seg = new float[6];
+        int segType;
+
+        segments.add(new PathSegment(PathIterator.SEG_MOVETO, 0f, 0f, 0f,
+                                     origIndex));
+
+        while (!pi.isDone()) {
+            origIndex++;
+            indexes.add(new Integer(index));
+            segType = pi.currentSegment(seg);
+            switch (segType) {
+                case PathIterator.SEG_MOVETO:
+                    segments.add(new PathSegment(segType, seg[0], seg[1],
+                                                 pathLength, origIndex));
+                    currentX = seg[0];
+                    currentY = seg[1];
+                    lastMoveX = currentX;
+                    lastMoveY = currentY;
+                    index++;
+                    pi.next();
+                    break;
+                case PathIterator.SEG_LINETO:
+                    pathLength += Point2D.distance(currentX, currentY, seg[0],
+                                                   seg[1]);
+                    segments.add(new PathSegment(segType, seg[0], seg[1],
+                                                 pathLength, origIndex));
+                    currentX = seg[0];
+                    currentY = seg[1];
+                    index++;
+                    pi.next();
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    pathLength += Point2D.distance(currentX, currentY,
+                                                   lastMoveX, lastMoveY);
+                    segments.add(new PathSegment(PathIterator.SEG_LINETO,
+                                                 lastMoveX, lastMoveY,
+                                                 pathLength, origIndex));
+                    currentX = lastMoveX;
+                    currentY = lastMoveY;
+                    index++;
+                    pi.next();
+                    break;
+                default:
+                    sspi.setPathIterator(pi, currentX, currentY);
+                    FlatteningPathIterator fpi =
+                        new FlatteningPathIterator(sspi, 0.01f);
+                    while (!fpi.isDone()) {
+                        segType = fpi.currentSegment(seg);
+                        if (segType == PathIterator.SEG_LINETO) {
+                            pathLength += Point2D.distance(currentX, currentY,
+                                                           seg[0], seg[1]);
+                            segments.add(new PathSegment(segType, seg[0],
+                                                         seg[1], pathLength,
+                                                         origIndex));
+                            currentX = seg[0];
+                            currentY = seg[1];
+                            index++;
+                        }
+                        fpi.next();
+                    }
+            }
+        }
+        segmentIndexes = new int[indexes.size()];
+        for (int i = 0; i < segmentIndexes.length; i++) {
+            segmentIndexes[i] = ((Integer) indexes.get(i)).intValue();
+        }
+        initialised = true;
+    }
+
+    /**
+     * Returns the number of segments in the path.
+     */
+    public int getNumberOfSegments() {
+        if (!initialised) {
+            initialise();
+        }
+        return segmentIndexes.length;
+    }
+
+    /**
+     * Returns the length at the start of the segment given by the specified
+     * index.
+     */
+    public float getLengthAtSegment(int index) {
+        if (!initialised) {
+            initialise();
+        }
+        if (index <= 0) {
+            return 0;
+        }
+        if (index >= segmentIndexes.length) {
+            return pathLength;
+        }
+        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
+        return seg.getLength();
+    }
+
+    /**
+     * Returns the index of the segment at the given distance along the path.
+     */
+    public int segmentAtLength(float length) {
+        int upperIndex = findUpperIndex(length);
+        if (upperIndex == -1) {
+            // Length is off the end of the path.
+            return -1;
+        }
+
+        if (upperIndex == 0) {
+            // Length was probably zero, so return the upper segment.
+            PathSegment upper = (PathSegment) segments.get(upperIndex);
+            return upper.getIndex();
+        }
+
+        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
+        return lower.getIndex();
+    }
+
+    /**
+     * Returns the point that is the given proportion along the path segment
+     * given by the specified index.
+     */
+    public Point2D pointAtLength(int index, float proportion) {
+        if (!initialised) {
+            initialise();
+        }
+        if (index < 0 || index >= segmentIndexes.length) {
+            return null;
+        }
+        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
+        float start = seg.getLength();
+        float end;
+        if (index == segmentIndexes.length - 1) {
+            end = pathLength;
+        } else {
+            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
+            end = seg.getLength();
+        }
+        return pointAtLength(start + (end - start) * proportion);
+    }
+
+    /**
+     * Returns the point that is at the given length along the path.
+     * @param length The length along the path
+     * @return The point at the given length
+     */
+    public Point2D pointAtLength(float length) {
+        int upperIndex = findUpperIndex(length);
+        if (upperIndex == -1) {
+            // Length is off the end of the path.
+            return null;
+        }
+
+        PathSegment upper = (PathSegment) segments.get(upperIndex);
+
+        if (upperIndex == 0) {
+            // Length was probably zero, so return the upper point.
+            return new Point2D.Float(upper.getX(), upper.getY());
+        }
+
+        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
+
+        // Now work out where along the line would be the length.
+        float offset = length - lower.getLength();
+
+        // Compute the slope.
+        double theta = Math.atan2(upper.getY() - lower.getY(),
+                                  upper.getX() - lower.getX());
+
+        float xPoint = (float) (lower.getX() + offset * Math.cos(theta));
+        float yPoint = (float) (lower.getY() + offset * Math.sin(theta));
+
+        return new Point2D.Float(xPoint, yPoint);
+    }
+
+    /**
+     * Returns the slope of the path at the specified length.
+     * @param index The segment number
+     * @param proportion The proportion along the given segment
+     * @return the angle in radians, in the range [-{@link Math#PI},
+     *         {@link Math#PI}].
+     */
+    public float angleAtLength(int index, float proportion) {
+        if (!initialised) {
+            initialise();
+        }
+        if (index < 0 || index >= segmentIndexes.length) {
+            return 0f;
+        }
+        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
+        float start = seg.getLength();
+        float end;
+        if (index == segmentIndexes.length - 1) {
+            end = pathLength;
+        } else {
+            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
+            end = seg.getLength();
+        }
+        return angleAtLength(start + (end - start) * proportion);
+    }
+
+    /**
+     * Returns the slope of the path at the specified length.
+     * @param length The length along the path
+     * @return the angle in radians, in the range [-{@link Math#PI},
+     *         {@link Math#PI}].
+     */
+    public float angleAtLength(float length) {
+        int upperIndex = findUpperIndex(length);
+        if (upperIndex == -1) {
+            // Length is off the end of the path.
+            return 0f;
+        }
+
+        PathSegment upper = (PathSegment) segments.get(upperIndex);
+
+        if (upperIndex == 0) {
+            // Length was probably zero, so return the angle between the first
+            // and second segments.
+            upperIndex = 1;
+        }
+
+        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
+
+        // Compute the slope.
+        return (float) Math.atan2(upper.getY() - lower.getY(),
+                                  upper.getX() - lower.getX());
+    }
+
+    /**
+     * Returns the index of the path segment that bounds the specified
+     * length along the path.
+     * @param length The length along the path
+     * @return The path segment index, or -1 if there is not such segment
+     */
+    public int findUpperIndex(float length) {
+        if (!initialised) {
+            initialise();
+        }
+
+        if (length < 0 || length > pathLength) {
+            // Length is outside the path, so return -1.
+            return -1;
+        }
+
+        // Find the two segments that are each side of the length.
+        int lb = 0;
+        int ub = segments.size() - 1;
+        while (lb != ub) {
+            int curr = (lb + ub) >> 1;
+            PathSegment ps = (PathSegment) segments.get(curr);
+            if (ps.getLength() >= length) {
+                ub = curr;
+            } else {
+                lb = curr + 1;
+            }
+        }
+        for (;;) {
+            PathSegment ps = (PathSegment) segments.get(ub);
+            if (ps.getSegType() != PathIterator.SEG_MOVETO
+                    || ub == segments.size() - 1) {
+                break;
+            }
+            ub++;
+        }
+
+        int upperIndex = -1;
+        int currentIndex = 0;
+        int numSegments = segments.size();
+        while (upperIndex <= 0 && currentIndex < numSegments) {
+            PathSegment ps = (PathSegment) segments.get(currentIndex);
+            if (ps.getLength() >= length
+                    && ps.getSegType() != PathIterator.SEG_MOVETO) {
+                upperIndex = currentIndex;
+            }
+            currentIndex++;
+        }
+        return upperIndex;
+    }
+
+    /**
+     * A {@link PathIterator} that returns only the next path segment from
+     * another {@link PathIterator}.
+     */
+    protected static class SingleSegmentPathIterator implements PathIterator {
+
+        /**
+         * The path iterator being wrapped.
+         */
+        protected PathIterator it;
+
+        /**
+         * Whether the single segment has been passed.
+         */
+        protected boolean done;
+
+        /**
+         * Whether the generated move command has been returned.
+         */
+        protected boolean moveDone;
+
+        /**
+         * The x coordinate of the next move command.
+         */
+        protected double x;
+
+        /**
+         * The y coordinate of the next move command.
+         */
+        protected double y;
+
+        /**
+         * Sets the path iterator to use and the initial SEG_MOVETO command
+         * to return before it.
+         */
+        public void setPathIterator(PathIterator it, double x, double y) {
+            this.it = it;
+            this.x = x;
+            this.y = y;
+            done = false;
+            moveDone = false;
+        }
+
+        public int currentSegment(double[] coords) {
+            int type = it.currentSegment(coords);
+            if (!moveDone) {
+                coords[0] = x;
+                coords[1] = y;
+                return SEG_MOVETO;
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            int type = it.currentSegment(coords);
+            if (!moveDone) {
+                coords[0] = (float) x;
+                coords[1] = (float) y;
+                return SEG_MOVETO;
+            }
+            return type;
+        }
+
+        public int getWindingRule() {
+            return it.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return done || it.isDone();
+        }
+
+        public void next() {
+            if (!done) {
+                if (!moveDone) {
+                    moveDone = true;
+                } else {
+                    it.next();
+                    done = true;
+                }
+            }
+        }
+    }
+
+    /**
+     * A single path segment in the flattened version of the path.
+     * This is a local helper class. PathSegment-objects are stored in
+     * the {@link PathLength#segments} - list.
+     * This is used as an immutable value-object.
+     */
+    protected static class PathSegment {
+
+        /**
+         * The path segment type.
+         */
+        protected final int segType;
+
+        /**
+         * The x coordinate of the path segment.
+         */
+        protected float x;
+
+        /**
+         * The y coordinate of the path segment.
+         */
+        protected float y;
+
+        /**
+         * The length of the path segment, accumulated from the start.
+         */
+        protected float length;
+
+        /**
+         * The index of the original path segment this flattened segment is a
+         * part of.
+         */
+        protected int index;
+
+        /**
+         * Creates a new PathSegment with the specified parameters.
+         * @param segType The segment type
+         * @param x The x coordinate
+         * @param y The y coordinate
+         * @param len The segment length
+         * @param idx The index of the original path segment this flattened
+         *            segment is a part of
+         */
+        PathSegment(int segType, float x, float y, float len, int idx) {
+            this.segType = segType;
+            this.x = x;
+            this.y = y;
+            this.length = len;
+            this.index = idx;
+        }
+
+        /**
+         * Returns the segment type.
+         */
+        public int getSegType() {
+            return segType;
+        }
+
+        /**
+         * Returns the x coordinate of the path segment.
+         */
+        public float getX() {
+            return x;
+        }
+
+        /**
+         * Sets the x coordinate of the path segment.
+         */
+        public void setX(float v) {
+            x = v;
+        }
+
+        /**
+         * Returns the y coordinate of the path segment.
+         */
+        public float getY() {
+            return y;
+        }
+
+        /**
+         * Sets the y coordinate of the path segment.
+         */
+        public void setY(float v) {
+            y = v;
+        }
+
+        /**
+         * Returns the length of the path segment.
+         */
+        public float getLength() {
+            return length;
+        }
+
+        /**
+         * Sets the length of the path segment.
+         */
+        public void setLength(float v) {
+            length = v;
+        }
+
+        /**
+         * Returns the segment index.
+         */
+        public int getIndex() {
+            return index;
+        }
+
+        /**
+         * Sets the segment index.
+         */
+        public void setIndex(int v) {
+            index = v;
+        }
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/PathLength.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Polygon2D.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Polygon2D.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Polygon2D.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Polygon2D.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,463 @@
+/*
+
+   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 org.apache.flex.forks.batik.ext.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.Polygon;
+import java.awt.Point;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * This class is a Polygon with float coordinates.
+ *
+ * @version $Id: Polygon2D.java 594018 2007-11-12 04:17:41Z cam $
+ */
+public class Polygon2D implements Shape, Cloneable, Serializable {
+
+    /**
+     * The total number of points.  The value of <code>npoints</code>
+     * represents the number of valid points in this <code>Polygon</code>.
+     *
+     */
+    public int npoints;
+
+    /**
+     * The array of <i>x</i> coordinates. The value of {@link #npoints npoints} is equal to the
+     * number of points in this <code>Polygon2D</code>.
+     *
+     */
+    public float[] xpoints;
+
+    /**
+     * The array of <i>x</i> coordinates. The value of {@link #npoints npoints} is equal to the
+     * number of points in this <code>Polygon2D</code>.
+     *
+     */
+    public float[] ypoints;
+
+    /**
+     * Bounds of the Polygon2D.
+     * @see #getBounds()
+     */
+    protected Rectangle2D bounds;
+
+    private GeneralPath path;
+    private GeneralPath closedPath;
+
+    /**
+     * Creates an empty Polygon2D.
+     */
+    public Polygon2D() {
+        xpoints = new float[4];
+        ypoints = new float[4];
+    }
+
+    /**
+     * Constructs and initializes a <code>Polygon2D</code> from the specified
+     * Rectangle2D.
+     * @param rec the Rectangle2D
+     * @exception  NullPointerException rec is <code>null</code>.
+     */
+    public Polygon2D(Rectangle2D rec) {
+        if (rec == null) {
+            throw new IndexOutOfBoundsException("null Rectangle");
+        }
+        npoints = 4;
+        xpoints = new float[4];
+        ypoints = new float[4];
+        xpoints[0] = (float)rec.getMinX();
+        ypoints[0] = (float)rec.getMinY();
+        xpoints[1] = (float)rec.getMaxX();
+        ypoints[1] = (float)rec.getMinY();
+        xpoints[2] = (float)rec.getMaxX();
+        ypoints[2] = (float)rec.getMaxY();
+        xpoints[3] = (float)rec.getMinX();
+        ypoints[3] = (float)rec.getMaxY();
+        calculatePath();
+    }
+
+    /**
+     * Constructs and initializes a <code>Polygon2D</code> from the specified
+     * Polygon.
+     * @param pol the Polygon
+     * @exception  NullPointerException pol is <code>null</code>.
+     */
+    public Polygon2D(Polygon pol) {
+        if (pol == null) {
+            throw new IndexOutOfBoundsException("null Polygon");
+        }
+        this.npoints = pol.npoints;
+        this.xpoints = new float[pol.npoints];
+        this.ypoints = new float[pol.npoints];
+        for (int i = 0; i < pol.npoints; i++) {
+            xpoints[i] = pol.xpoints[i];
+            ypoints[i] = pol.ypoints[i];
+        }
+        calculatePath();
+    }
+
+    /**
+     * Constructs and initializes a <code>Polygon2D</code> from the specified
+     * parameters.
+     * @param xpoints an array of <i>x</i> coordinates
+     * @param ypoints an array of <i>y</i> coordinates
+     * @param npoints the total number of points in the <code>Polygon2D</code>
+     * @exception  NegativeArraySizeException if the value of
+     *                       <code>npoints</code> is negative.
+     * @exception  IndexOutOfBoundsException if <code>npoints</code> is
+     *             greater than the length of <code>xpoints</code>
+     *             or the length of <code>ypoints</code>.
+     * @exception  NullPointerException if <code>xpoints</code> or
+     *             <code>ypoints</code> is <code>null</code>.
+     */
+    public Polygon2D(float[] xpoints, float[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            throw new IndexOutOfBoundsException("npoints > xpoints.length || npoints > ypoints.length");
+        }
+        this.npoints = npoints;
+        this.xpoints = new float[npoints];
+        this.ypoints = new float[npoints];
+        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+        calculatePath();
+    }
+
+    /**
+     * Constructs and initializes a <code>Polygon2D</code> from the specified
+     * parameters.
+     * @param xpoints an array of <i>x</i> coordinates
+     * @param ypoints an array of <i>y</i> coordinates
+     * @param npoints the total number of points in the <code>Polygon2D</code>
+     * @exception  NegativeArraySizeException if the value of
+     *                       <code>npoints</code> is negative.
+     * @exception  IndexOutOfBoundsException if <code>npoints</code> is
+     *             greater than the length of <code>xpoints</code>
+     *             or the length of <code>ypoints</code>.
+     * @exception  NullPointerException if <code>xpoints</code> or
+     *             <code>ypoints</code> is <code>null</code>.
+     */
+    public Polygon2D(int[] xpoints, int[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            throw new IndexOutOfBoundsException("npoints > xpoints.length || npoints > ypoints.length");
+        }
+        this.npoints = npoints;
+        this.xpoints = new float[npoints];
+        this.ypoints = new float[npoints];
+        for (int i = 0; i < npoints; i++) {
+            this.xpoints[i] = xpoints[i];
+            this.ypoints[i] = ypoints[i];
+        }
+        calculatePath();
+    }
+
+    /**
+     * Resets this <code>Polygon</code> object to an empty polygon.
+     */
+    public void reset() {
+        npoints = 0;
+        bounds = null;
+        path = new GeneralPath();
+        closedPath = null;
+    }
+
+    public Object clone() {
+        Polygon2D pol = new Polygon2D();
+        for (int i = 0; i < npoints; i++) {
+            pol.addPoint(xpoints[i], ypoints[i]);
+        }
+        return pol;
+    }
+
+    private void calculatePath() {
+        path = new GeneralPath();
+        path.moveTo(xpoints[0], ypoints[0]);
+        for (int i = 1; i < npoints; i++) {
+            path.lineTo(xpoints[i], ypoints[i]);
+        }
+        bounds = path.getBounds2D();
+        closedPath = null;
+    }
+
+    private void updatePath(float x, float y) {
+        closedPath = null;
+        if (path == null) {
+            path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+            path.moveTo(x, y);
+            bounds = new Rectangle2D.Float(x, y, 0, 0);
+        } else {
+            path.lineTo(x, y);
+            float _xmax = (float)bounds.getMaxX();
+            float _ymax = (float)bounds.getMaxY();
+            float _xmin = (float)bounds.getMinX();
+            float _ymin = (float)bounds.getMinY();
+            if (x < _xmin) _xmin = x;
+            else if (x > _xmax) _xmax = x;
+            if (y < _ymin) _ymin = y;
+            else if (y > _ymax) _ymax = y;
+            bounds = new Rectangle2D.Float(_xmin, _ymin, _xmax - _xmin, _ymax - _ymin);
+        }
+    }
+
+    /* get the associated {@link Polyline2D}.
+     */
+    public Polyline2D getPolyline2D() {
+
+        Polyline2D pol = new Polyline2D( xpoints, ypoints, npoints );
+
+        pol.addPoint( xpoints[0], ypoints[0]);
+
+        return pol;
+    }
+
+    public Polygon getPolygon() {
+        int[] _xpoints = new int[npoints];
+        int[] _ypoints = new int[npoints];
+        for (int i = 0; i < npoints; i++) {
+            _xpoints[i] = (int)xpoints[i];     // todo maybe rounding is better ?
+            _ypoints[i] = (int)ypoints[i];
+        }
+
+        return new Polygon(_xpoints, _ypoints, npoints);
+    }
+
+    public void addPoint(Point2D p) {
+        addPoint((float)p.getX(), (float)p.getY());
+    }
+
+    /**
+     * Appends the specified coordinates to this <code>Polygon2D</code>.
+     * @param       x the specified x coordinate
+     * @param       y the specified y coordinate
+     */
+    public void addPoint(float x, float y) {
+        if (npoints == xpoints.length) {
+            float[] tmp;
+
+            tmp = new float[npoints * 2];
+            System.arraycopy(xpoints, 0, tmp, 0, npoints);
+            xpoints = tmp;
+
+            tmp = new float[npoints * 2];
+            System.arraycopy(ypoints, 0, tmp, 0, npoints);
+            ypoints = tmp;
+        }
+        xpoints[npoints] = x;
+        ypoints[npoints] = y;
+        npoints++;
+        updatePath(x, y);
+    }
+
+    /**
+     * Determines whether the specified {@link Point} is inside this
+     * <code>Polygon</code>.
+     * @param p the specified <code>Point</code> to be tested
+     * @return <code>true</code> if the <code>Polygon</code> contains the
+     *                         <code>Point</code>; <code>false</code> otherwise.
+     * @see #contains(double, double)
+     */
+    public boolean contains(Point p) {
+        return contains(p.x, p.y);
+    }
+
+    /**
+     * Determines whether the specified coordinates are inside this
+     * <code>Polygon</code>.
+     * <p>
+     * @param x the specified x coordinate to be tested
+     * @param y the specified y coordinate to be tested
+     * @return  <code>true</code> if this <code>Polygon</code> contains
+     *                         the specified coordinates, (<i>x</i>,&nbsp;<i>y</i>);
+     *                         <code>false</code> otherwise.
+     */
+    public boolean contains(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Returns the high precision bounding box of the {@link Shape}.
+     * @return a {@link Rectangle2D} that precisely
+     *                bounds the <code>Shape</code>.
+     */
+    public Rectangle2D getBounds2D() {
+        return bounds;
+    }
+
+    public Rectangle getBounds() {
+        if (bounds == null) return null;
+        else return bounds.getBounds();
+    }
+
+    /**
+     * Determines if the specified coordinates are inside this
+     * <code>Polygon</code>.  For the definition of
+     * <i>insideness</i>, see the class comments of {@link Shape}.
+     * @param x the specified x coordinate
+     * @param y the specified y coordinate
+     * @return <code>true</code> if the <code>Polygon</code> contains the
+     * specified coordinates; <code>false</code> otherwise.
+     */
+    public boolean contains(double x, double y) {
+        if (npoints <= 2 || !bounds.contains(x, y)) {
+            return false;
+        }
+        updateComputingPath();
+
+        return closedPath.contains(x, y);
+    }
+
+    private void updateComputingPath() {
+        if (npoints >= 1) {
+            if (closedPath == null) {
+                closedPath = (GeneralPath)path.clone();
+                closedPath.closePath();
+            }
+        }
+    }
+
+    /**
+     * Tests if a specified {@link Point2D} is inside the boundary of this
+     * <code>Polygon</code>.
+     * @param p a specified <code>Point2D</code>
+     * @return <code>true</code> if this <code>Polygon</code> contains the
+     *                 specified <code>Point2D</code>; <code>false</code>
+     *          otherwise.
+     * @see #contains(double, double)
+     */
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    /**
+     * Tests if the interior of this <code>Polygon</code> intersects the
+     * interior of a specified set of rectangular coordinates.
+     * @param x the x coordinate of the specified rectangular
+     *                        shape's top-left corner
+     * @param y the y coordinate of the specified rectangular
+     *                        shape's top-left corner
+     * @param w the width of the specified rectangular shape
+     * @param h the height of the specified rectangular shape
+     * @return <code>true</code> if the interior of this
+     *                        <code>Polygon</code> and the interior of the
+     *                        specified set of rectangular
+     *                         coordinates intersect each other;
+     *                        <code>false</code> otherwise.
+     */
+    public boolean intersects(double x, double y, double w, double h) {
+        if (npoints <= 0 || !bounds.intersects(x, y, w, h)) {
+            return false;
+        }
+        updateComputingPath();
+        return closedPath.intersects(x, y, w, h);
+    }
+
+    /**
+     * Tests if the interior of this <code>Polygon</code> intersects the
+     * interior of a specified <code>Rectangle2D</code>.
+     * @param r a specified <code>Rectangle2D</code>
+     * @return <code>true</code> if this <code>Polygon</code> and the
+     *                         interior of the specified <code>Rectangle2D</code>
+     *                         intersect each other; <code>false</code>
+     *                         otherwise.
+     */
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Tests if the interior of this <code>Polygon</code> entirely
+     * contains the specified set of rectangular coordinates.
+     * @param x the x coordinate of the top-left corner of the
+     *                         specified set of rectangular coordinates
+     * @param y the y coordinate of the top-left corner of the
+     *                         specified set of rectangular coordinates
+     * @param w the width of the set of rectangular coordinates
+     * @param h the height of the set of rectangular coordinates
+     * @return <code>true</code> if this <code>Polygon</code> entirely
+     *                         contains the specified set of rectangular
+     *                         coordinates; <code>false</code> otherwise.
+     */
+    public boolean contains(double x, double y, double w, double h) {
+        if (npoints <= 0 || !bounds.intersects(x, y, w, h)) {
+            return false;
+        }
+
+        updateComputingPath();
+        return closedPath.contains(x, y, w, h);
+    }
+
+    /**
+     * Tests if the interior of this <code>Polygon</code> entirely
+     * contains the specified <code>Rectangle2D</code>.
+     * @param r the specified <code>Rectangle2D</code>
+     * @return <code>true</code> if this <code>Polygon</code> entirely
+     *                         contains the specified <code>Rectangle2D</code>;
+     *                        <code>false</code> otherwise.
+     * @see #contains(double, double, double, double)
+     */
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Returns an iterator object that iterates along the boundary of this
+     * <code>Polygon</code> and provides access to the geometry
+     * of the outline of this <code>Polygon</code>.  An optional
+     * {@link AffineTransform} can be specified so that the coordinates
+     * returned in the iteration are transformed accordingly.
+     * @param at an optional <code>AffineTransform</code> to be applied to the
+     *                 coordinates as they are returned in the iteration, or
+     *                <code>null</code> if untransformed coordinates are desired
+     * @return a {@link PathIterator} object that provides access to the
+     *                geometry of this <code>Polygon</code>.
+     */
+    public PathIterator getPathIterator(AffineTransform at) {
+        updateComputingPath();
+        if (closedPath == null) return null;
+        else return closedPath.getPathIterator(at);
+    }
+
+    /**
+     * Returns an iterator object that iterates along the boundary of
+     * the <code>Polygon2D</code> and provides access to the geometry of the
+     * outline of the <code>Shape</code>.  Only SEG_MOVETO, SEG_LINETO, and
+     * SEG_CLOSE point types are returned by the iterator.
+     * Since polygons are already flat, the <code>flatness</code> parameter
+     * is ignored.
+     * @param at an optional <code>AffineTransform</code> to be applied to the
+     *                 coordinates as they are returned in the iteration, or
+     *                <code>null</code> if untransformed coordinates are desired
+     * @param flatness the maximum amount that the control points
+     *                 for a given curve can vary from colinear before a subdivided
+     *                curve is replaced by a straight line connecting the
+     *                 endpoints.  Since polygons are already flat the
+     *                 <code>flatness</code> parameter is ignored.
+     * @return a <code>PathIterator</code> object that provides access to the
+     *                 <code>Shape</code> object's geometry.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return getPathIterator(at);
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/geom/Polygon2D.java
------------------------------------------------------------------------------
    svn:eol-style = native