Path_Delegatepublic final class Path_Delegate extends Object Delegate implementing the native methods of android.graphics.Path
Through the layoutlib_create tool, the original native methods of Path have been replaced
by calls to methods of the same name in this delegate class.
This class behaves like the original native implementation, but in Java, keeping previously
native data into its own objects and mapping them to int that are sent back and forth between
it and the original Path class. |
Fields Summary |
---|
private static final com.android.layoutlib.bridge.impl.DelegateManager | sManager | private android.graphics.Path.FillType | mFillType | private GeneralPath | mPath | private float | mLastX | private float | mLastY |
Methods Summary |
---|
private static void | addPath(long destPath, long srcPath, java.awt.geom.AffineTransform transform)
Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
if (destPathDelegate == null) {
return;
}
Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
if (srcPathDelegate == null) {
return;
}
if (transform != null) {
destPathDelegate.mPath.append(
srcPathDelegate.mPath.getPathIterator(transform), false);
} else {
destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
}
| private void | addRect(float left, float top, float right, float bottom, int dir)Add a closed rectangle contour to the path
moveTo(left, top);
Direction direction = getDirection(dir);
switch (direction) {
case CW:
lineTo(right, top);
lineTo(right, bottom);
lineTo(left, bottom);
break;
case CCW:
lineTo(left, bottom);
lineTo(right, bottom);
lineTo(right, top);
break;
}
close();
resetLastPointFromPath();
| private void | arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)Append the specified arc to the path as a new contour. If the start of
the path is different from the path's current last point, then an
automatic lineTo() is added to connect the current contour to the
start of the arc. However, if the path is empty, then we call moveTo()
with the first point of the arc. The sweep angle is tread mod 360.
Arc2D arc = new Arc2D.Float(left, top, right - left, bottom - top, -startAngle,
-sweepAngle, Arc2D.OPEN);
mPath.append(arc, true /*connect*/);
resetLastPointFromPath();
| private void | close()Close the current contour. If the current point is not equal to the
first point of the contour, a line segment is automatically added.
mPath.closePath();
| private void | cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)Add a cubic bezier from the last point, approaching control points
(x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
made for this contour, the first point is automatically set to (0,0).
mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
| private void | fillBounds(RectF bounds)Fills the given {@link RectF} with the path bounds.
Rectangle2D rect = mPath.getBounds2D();
bounds.left = (float)rect.getMinX();
bounds.right = (float)rect.getMaxX();
bounds.top = (float)rect.getMinY();
bounds.bottom = (float)rect.getMaxY();
| static void | finalizer(long nPath)
sManager.removeJavaReferenceFor(nPath);
| public static android.graphics.Path_Delegate | getDelegate(long nPath)
// ---- Public Helper methods ----
return sManager.getDelegate(nPath);
| private static android.graphics.Path.Direction | getDirection(int direction)
for (Direction d : Direction.values()) {
if (direction == d.nativeInt) {
return d;
}
}
assert false;
return null;
| public java.awt.Shape | getJavaShape()
return mPath;
| private static int | getWindingRule(android.graphics.Path.FillType type)Returns the Java2D winding rules matching a given Android {@link FillType}.
switch (type) {
case WINDING:
case INVERSE_WINDING:
return GeneralPath.WIND_NON_ZERO;
case EVEN_ODD:
case INVERSE_EVEN_ODD:
return GeneralPath.WIND_EVEN_ODD;
}
assert false;
throw new IllegalArgumentException();
| static long | init1()
// create the delegate
Path_Delegate newDelegate = new Path_Delegate();
return sManager.addNewDelegate(newDelegate);
| static long | init2(long nPath)
// create the delegate
Path_Delegate newDelegate = new Path_Delegate();
// get the delegate to copy, which could be null if nPath is 0
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate != null) {
newDelegate.set(pathDelegate);
}
return sManager.addNewDelegate(newDelegate);
| private boolean | isEmpty()Returns whether the path is empty.
return mPath.getCurrentPoint() == null;
| private void | lineTo(float x, float y)Add a line from the last point to the specified point (x,y).
If no moveTo() call has been made for this contour, the first point is
automatically set to (0,0).
if (isEmpty()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
mPath.lineTo(mLastX = x, mLastY = y);
| private void | moveTo(float x, float y)Set the beginning of the next contour to the point (x,y).
mPath.moveTo(mLastX = x, mLastY = y);
| static void | native_addArc(long nPath, float left, float top, float right, float bottom, float startAngle, float sweepAngle)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
// because x/y is the center of the circle, need to offset this by the radius
pathDelegate.mPath.append(new Arc2D.Float(
left, top, right - left, bottom - top,
-startAngle, -sweepAngle, Arc2D.OPEN), false);
| static void | native_addCircle(long nPath, float x, float y, float radius, int dir)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
// because x/y is the center of the circle, need to offset this by the radius
pathDelegate.mPath.append(new Ellipse2D.Float(
x - radius, y - radius, radius * 2, radius * 2), false);
| static void | native_addOval(long nPath, float left, float top, float right, float bottom, int dir)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mPath.append(new Ellipse2D.Float(
left, top, right - left, bottom - top), false);
| static void | native_addPath(long nPath, long src, float dx, float dy)
addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
| static void | native_addPath(long nPath, long src)
addPath(nPath, src, null /*transform*/);
| static void | native_addPath(long nPath, long src, long matrix)
Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
if (matrixDelegate == null) {
return;
}
addPath(nPath, src, matrixDelegate.getAffineTransform());
| static void | native_addRect(long nPath, float left, float top, float right, float bottom, int dir)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.addRect(left, top, right, bottom, dir);
| static void | native_addRoundRect(long nPath, float left, float top, float right, float bottom, float rx, float ry, int dir)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mPath.append(new RoundRectangle2D.Float(
left, top, right - left, bottom - top, rx * 2, ry * 2), false);
| static void | native_addRoundRect(long nPath, float left, float top, float right, float bottom, float[] radii, int dir)
// Java2D doesn't support different rounded corners in each corner, so just use the
// first value.
native_addRoundRect(nPath, left, top, right, bottom, radii[0], radii[1], dir);
// there can be a case where this API is used but with similar values for all corners, so
// in that case we don't warn.
// we only care if 2 corners are different so just compare to the next one.
for (int i = 0 ; i < 3 ; i++) {
if (radii[i * 2] != radii[(i + 1) * 2] || radii[i * 2 + 1] != radii[(i + 1) * 2 + 1]) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Different corner sizes are not supported in Path.addRoundRect.",
null, null /*data*/);
break;
}
}
| static float[] | native_approximate(long nPath, float error)
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null);
return new float[0];
| static void | native_arcTo(long nPath, float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.arcTo(left, top, right, bottom, startAngle, sweepAngle, forceMoveTo);
| static void | native_close(long nPath)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.close();
| static void | native_computeBounds(long nPath, RectF bounds)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.fillBounds(bounds);
| static void | native_cubicTo(long nPath, float x1, float y1, float x2, float y2, float x3, float y3)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
| static int | native_getFillType(long nPath)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return 0;
}
return pathDelegate.mFillType.nativeInt;
| static void | native_incReserve(long nPath, int extraPtCount)
// since we use a java2D path, there's no way to pre-allocate new points,
// so we do nothing.
| static boolean | native_isConvex(long nPath)
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Path.isConvex is not supported.", null, null);
return true;
| static boolean | native_isEmpty(long nPath)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return true;
}
return pathDelegate.isEmpty();
| static boolean | native_isRect(long nPath, RectF rect)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return false;
}
// create an Area that can test if the path is a rect
Area area = new Area(pathDelegate.mPath);
if (area.isRectangular()) {
if (rect != null) {
pathDelegate.fillBounds(rect);
}
return true;
}
return false;
| static void | native_lineTo(long nPath, float x, float y)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.lineTo(x, y);
| static void | native_moveTo(long nPath, float x, float y)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.moveTo(x, y);
| static void | native_offset(long nPath, float dx, float dy, long dst_path)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
// could be null if the int is 0;
Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
pathDelegate.offset(dx, dy, dstDelegate);
| static void | native_offset(long nPath, float dx, float dy)
native_offset(nPath, dx, dy, 0);
| static boolean | native_op(long nPath1, long nPath2, int op, long result)
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null);
return false;
| static void | native_quadTo(long nPath, float x1, float y1, float x2, float y2)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.quadTo(x1, y1, x2, y2);
| static void | native_rCubicTo(long nPath, float x1, float y1, float x2, float y2, float x3, float y3)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
| static void | native_rLineTo(long nPath, float dx, float dy)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.rLineTo(dx, dy);
| static void | native_rMoveTo(long nPath, float dx, float dy)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.rMoveTo(dx, dy);
| static void | native_rQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
| static void | native_reset(long nPath)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mPath.reset();
| static void | native_rewind(long nPath)
// call out to reset since there's nothing to optimize in
// terms of data structs.
native_reset(nPath);
| static void | native_set(long native_dst, long native_src)
Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
if (pathDstDelegate == null) {
return;
}
Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
if (pathSrcDelegate == null) {
return;
}
pathDstDelegate.set(pathSrcDelegate);
| static void | native_setFillType(long nPath, int ft)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mFillType = Path.sFillTypeArray[ft];
| static void | native_setLastPoint(long nPath, float dx, float dy)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
pathDelegate.mLastX = dx;
pathDelegate.mLastY = dy;
| static void | native_transform(long nPath, long matrix, long dst_path)
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
if (pathDelegate == null) {
return;
}
Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
if (matrixDelegate == null) {
return;
}
// this can be null if dst_path is 0
Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
pathDelegate.transform(matrixDelegate, dstDelegate);
| static void | native_transform(long nPath, long matrix)
native_transform(nPath, matrix, 0);
| public void | offset(float dx, float dy, android.graphics.Path_Delegate dst)Offset the path by (dx,dy), returning true on success
GeneralPath newPath = new GeneralPath();
PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
newPath.append(iterator, false /*connect*/);
if (dst != null) {
dst.mPath = newPath;
} else {
mPath = newPath;
}
| private void | quadTo(float x1, float y1, float x2, float y2)Add a quadratic bezier from the last point, approaching control point
(x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
this contour, the first point is automatically set to (0,0).
mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
| private void | rCubicTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3)Same as cubicTo, but the coordinates are considered relative to the
current point on this contour. If there is no previous point, then a
moveTo(0,0) is inserted automatically.
if (isEmpty()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
dx1 += mLastX;
dy1 += mLastY;
dx2 += mLastX;
dy2 += mLastY;
dx3 += mLastX;
dy3 += mLastY;
mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
| private void | rLineTo(float dx, float dy)Same as lineTo, but the coordinates are considered relative to the last
point on this contour. If there is no previous point, then a moveTo(0,0)
is inserted automatically.
if (isEmpty()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
dx += mLastX;
dy += mLastY;
mPath.lineTo(mLastX = dx, mLastY = dy);
| private void | rMoveTo(float dx, float dy)Set the beginning of the next contour relative to the last point on the
previous contour. If there is no previous contour, this is treated the
same as moveTo().
dx += mLastX;
dy += mLastY;
mPath.moveTo(mLastX = dx, mLastY = dy);
| private void | rQuadTo(float dx1, float dy1, float dx2, float dy2)Same as quadTo, but the coordinates are considered relative to the last
point on this contour. If there is no previous point, then a moveTo(0,0)
is inserted automatically.
if (isEmpty()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
dx1 += mLastX;
dy1 += mLastY;
dx2 += mLastX;
dy2 += mLastY;
mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
| public void | reset()
mPath.reset();
| private void | resetLastPointFromPath()
Point2D last = mPath.getCurrentPoint();
mLastX = (float) last.getX();
mLastY = (float) last.getY();
| private void | set(android.graphics.Path_Delegate delegate)
mPath.reset();
setFillType(delegate.mFillType);
mPath.append(delegate.mPath, false /*connect*/);
| private void | setFillType(android.graphics.Path.FillType fillType)
mFillType = fillType;
mPath.setWindingRule(getWindingRule(fillType));
| public void | setJavaShape(java.awt.Shape shape)
mPath.reset();
mPath.append(shape, false /*connect*/);
| public void | setPathIterator(java.awt.geom.PathIterator iterator)
mPath.reset();
mPath.append(iterator, false /*connect*/);
| public void | transform(Matrix_Delegate matrix, android.graphics.Path_Delegate dst)Transform the points in this path by matrix, and write the answer
into dst. If dst is null, then the the original path is modified.
if (matrix.hasPerspective()) {
assert false;
Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
"android.graphics.Path#transform() only " +
"supports affine transformations.", null, null /*data*/);
}
GeneralPath newPath = new GeneralPath();
PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
newPath.append(iterator, false /*connect*/);
if (dst != null) {
dst.mPath = newPath;
} else {
mPath = newPath;
}
|
|