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 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>, <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