Methods Summary |
---|
public final void | append(java.awt.Shape s, boolean connect)Appends the geometry of the specified {@code Shape} object to the
path, possibly connecting the new geometry to the existing path
segments with a line segment.
If the {@code connect} parameter is {@code true} and the
path is not empty then any initial {@code moveTo} in the
geometry of the appended {@code Shape}
is turned into a {@code lineTo} segment.
If the destination coordinates of such a connecting {@code lineTo}
segment match the ending coordinates of a currently open
subpath then the segment is omitted as superfluous.
The winding rule of the specified {@code Shape} is ignored
and the appended geometry is governed by the winding
rule specified for this path.
append(s.getPathIterator(null), connect);
|
public abstract void | append(java.awt.geom.PathIterator pi, boolean connect)Appends the geometry of the specified
{@link PathIterator} object
to the path, possibly connecting the new geometry to the existing
path segments with a line segment.
If the {@code connect} parameter is {@code true} and the
path is not empty then any initial {@code moveTo} in the
geometry of the appended {@code Shape} is turned into a
{@code lineTo} segment.
If the destination coordinates of such a connecting {@code lineTo}
segment match the ending coordinates of a currently open
subpath then the segment is omitted as superfluous.
The winding rule of the specified {@code Shape} is ignored
and the appended geometry is governed by the winding
rule specified for this path.
|
abstract void | append(float x, float y)
|
abstract void | append(double x, double y)
|
public abstract java.lang.Object | clone()Creates a new object of the same class as this object.
|
abstract double[] | cloneCoordsDouble(java.awt.geom.AffineTransform at)
|
abstract float[] | cloneCoordsFloat(java.awt.geom.AffineTransform at)
|
public final synchronized void | closePath()Closes the current subpath by drawing a straight line back to
the coordinates of the last {@code moveTo}. If the path is already
closed then this method has no effect.
if (numTypes == 0 || pointTypes[numTypes - 1] != SEG_CLOSE) {
needRoom(true, 0);
pointTypes[numTypes++] = SEG_CLOSE;
}
|
public static boolean | contains(java.awt.geom.PathIterator pi, double x, double y)Tests if the specified coordinates are inside the closed
boundary of the specified {@link PathIterator}.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#contains(double, double)} method.
if (x * 0.0 + y * 0.0 == 0.0) {
/* N * 0.0 is 0.0 only if N is finite.
* Here we know that both x and y are finite.
*/
int mask = (pi.getWindingRule() == WIND_NON_ZERO ? -1 : 1);
int cross = Curve.pointCrossingsForPath(pi, x, y);
return ((cross & mask) != 0);
} else {
/* Either x or y was infinite or NaN.
* A NaN always produces a negative response to any test
* and Infinity values cannot be "inside" any path so
* they should return false as well.
*/
return false;
}
|
public static boolean | contains(java.awt.geom.PathIterator pi, java.awt.geom.Point2D p)Tests if the specified {@link Point2D} is inside the closed
boundary of the specified {@link PathIterator}.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#contains(Point2D)} method.
return contains(pi, p.getX(), p.getY());
|
public final boolean | contains(double x, double y){@inheritDoc}
if (x * 0.0 + y * 0.0 == 0.0) {
/* N * 0.0 is 0.0 only if N is finite.
* Here we know that both x and y are finite.
*/
if (numTypes < 2) {
return false;
}
int mask = (windingRule == WIND_NON_ZERO ? -1 : 1);
return ((pointCrossings(x, y) & mask) != 0);
} else {
/* Either x or y was infinite or NaN.
* A NaN always produces a negative response to any test
* and Infinity values cannot be "inside" any path so
* they should return false as well.
*/
return false;
}
|
public final boolean | contains(java.awt.geom.Point2D p){@inheritDoc}
return contains(p.getX(), p.getY());
|
public static boolean | contains(java.awt.geom.PathIterator pi, double x, double y, double w, double h)Tests if the specified rectangular area is entirely inside the
closed boundary of the specified {@link PathIterator}.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#contains(double, double, double, double)} method.
This method object may conservatively return false in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such segments could lie entirely within the interior of the
path if they are part of a path with a {@link #WIND_NON_ZERO}
winding rule or if the segments are retraced in the reverse
direction such that the two sets of segments cancel each
other out without any exterior area falling between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
if (java.lang.Double.isNaN(x+w) || java.lang.Double.isNaN(y+h)) {
/* [xy]+[wh] is NaN if any of those values are NaN,
* or if adding the two together would produce NaN
* by virtue of adding opposing Infinte values.
* Since we need to add them below, their sum must
* not be NaN.
* We return false because NaN always produces a
* negative response to tests
*/
return false;
}
if (w <= 0 || h <= 0) {
return false;
}
int mask = (pi.getWindingRule() == WIND_NON_ZERO ? -1 : 2);
int crossings = Curve.rectCrossingsForPath(pi, x, y, x+w, y+h);
return (crossings != Curve.RECT_INTERSECTS &&
(crossings & mask) != 0);
|
public static boolean | contains(java.awt.geom.PathIterator pi, java.awt.geom.Rectangle2D r)Tests if the specified {@link Rectangle2D} is entirely inside the
closed boundary of the specified {@link PathIterator}.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#contains(Rectangle2D)} method.
This method object may conservatively return false in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such segments could lie entirely within the interior of the
path if they are part of a path with a {@link #WIND_NON_ZERO}
winding rule or if the segments are retraced in the reverse
direction such that the two sets of segments cancel each
other out without any exterior area falling between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
return contains(pi, r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
public final boolean | contains(double x, double y, double w, double h){@inheritDoc}
This method object may conservatively return false in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such segments could lie entirely within the interior of the
path if they are part of a path with a {@link #WIND_NON_ZERO}
winding rule or if the segments are retraced in the reverse
direction such that the two sets of segments cancel each
other out without any exterior area falling between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
if (java.lang.Double.isNaN(x+w) || java.lang.Double.isNaN(y+h)) {
/* [xy]+[wh] is NaN if any of those values are NaN,
* or if adding the two together would produce NaN
* by virtue of adding opposing Infinte values.
* Since we need to add them below, their sum must
* not be NaN.
* We return false because NaN always produces a
* negative response to tests
*/
return false;
}
if (w <= 0 || h <= 0) {
return false;
}
int mask = (windingRule == WIND_NON_ZERO ? -1 : 2);
int crossings = rectCrossings(x, y, x+w, y+h);
return (crossings != Curve.RECT_INTERSECTS &&
(crossings & mask) != 0);
|
public final boolean | contains(java.awt.geom.Rectangle2D r){@inheritDoc}
This method object may conservatively return false in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such segments could lie entirely within the interior of the
path if they are part of a path with a {@link #WIND_NON_ZERO}
winding rule or if the segments are retraced in the reverse
direction such that the two sets of segments cancel each
other out without any exterior area falling between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
public final synchronized java.awt.Shape | createTransformedShape(java.awt.geom.AffineTransform at)Returns a new {@code Shape} representing a transformed version
of this {@code Path2D}.
Note that the exact type and coordinate precision of the return
value is not specified for this method.
The method will return a Shape that contains no less precision
for the transformed geometry than this {@code Path2D} currently
maintains, but it may contain no more precision either.
If the tradeoff of precision vs. storage size in the result is
important then the convenience constructors in the
{@link Path2D.Float#Path2D.Float(Shape, AffineTransform) Path2D.Float}
and
{@link Path2D.Double#Path2D.Double(Shape, AffineTransform) Path2D.Double}
subclasses should be used to make the choice explicit.
Path2D p2d = (Path2D) clone();
if (at != null) {
p2d.transform(at);
}
return p2d;
|
public abstract void | curveTo(double x1, double y1, double x2, double y2, double x3, double y3)Adds a curved segment, defined by three new points, to the path by
drawing a Bézier curve that intersects both the current
coordinates and the specified coordinates {@code (x3,y3)},
using the specified points {@code (x1,y1)} and {@code (x2,y2)} as
Bézier control points.
All coordinates are specified in double precision.
|
public final java.awt.Rectangle | getBounds(){@inheritDoc}
return getBounds2D().getBounds();
|
public final synchronized java.awt.geom.Point2D | getCurrentPoint()Returns the coordinates most recently added to the end of the path
as a {@link Point2D} object.
int index = numCoords;
if (numTypes < 1 || index < 1) {
return null;
}
if (pointTypes[numTypes - 1] == SEG_CLOSE) {
loop:
for (int i = numTypes - 2; i > 0; i--) {
switch (pointTypes[i]) {
case SEG_MOVETO:
break loop;
case SEG_LINETO:
index -= 2;
break;
case SEG_QUADTO:
index -= 4;
break;
case SEG_CUBICTO:
index -= 6;
break;
case SEG_CLOSE:
break;
}
}
}
return getPoint(index - 2);
|
public java.awt.geom.PathIterator | getPathIterator(java.awt.geom.AffineTransform at, double flatness){@inheritDoc}
The iterator for this class is not multi-threaded safe,
which means that this {@code Path2D} class does not
guarantee that modifications to the geometry of this
{@code Path2D} object do not affect any iterations of
that geometry that are already in process.
return new FlatteningPathIterator(getPathIterator(at), flatness);
|
abstract java.awt.geom.Point2D | getPoint(int coordindex)
|
public final synchronized int | getWindingRule()Returns the fill style winding rule.
return windingRule;
|
public static boolean | intersects(java.awt.geom.PathIterator pi, double x, double y, double w, double h)Tests if the interior of the specified {@link PathIterator}
intersects the interior of a specified set of rectangular
coordinates.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#intersects(double, double, double, double)} method.
This method object may conservatively return true in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such a case may occur if some set of segments of the
path are retraced in the reverse direction such that the
two sets of segments cancel each other out without any
interior area between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
if (java.lang.Double.isNaN(x+w) || java.lang.Double.isNaN(y+h)) {
/* [xy]+[wh] is NaN if any of those values are NaN,
* or if adding the two together would produce NaN
* by virtue of adding opposing Infinte values.
* Since we need to add them below, their sum must
* not be NaN.
* We return false because NaN always produces a
* negative response to tests
*/
return false;
}
if (w <= 0 || h <= 0) {
return false;
}
int mask = (pi.getWindingRule() == WIND_NON_ZERO ? -1 : 2);
int crossings = Curve.rectCrossingsForPath(pi, x, y, x+w, y+h);
return (crossings == Curve.RECT_INTERSECTS ||
(crossings & mask) != 0);
|
public static boolean | intersects(java.awt.geom.PathIterator pi, java.awt.geom.Rectangle2D r)Tests if the interior of the specified {@link PathIterator}
intersects the interior of a specified {@link Rectangle2D}.
This method provides a basic facility for implementors of
the {@link Shape} interface to implement support for the
{@link Shape#intersects(Rectangle2D)} method.
This method object may conservatively return true in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such a case may occur if some set of segments of the
path are retraced in the reverse direction such that the
two sets of segments cancel each other out without any
interior area between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
return intersects(pi, r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
public final boolean | intersects(double x, double y, double w, double h){@inheritDoc}
This method object may conservatively return true in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such a case may occur if some set of segments of the
path are retraced in the reverse direction such that the
two sets of segments cancel each other out without any
interior area between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
if (java.lang.Double.isNaN(x+w) || java.lang.Double.isNaN(y+h)) {
/* [xy]+[wh] is NaN if any of those values are NaN,
* or if adding the two together would produce NaN
* by virtue of adding opposing Infinte values.
* Since we need to add them below, their sum must
* not be NaN.
* We return false because NaN always produces a
* negative response to tests
*/
return false;
}
if (w <= 0 || h <= 0) {
return false;
}
int mask = (windingRule == WIND_NON_ZERO ? -1 : 2);
int crossings = rectCrossings(x, y, x+w, y+h);
return (crossings == Curve.RECT_INTERSECTS ||
(crossings & mask) != 0);
|
public final boolean | intersects(java.awt.geom.Rectangle2D r){@inheritDoc}
This method object may conservatively return true in
cases where the specified rectangular area intersects a
segment of the path, but that segment does not represent a
boundary between the interior and exterior of the path.
Such a case may occur if some set of segments of the
path are retraced in the reverse direction such that the
two sets of segments cancel each other out without any
interior area between them.
To determine whether segments represent true boundaries of
the interior of the path would require extensive calculations
involving all of the segments of the path and the winding
rule and are thus beyond the scope of this implementation.
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
public abstract void | lineTo(double x, double y)Adds a point to the path by drawing a straight line from the
current coordinates to the new specified coordinates
specified in double precision.
|
public abstract void | moveTo(double x, double y)Adds a point to the path by moving to the specified
coordinates specified in double precision.
|
abstract void | needRoom(boolean needMove, int newCoords)
|
abstract int | pointCrossings(double px, double py)
|
public abstract void | quadTo(double x1, double y1, double x2, double y2)Adds a curved segment, defined by two new points, to the path by
drawing a Quadratic curve that intersects both the current
coordinates and the specified coordinates {@code (x2,y2)},
using the specified point {@code (x1,y1)} as a quadratic
parametric control point.
All coordinates are specified in double precision.
|
final void | readObject(java.io.ObjectInputStream s, boolean storedbl)
s.defaultReadObject();
// The subclass calls this method with the storage type that
// they want us to use (storedbl) so we ignore the storage
// method hint from the stream.
s.readByte();
int nT = s.readInt();
int nC = s.readInt();
try {
setWindingRule(s.readByte());
} catch (IllegalArgumentException iae) {
throw new java.io.InvalidObjectException(iae.getMessage());
}
pointTypes = new byte[(nT < 0) ? INIT_SIZE : nT];
if (nC < 0) {
nC = INIT_SIZE * 2;
}
if (storedbl) {
((Path2D.Double) this).doubleCoords = new double[nC];
} else {
((Path2D.Float) this).floatCoords = new float[nC];
}
PATHDONE:
for (int i = 0; nT < 0 || i < nT; i++) {
boolean isdbl;
int npoints;
byte segtype;
byte serialtype = s.readByte();
switch (serialtype) {
case SERIAL_SEG_FLT_MOVETO:
isdbl = false;
npoints = 1;
segtype = SEG_MOVETO;
break;
case SERIAL_SEG_FLT_LINETO:
isdbl = false;
npoints = 1;
segtype = SEG_LINETO;
break;
case SERIAL_SEG_FLT_QUADTO:
isdbl = false;
npoints = 2;
segtype = SEG_QUADTO;
break;
case SERIAL_SEG_FLT_CUBICTO:
isdbl = false;
npoints = 3;
segtype = SEG_CUBICTO;
break;
case SERIAL_SEG_DBL_MOVETO:
isdbl = true;
npoints = 1;
segtype = SEG_MOVETO;
break;
case SERIAL_SEG_DBL_LINETO:
isdbl = true;
npoints = 1;
segtype = SEG_LINETO;
break;
case SERIAL_SEG_DBL_QUADTO:
isdbl = true;
npoints = 2;
segtype = SEG_QUADTO;
break;
case SERIAL_SEG_DBL_CUBICTO:
isdbl = true;
npoints = 3;
segtype = SEG_CUBICTO;
break;
case SERIAL_SEG_CLOSE:
isdbl = false;
npoints = 0;
segtype = SEG_CLOSE;
break;
case SERIAL_PATH_END:
if (nT < 0) {
break PATHDONE;
}
throw new StreamCorruptedException("unexpected PATH_END");
default:
throw new StreamCorruptedException("unrecognized path type");
}
needRoom(segtype != SEG_MOVETO, npoints * 2);
if (isdbl) {
while (--npoints >= 0) {
append(s.readDouble(), s.readDouble());
}
} else {
while (--npoints >= 0) {
append(s.readFloat(), s.readFloat());
}
}
pointTypes[numTypes++] = segtype;
}
if (nT >= 0 && s.readByte() != SERIAL_PATH_END) {
throw new StreamCorruptedException("missing PATH_END");
}
|
abstract int | rectCrossings(double rxmin, double rymin, double rxmax, double rymax)
|
public final synchronized void | reset()Resets the path to empty. The append position is set back to the
beginning of the path and all coordinates and point types are
forgotten.
numTypes = numCoords = 0;
|
public final void | setWindingRule(int rule)Sets the winding rule for this path to the specified value.
if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
throw new IllegalArgumentException("winding rule must be "+
"WIND_EVEN_ODD or "+
"WIND_NON_ZERO");
}
windingRule = rule;
|
public abstract void | transform(java.awt.geom.AffineTransform at)Transforms the geometry of this path using the specified
{@link AffineTransform}.
The geometry is transformed in place, which permanently changes the
boundary defined by this object.
|
final void | writeObject(java.io.ObjectOutputStream s, boolean isdbl)
s.defaultWriteObject();
float fCoords[];
double dCoords[];
if (isdbl) {
dCoords = ((Path2D.Double) this).doubleCoords;
fCoords = null;
} else {
fCoords = ((Path2D.Float) this).floatCoords;
dCoords = null;
}
int numTypes = this.numTypes;
s.writeByte(isdbl
? SERIAL_STORAGE_DBL_ARRAY
: SERIAL_STORAGE_FLT_ARRAY);
s.writeInt(numTypes);
s.writeInt(numCoords);
s.writeByte((byte) windingRule);
int cindex = 0;
for (int i = 0; i < numTypes; i++) {
int npoints;
byte serialtype;
switch (pointTypes[i]) {
case SEG_MOVETO:
npoints = 1;
serialtype = (isdbl
? SERIAL_SEG_DBL_MOVETO
: SERIAL_SEG_FLT_MOVETO);
break;
case SEG_LINETO:
npoints = 1;
serialtype = (isdbl
? SERIAL_SEG_DBL_LINETO
: SERIAL_SEG_FLT_LINETO);
break;
case SEG_QUADTO:
npoints = 2;
serialtype = (isdbl
? SERIAL_SEG_DBL_QUADTO
: SERIAL_SEG_FLT_QUADTO);
break;
case SEG_CUBICTO:
npoints = 3;
serialtype = (isdbl
? SERIAL_SEG_DBL_CUBICTO
: SERIAL_SEG_FLT_CUBICTO);
break;
case SEG_CLOSE:
npoints = 0;
serialtype = SERIAL_SEG_CLOSE;
break;
default:
// Should never happen
throw new InternalError("unrecognized path type");
}
s.writeByte(serialtype);
while (--npoints >= 0) {
if (isdbl) {
s.writeDouble(dCoords[cindex++]);
s.writeDouble(dCoords[cindex++]);
} else {
s.writeFloat(fCoords[cindex++]);
s.writeFloat(fCoords[cindex++]);
}
}
}
s.writeByte((byte) SERIAL_PATH_END);
|