diff options
| -rw-r--r-- | core/jni/android/graphics/Path.cpp | 7 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/graphics/PathOffsetTest.java | 91 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Path.java | 44 |
3 files changed, 124 insertions, 18 deletions
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index 2998c99a273e..ab393f2bc1f1 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -232,12 +232,6 @@ public: obj->addPath(*src, *matrix); } - static void offset__FFPath(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy, jlong dstHandle) { - SkPath* obj = reinterpret_cast<SkPath*>(objHandle); - SkPath* dst = reinterpret_cast<SkPath*>(dstHandle); - obj->offset(dx, dy, dst); - } - static void offset__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); obj->offset(dx, dy); @@ -508,7 +502,6 @@ static const JNINativeMethod methods[] = { {"native_addPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF}, {"native_addPath","(JJ)V", (void*) SkPathGlue::addPath__Path}, {"native_addPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix}, - {"native_offset","(JFFJ)V", (void*) SkPathGlue::offset__FFPath}, {"native_offset","(JFF)V", (void*) SkPathGlue::offset__FF}, {"native_setLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint}, {"native_transform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath}, diff --git a/core/tests/coretests/src/android/graphics/PathOffsetTest.java b/core/tests/coretests/src/android/graphics/PathOffsetTest.java new file mode 100644 index 000000000000..950f8731bae1 --- /dev/null +++ b/core/tests/coretests/src/android/graphics/PathOffsetTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + + +import android.graphics.Bitmap.Config; +import android.graphics.Path.Direction; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class PathOffsetTest { + + private static final int SQUARE = 10; + private static final int WIDTH = 100; + private static final int HEIGHT = 100; + private static final int START_X = 10; + private static final int START_Y = 20; + private static final int OFFSET_X = 30; + private static final int OFFSET_Y = 40; + + @Test + @SmallTest + public void testPathOffset() { + Path actualPath = new Path(); + actualPath.addRect(START_X, START_Y, START_X + SQUARE, START_Y + SQUARE, Direction.CW); + assertTrue(actualPath.isSimplePath); + actualPath.offset(OFFSET_X, OFFSET_Y); + assertTrue(actualPath.isSimplePath); + + Path expectedPath = new Path(); + expectedPath.addRect(START_X + OFFSET_X, START_Y + OFFSET_Y, START_X + OFFSET_X + SQUARE, + START_Y + OFFSET_Y + SQUARE, Direction.CW); + + assertPaths(actualPath, expectedPath); + } + + @Test + @SmallTest + public void testPathOffsetWithDestination() { + Path initialPath = new Path(); + initialPath.addRect(START_X, START_Y, START_X + SQUARE, START_Y + SQUARE, Direction.CW); + Path actualPath = new Path(); + assertTrue(initialPath.isSimplePath); + assertTrue(actualPath.isSimplePath); + initialPath.offset(OFFSET_X, OFFSET_Y, actualPath); + assertTrue(actualPath.isSimplePath); + + Path expectedPath = new Path(); + expectedPath.addRect(START_X + OFFSET_X, START_Y + OFFSET_Y, START_X + OFFSET_X + SQUARE, + START_Y + OFFSET_Y + SQUARE, Direction.CW); + + assertPaths(actualPath, expectedPath); + } + + private static void assertPaths(Path actual, Path expected) { + Bitmap actualBitmap = drawAndGetBitmap(actual); + Bitmap expectedBitmap = drawAndGetBitmap(expected); + assertTrue(actualBitmap.sameAs(expectedBitmap)); + } + + private static Bitmap drawAndGetBitmap(Path path) { + Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Config.ARGB_8888); + bitmap.eraseColor(Color.BLACK); + Paint paint = new Paint(); + paint.setColor(Color.RED); + Canvas canvas = new Canvas(bitmap); + canvas.drawPath(path, paint); + return bitmap; + } + +} diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index da3deffdef40..de391af5d4ce 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -16,6 +16,9 @@ package android.graphics; +import android.annotation.NonNull; +import android.annotation.Nullable; + /** * The Path class encapsulates compound (multiple contour) geometric paths * consisting of straight line segments, quadratic curves, and cubic curves. @@ -91,10 +94,22 @@ public class Path { /** Replace the contents of this with the contents of src. */ - public void set(Path src) { - if (this != src) { - isSimplePath = src.isSimplePath; - native_set(mNativePath, src.mNativePath); + public void set(@NonNull Path src) { + if (this == src) { + return; + } + isSimplePath = src.isSimplePath; + native_set(mNativePath, src.mNativePath); + if (!isSimplePath) { + return; + } + + if (rects != null && src.rects != null) { + rects.set(src.rects); + } else if (rects != null && src.rects == null) { + rects.setEmpty(); + } else if (src.rects != null) { + rects = new Region(src.rects); } } @@ -685,13 +700,13 @@ public class Path { * @param dst The translated path is written here. If this is null, then * the original path is modified. */ - public void offset(float dx, float dy, Path dst) { - long dstNative = 0; + public void offset(float dx, float dy, @Nullable Path dst) { if (dst != null) { - dstNative = dst.mNativePath; - dst.isSimplePath = false; + dst.set(this); + } else { + dst = this; } - native_offset(mNativePath, dx, dy, dstNative); + dst.offset(dx, dy); } /** @@ -701,7 +716,15 @@ public class Path { * @param dy The amount in the Y direction to offset the entire path */ public void offset(float dx, float dy) { - isSimplePath = false; + if (isSimplePath && rects == null) { + // nothing to offset + return; + } + if (isSimplePath && dx == Math.rint(dx) && dy == Math.rint(dy)) { + rects.translate((int) dx, (int) dy); + } else { + isSimplePath = false; + } native_offset(mNativePath, dx, dy); } @@ -823,7 +846,6 @@ public class Path { private static native void native_addPath(long nPath, long src, float dx, float dy); private static native void native_addPath(long nPath, long src); private static native void native_addPath(long nPath, long src, long matrix); - private static native void native_offset(long nPath, float dx, float dy, long dst_path); private static native void native_offset(long nPath, float dx, float dy); private static native void native_setLastPoint(long nPath, float dx, float dy); private static native void native_transform(long nPath, long matrix, long dst_path); |