diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index 776398fbb094e..34d09859e2b4f 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -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) {