FileDocCategorySizeDatePackage
GeneralPath.javaAPI DocAndroid 1.5 API19887Wed May 06 22:41:54 BST 2009java.awt.geom

GeneralPath

public final class GeneralPath extends Object implements Shape, Cloneable
The class GeneralPath represents a shape whose outline is given by different types of curved and straight segments.
since
Android 1.0

Fields Summary
public static final int
WIND_EVEN_ODD
The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}.
public static final int
WIND_NON_ZERO
The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}.
private static final int
BUFFER_SIZE
The buffers size.
private static final int
BUFFER_CAPACITY
The buffers capacity.
byte[]
types
The point's types buffer.
float[]
points
The points buffer.
int
typeSize
The point's type buffer size.
int
pointSize
The points buffer size.
int
rule
The path rule.
static int[]
pointShift
The space amount in points buffer for different segmenet's types.
Constructors Summary
public GeneralPath()
Instantiates a new general path with the winding rule set to {@link PathIterator#WIND_NON_ZERO} and the initial capacity (number of segments) set to the default value 10.

        this(WIND_NON_ZERO, BUFFER_SIZE);
    
public GeneralPath(int rule)
Instantiates a new general path with the given winding rule and the initial capacity (number of segments) set to the default value 10.

param
rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or {@link PathIterator#WIND_NON_ZERO}.

        this(rule, BUFFER_SIZE);
    
public GeneralPath(int rule, int initialCapacity)
Instantiates a new general path with the given winding rule and initial capacity (number of segments).

param
rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or {@link PathIterator#WIND_NON_ZERO}.
param
initialCapacity the number of segments the path is set to hold.

        setWindingRule(rule);
        types = new byte[initialCapacity];
        points = new float[initialCapacity * 2];
    
public GeneralPath(Shape shape)
Creates a new GeneralPath from the outline of the given shape.

param
shape the shape.

        this(WIND_NON_ZERO, BUFFER_SIZE);
        PathIterator p = shape.getPathIterator(null);
        setWindingRule(p.getWindingRule());
        append(p, false);
    
Methods Summary
public voidappend(java.awt.Shape shape, boolean connect)
Appends the outline of the specified shape onto the end of this GeneralPath.

param
shape the shape whose outline is to be appended.
param
connect true to connect this path's current endpoint to the first point of the shape's outline or false to append the shape's outline without connecting it.
throws
NullPointerException if the shape parameter is null.

        PathIterator p = shape.getPathIterator(null);
        append(p, connect);
    
public voidappend(java.awt.geom.PathIterator path, boolean connect)
Appends the path defined by the specified PathIterator onto the end of this GeneralPath.

param
path the PathIterator that defines the new path to append.
param
connect true to connect this path's current endpoint to the first point of the shape's outline or false to append the shape's outline without connecting it.

        while (!path.isDone()) {
            float coords[] = new float[6];
            switch (path.currentSegment(coords)) {
                case PathIterator.SEG_MOVETO:
                    if (!connect || typeSize == 0) {
                        moveTo(coords[0], coords[1]);
                        break;
                    }
                    if (types[typeSize - 1] != PathIterator.SEG_CLOSE
                            && points[pointSize - 2] == coords[0]
                            && points[pointSize - 1] == coords[1]) {
                        break;
                    }
                    // NO BREAK;
                case PathIterator.SEG_LINETO:
                    lineTo(coords[0], coords[1]);
                    break;
                case PathIterator.SEG_QUADTO:
                    quadTo(coords[0], coords[1], coords[2], coords[3]);
                    break;
                case PathIterator.SEG_CUBICTO:
                    curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
                    break;
                case PathIterator.SEG_CLOSE:
                    closePath();
                    break;
            }
            path.next();
            connect = false;
        }
    
voidcheckBuf(int pointCount, boolean checkMove)
Checks the point data buffer sizes to see whether pointCount additional point-data elements can fit. (Note that the number of point data elements to add is more than one per point -- it depends on the type of point being added.) Reallocates the buffers to enlarge the size if necessary.

param
pointCount the number of point data elements to be added.
param
checkMove whether to check for existing points.
throws
IllegalPathStateException checkMove is true and the path is currently empty.

        if (checkMove && typeSize == 0) {
            // awt.20A=First segment should be SEG_MOVETO type
            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
        }
        if (typeSize == types.length) {
            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
            System.arraycopy(types, 0, tmp, 0, typeSize);
            types = tmp;
        }
        if (pointSize + pointCount > points.length) {
            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
            System.arraycopy(points, 0, tmp, 0, pointSize);
            points = tmp;
        }
    
public java.lang.Objectclone()

        try {
            GeneralPath p = (GeneralPath)super.clone();
            p.types = types.clone();
            p.points = points.clone();
            return p;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    
public voidclosePath()
Appends the type information to declare that the current endpoint closes the curve.

        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
            checkBuf(0, true);
            types[typeSize++] = PathIterator.SEG_CLOSE;
        }
    
public booleancontains(double px, double py)

        return isInside(Crossing.crossShape(this, px, py));
    
public booleancontains(double rx, double ry, double rw, double rh)

        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
        return cross != Crossing.CROSSING && isInside(cross);
    
public booleancontains(java.awt.geom.Point2D p)

        return contains(p.getX(), p.getY());
    
public booleancontains(java.awt.geom.Rectangle2D r)

        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
    
public java.awt.ShapecreateTransformedShape(java.awt.geom.AffineTransform t)
Creates a new GeneralPath whose data is given by this path's data transformed according to the specified AffineTransform.

param
t the AffineTransform.
return
the new GeneralPath whose data is given by this path's data transformed according to the specified AffineTransform.

        GeneralPath p = (GeneralPath)clone();
        if (t != null) {
            p.transform(t);
        }
        return p;
    
public voidcurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
Appends a new segment to the end of this general path by making a cubic curve from the current endpoint to the point (x3, y3) using (x1, y1) and (x2, y2) as control points.

see
java.awt.geom.CubicCurve2D
param
x1 the x coordinate of the new cubic segment's first control point.
param
y1 the y coordinate of the new cubic segment's first control point.
param
x2 the x coordinate of the new cubic segment's second control point.
param
y2 the y coordinate of the new cubic segment's second control point.
param
x3 the x coordinate of the new cubic segment's end point.
param
y3 the y coordinate of the new cubic segment's end point.

        checkBuf(6, true);
        types[typeSize++] = PathIterator.SEG_CUBICTO;
        points[pointSize++] = x1;
        points[pointSize++] = y1;
        points[pointSize++] = x2;
        points[pointSize++] = y2;
        points[pointSize++] = x3;
        points[pointSize++] = y3;
    
public java.awt.RectanglegetBounds()

        return getBounds2D().getBounds();
    
public java.awt.geom.Rectangle2DgetBounds2D()

        float rx1, ry1, rx2, ry2;
        if (pointSize == 0) {
            rx1 = ry1 = rx2 = ry2 = 0.0f;
        } else {
            int i = pointSize - 1;
            ry1 = ry2 = points[i--];
            rx1 = rx2 = points[i--];
            while (i > 0) {
                float y = points[i--];
                float x = points[i--];
                if (x < rx1) {
                    rx1 = x;
                } else if (x > rx2) {
                    rx2 = x;
                }
                if (y < ry1) {
                    ry1 = y;
                } else if (y > ry2) {
                    ry2 = y;
                }
            }
        }
        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
    
public java.awt.geom.Point2DgetCurrentPoint()
Gets the current end point of the path.

return
the current end point of the path.

        if (typeSize == 0) {
            return null;
        }
        int j = pointSize - 2;
        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {

            for (int i = typeSize - 2; i > 0; i--) {
                int type = types[i];
                if (type == PathIterator.SEG_MOVETO) {
                    break;
                }
                j -= pointShift[type];
            }
        }
        return new Point2D.Float(points[j], points[j + 1]);
    
public java.awt.geom.PathIteratorgetPathIterator(java.awt.geom.AffineTransform t)

        return new Iterator(this, t);
    
public java.awt.geom.PathIteratorgetPathIterator(java.awt.geom.AffineTransform t, double flatness)

        return new FlatteningPathIterator(getPathIterator(t), flatness);
    
public intgetWindingRule()
Gets the winding rule.

return
the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or {@link PathIterator#WIND_NON_ZERO}.

        return rule;
    
public booleanintersects(double rx, double ry, double rw, double rh)

        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
        return cross == Crossing.CROSSING || isInside(cross);
    
public booleanintersects(java.awt.geom.Rectangle2D r)

        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
    
booleanisInside(int cross)
Checks the cross count (number of times a ray from the point crosses the shape's boundary) to determine whether the number of crossings corresponds to a point inside the shape or not (according to the shape's path rule).

param
cross the point's cross count.
return
true if the point is inside the path, or false otherwise.

        if (rule == WIND_NON_ZERO) {
            return Crossing.isInsideNonZero(cross);
        }
        return Crossing.isInsideEvenOdd(cross);
    
public voidlineTo(float x, float y)
Appends a new segment to the end of this general path by making a straight line segment from the current endpoint to the given new point.

param
x the x coordinate of the next point to append.
param
y the y coordinate of the next point to append.

        checkBuf(2, true);
        types[typeSize++] = PathIterator.SEG_LINETO;
        points[pointSize++] = x;
        points[pointSize++] = y;
    
public voidmoveTo(float x, float y)
Appends a new point to the end of this general path, disconnected from the existing path.

param
x the x coordinate of the next point to append.
param
y the y coordinate of the next point to append.

        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
            points[pointSize - 2] = x;
            points[pointSize - 1] = y;
        } else {
            checkBuf(2, false);
            types[typeSize++] = PathIterator.SEG_MOVETO;
            points[pointSize++] = x;
            points[pointSize++] = y;
        }
    
public voidquadTo(float x1, float y1, float x2, float y2)
Appends a new segment to the end of this general path by making a quadratic curve from the current endpoint to the point (x2, y2) using the point (x1, y1) as the quadratic curve's control point.

param
x1 the x coordinate of the quadratic curve's control point.
param
y1 the y coordinate of the quadratic curve's control point.
param
x2 the x coordinate of the quadratic curve's end point.
param
y2 the y coordinate of the quadratic curve's end point.

        checkBuf(4, true);
        types[typeSize++] = PathIterator.SEG_QUADTO;
        points[pointSize++] = x1;
        points[pointSize++] = y1;
        points[pointSize++] = x2;
        points[pointSize++] = y2;
    
public voidreset()
Resets the GeneralPath to being an empty path. The underlying point and segment data is not deleted but rather the end indices of the data arrays are set to zero.

        typeSize = 0;
        pointSize = 0;
    
public voidsetWindingRule(int rule)
Sets the winding rule, which determines how to decide whether a point that isn't on the path itself is inside or outside of the shape.

param
rule the new winding rule.
throws
IllegalArgumentException if the winding rule is neither {@link PathIterator#WIND_EVEN_ODD} nor {@link PathIterator#WIND_NON_ZERO}.

        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
            // awt.209=Invalid winding rule value
            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
        }
        this.rule = rule;
    
public voidtransform(java.awt.geom.AffineTransform t)
Transform all of the coordinates of this path according to the specified AffineTransform.

param
t the AffineTransform.

        t.transform(points, 0, points, 0, pointSize / 2);