Poor implementation of Path.approximate()
Include a very poor implementation of Path.approximate() in LayoutLib that only returns the first and last coordinate of the path. This avoids crashing the rendering when certain assumptions are made on the value returned from the method. Also change the error to a warning. Change-Id: I9241dec734d4df90a9eebd1e6de8b3e443eee3c8
This commit is contained in:
@ -21,6 +21,7 @@ import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.graphics.Path.Direction;
|
||||
import android.graphics.Path.FillType;
|
||||
|
||||
@ -30,10 +31,12 @@ import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.Path
|
||||
@ -56,7 +59,7 @@ public final class Path_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
private FillType mFillType = FillType.WINDING;
|
||||
private GeneralPath mPath = new GeneralPath();
|
||||
private Path2D mPath = new Path2D.Double();
|
||||
|
||||
private float mLastX = 0;
|
||||
private float mLastY = 0;
|
||||
@ -486,8 +489,54 @@ public final class Path_Delegate {
|
||||
|
||||
@LayoutlibDelegate
|
||||
/*package*/ static float[] native_approximate(long nPath, float error) {
|
||||
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null);
|
||||
return new float[0];
|
||||
Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not fully supported",
|
||||
null);
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
return null;
|
||||
}
|
||||
PathIterator pathIterator = pathDelegate.mPath.getPathIterator(null);
|
||||
float[] tmp = new float[6];
|
||||
float[] coords = new float[6];
|
||||
boolean isFirstPoint = true;
|
||||
while (!pathIterator.isDone()) {
|
||||
int type = pathIterator.currentSegment(tmp);
|
||||
switch (type) {
|
||||
case PathIterator.SEG_MOVETO:
|
||||
case PathIterator.SEG_LINETO:
|
||||
store(coords, tmp, 1, isFirstPoint);
|
||||
break;
|
||||
case PathIterator.SEG_QUADTO:
|
||||
store(coords, tmp, 2, isFirstPoint);
|
||||
break;
|
||||
case PathIterator.SEG_CUBICTO:
|
||||
store(coords, tmp, 3, isFirstPoint);
|
||||
break;
|
||||
case PathIterator.SEG_CLOSE:
|
||||
// No points returned.
|
||||
}
|
||||
isFirstPoint = false;
|
||||
pathIterator.next();
|
||||
}
|
||||
if (isFirstPoint) {
|
||||
// No points found
|
||||
return new float[0];
|
||||
} else {
|
||||
return coords;
|
||||
}
|
||||
}
|
||||
|
||||
private static void store(float[] src, float[] dst, int count, boolean isFirst) {
|
||||
if (isFirst) {
|
||||
dst[0] = 0;
|
||||
dst[1] = src[0];
|
||||
dst[2] = src[1];
|
||||
}
|
||||
if (count > 1 || !isFirst) {
|
||||
dst[3] = 1;
|
||||
dst[4] = src[2 * count];
|
||||
dst[5] = src[2 * count + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Private helper methods ----
|
||||
@ -522,6 +571,7 @@ public final class Path_Delegate {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static Direction getDirection(int direction) {
|
||||
for (Direction d : Direction.values()) {
|
||||
if (direction == d.nativeInt) {
|
||||
|
Reference in New Issue
Block a user