blob: acf893e9544c46e22c4644d4b1fe5d3ce4ace6d5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* libs/android_runtime/android/graphics/PathMeasure.cpp
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018#include "GraphicsJNI.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019
20#include "SkPathMeasure.h"
21
22/* We declare an explicit pair, so that we don't have to rely on the java
23 client to be sure not to edit the path while we have an active measure
24 object associated with it.
25
26 This costs us the copy of the path, for the sake of not allowing a bad
27 java client to randomly crash (since we can't detect the case where the
28 native path has been modified).
29
30 The C side does have this risk, but it chooses for speed over safety. If it
31 later changes this, and is internally safe from changes to the path, then
32 we can remove this explicit copy from our JNI code.
33
34 Note that we do not have a reference on the java side to the java path.
35 Were we to not need the native copy here, we would want to add a java
36 reference, so that the java path would not get GD'd while the measure object
37 was still alive.
38*/
39struct PathMeasurePair {
40 PathMeasurePair() {}
41 PathMeasurePair(const SkPath& path, bool forceClosed)
42 : fPath(path), fMeasure(fPath, forceClosed) {}
43
44 SkPath fPath; // copy of the user's path
45 SkPathMeasure fMeasure; // this guy points to fPath
46};
47
48namespace android {
49
50class SkPathMeasureGlue {
51public:
52
Ashok Bhat0c10cc62014-01-10 18:38:39 +000053 static jlong create(JNIEnv* env, jobject clazz, jlong pathHandle,
54 jboolean forceClosedHandle) {
55 const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
56 bool forceClosed = (forceClosedHandle == JNI_TRUE);
57 PathMeasurePair* pair;
58 if(path)
59 pair = new PathMeasurePair(*path, forceClosed);
60 else
61 pair = new PathMeasurePair;
62 return reinterpret_cast<jlong>(pair);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +000064
65 static void setPath(JNIEnv* env, jobject clazz, jlong pairHandle,
66 jlong pathHandle, jboolean forceClosedHandle) {
67 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
68 const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
69 bool forceClosed = (forceClosedHandle == JNI_TRUE);
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 if (NULL == path) {
72 pair->fPath.reset();
73 } else {
74 pair->fPath = *path;
75 }
76 pair->fMeasure.setPath(&pair->fPath, forceClosed);
77 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +000078
79 static jfloat getLength(JNIEnv* env, jobject clazz, jlong pairHandle) {
80 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
81 return static_cast<jfloat>(SkScalarToFloat(pair->fMeasure.getLength()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +000083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 static void convertTwoElemFloatArray(JNIEnv* env, jfloatArray array, const SkScalar src[2]) {
85 AutoJavaFloatArray autoArray(env, array, 2);
86 jfloat* ptr = autoArray.ptr();
87 ptr[0] = SkScalarToFloat(src[0]);
88 ptr[1] = SkScalarToFloat(src[1]);
89 }
90
Ashok Bhat0c10cc62014-01-10 18:38:39 +000091 static jboolean getPosTan(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat dist, jfloatArray pos, jfloatArray tan) {
92 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 SkScalar tmpPos[2], tmpTan[2];
94 SkScalar* posPtr = pos ? tmpPos : NULL;
95 SkScalar* tanPtr = tan ? tmpTan : NULL;
96
Leon Scroggins III2e0103e2014-04-04 17:05:24 -040097 if (!pair->fMeasure.getPosTan(dist, (SkPoint*)posPtr, (SkVector*)tanPtr)) {
Ashok Bhat0c10cc62014-01-10 18:38:39 +000098 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 }
100
101 if (pos) {
102 convertTwoElemFloatArray(env, pos, tmpPos);
103 }
104 if (tan) {
105 convertTwoElemFloatArray(env, tan, tmpTan);
106 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000107 return JNI_TRUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000109
110 static jboolean getMatrix(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat dist,
111 jlong matrixHandle, jint flags) {
112 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
113 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400114 bool result = pair->fMeasure.getMatrix(dist, matrix, (SkPathMeasure::MatrixFlags)flags);
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000115 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000117
118 static jboolean getSegment(JNIEnv* env, jobject clazz, jlong pairHandle, jfloat startF,
119 jfloat stopF, jlong dstHandle, jboolean startWithMoveTo) {
120 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
121 SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400122 bool result = pair->fMeasure.getSegment(startF, stopF, dst, startWithMoveTo);
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000123 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000125
126 static jboolean isClosed(JNIEnv* env, jobject clazz, jlong pairHandle) {
127 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
128 bool result = pair->fMeasure.isClosed();
129 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000131
132 static jboolean nextContour(JNIEnv* env, jobject clazz, jlong pairHandle) {
133 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
134 bool result = pair->fMeasure.nextContour();
135 return result ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 }
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000137
138 static void destroy(JNIEnv* env, jobject clazz, jlong pairHandle) {
139 PathMeasurePair* pair = reinterpret_cast<PathMeasurePair*>(pairHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 delete pair;
141 }
142};
143
Daniel Micay76f6a862015-09-19 17:31:01 -0400144static const JNINativeMethod methods[] = {
Ashok Bhat0c10cc62014-01-10 18:38:39 +0000145 {"native_create", "(JZ)J", (void*) SkPathMeasureGlue::create },
146 {"native_setPath", "(JJZ)V", (void*) SkPathMeasureGlue::setPath },
147 {"native_getLength", "(J)F", (void*) SkPathMeasureGlue::getLength },
148 {"native_getPosTan", "(JF[F[F)Z", (void*) SkPathMeasureGlue::getPosTan },
149 {"native_getMatrix", "(JFJI)Z", (void*) SkPathMeasureGlue::getMatrix },
150 {"native_getSegment", "(JFFJZ)Z", (void*) SkPathMeasureGlue::getSegment },
151 {"native_isClosed", "(J)Z", (void*) SkPathMeasureGlue::isClosed },
152 {"native_nextContour", "(J)Z", (void*) SkPathMeasureGlue::nextContour },
153 {"native_destroy", "(J)V", (void*) SkPathMeasureGlue::destroy }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154};
155
156int register_android_graphics_PathMeasure(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800157 return RegisterMethodsOrDie(env, "android/graphics/PathMeasure", methods, NELEM(methods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158}
159
160}