1cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu/*
2cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * Copyright (C) 2015 The Android Open Source Project
3cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu *
4cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * Licensed under the Apache License, Version 2.0 (the "License");
5cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * you may not use this file except in compliance with the License.
6cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * You may obtain a copy of the License at
7cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu *
8cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu *      http://www.apache.org/licenses/LICENSE-2.0
9cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu *
10cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * Unless required by applicable law or agreed to in writing, software
11cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * distributed under the License is distributed on an "AS IS" BASIS,
12cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * See the License for the specific language governing permissions and
14cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu * limitations under the License.
15cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu */
16cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
17cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu#include "jni.h"
180a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu#include "GraphicsJNI.h"
19cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
20cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu#include <PathParser.h>
21cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu#include <SkPath.h>
22804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu#include <utils/VectorDrawableUtils.h>
23cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
241e67f08963cc245660049b6a588483a148955e08Doris Liu#include <android/log.h>
25cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu#include "core_jni_helpers.h"
26cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
27cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liunamespace android {
28cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
29804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liuusing namespace uirenderer;
30804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
310a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liustatic void parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
32cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu        jint strLength) {
33cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu    const char* pathString = env->GetStringUTFChars(inputPathStr, NULL);
34cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu    SkPath* skPath = reinterpret_cast<SkPath*>(skPathHandle);
351e67f08963cc245660049b6a588483a148955e08Doris Liu
36804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathParser::ParseResult result;
37b35da390601e3c24e777d72daacd8dbeb4d1d9c4Doris Liu    PathParser::parseAsciiStringForSkPath(skPath, &result, pathString, strLength);
38cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu    env->ReleaseStringUTFChars(inputPathStr, pathString);
391e67f08963cc245660049b6a588483a148955e08Doris Liu    if (result.failureOccurred) {
400a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu        doThrowIAE(env, result.failureMessage.c_str());
411e67f08963cc245660049b6a588483a148955e08Doris Liu    }
42cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu}
43cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
44804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic long createEmptyPathData(JNIEnv*, jobject) {
45804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* pathData = new PathData();
46804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    return reinterpret_cast<jlong>(pathData);
47804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
48804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
49804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic long createPathData(JNIEnv*, jobject, jlong pathDataPtr) {
50804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* pathData = reinterpret_cast<PathData*>(pathDataPtr);
51804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* newPathData = new PathData(*pathData);
52804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    return reinterpret_cast<jlong>(newPathData);
53804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
54804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
55804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic long createPathDataFromStringPath(JNIEnv* env, jobject, jstring inputStr, jint strLength) {
56804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    const char* pathString = env->GetStringUTFChars(inputStr, NULL);
57804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* pathData = new PathData();
58804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathParser::ParseResult result;
59b35da390601e3c24e777d72daacd8dbeb4d1d9c4Doris Liu    PathParser::getPathDataFromAsciiString(pathData, &result, pathString, strLength);
60804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    env->ReleaseStringUTFChars(inputStr, pathString);
61804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    if (!result.failureOccurred) {
62804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu        return reinterpret_cast<jlong>(pathData);
63804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    } else {
64804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu        delete pathData;
650a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu        doThrowIAE(env, result.failureMessage.c_str());
66804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu        return NULL;
67804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    }
68804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
69804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
70804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic bool interpolatePathData(JNIEnv*, jobject, jlong outPathDataPtr, jlong fromPathDataPtr,
71804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu        jlong toPathDataPtr, jfloat fraction) {
72804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* outPathData = reinterpret_cast<PathData*>(outPathDataPtr);
73804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* fromPathData = reinterpret_cast<PathData*>(fromPathDataPtr);
74804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* toPathData = reinterpret_cast<PathData*>(toPathDataPtr);
75804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    return VectorDrawableUtils::interpolatePathData(outPathData, *fromPathData,
76804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu            *toPathData, fraction);
77804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
78804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
79804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic void deletePathData(JNIEnv*, jobject, jlong pathDataHandle) {
80804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* pathData = reinterpret_cast<PathData*>(pathDataHandle);
81804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    delete pathData;
82804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
83804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
84804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic bool canMorphPathData(JNIEnv*, jobject, jlong fromPathDataPtr, jlong toPathDataPtr) {
85804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* fromPathData = reinterpret_cast<PathData*>(fromPathDataPtr);
86804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* toPathData = reinterpret_cast<PathData*>(toPathDataPtr);
87804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    return VectorDrawableUtils::canMorph(*fromPathData, *toPathData);
88804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
89804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
90804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic void setPathData(JNIEnv*, jobject, jlong outPathDataPtr, jlong fromPathDataPtr) {
91804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* fromPathData = reinterpret_cast<PathData*>(fromPathDataPtr);
92804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* outPathData = reinterpret_cast<PathData*>(outPathDataPtr);
93804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    *outPathData = *fromPathData;
94804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
95804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
96804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liustatic void setSkPathFromPathData(JNIEnv*, jobject, jlong outPathPtr, jlong pathDataPtr) {
97804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    PathData* pathData = reinterpret_cast<PathData*>(pathDataPtr);
98804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    SkPath* skPath = reinterpret_cast<SkPath*>(outPathPtr);
99804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    VectorDrawableUtils::verbsToPath(skPath, *pathData);
100804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu}
101804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu
102cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liustatic const JNINativeMethod gMethods[] = {
1030a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu    {"nParseStringForPath", "(JLjava/lang/String;I)V", (void*)parseStringForPath},
104804618d0863a5d8ad1b08a846bd5319be864a1cbDoris Liu    {"nCreatePathDataFromString", "(Ljava/lang/String;I)J", (void*)createPathDataFromStringPath},
10532995223a85a3b774789091d97987dfacc1e9ef3John Reck
10632995223a85a3b774789091d97987dfacc1e9ef3John Reck    // ---------------- @FastNative -----------------
10732995223a85a3b774789091d97987dfacc1e9ef3John Reck
10832995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nCreateEmptyPathData", "()J", (void*)createEmptyPathData},
10932995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nCreatePathData", "(J)J", (void*)createPathData},
11032995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nInterpolatePathData", "(JJJF)Z", (void*)interpolatePathData},
11132995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nFinalize", "(J)V", (void*)deletePathData},
11232995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nCanMorph", "(JJ)Z", (void*)canMorphPathData},
11332995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nSetPathData", "(JJ)V", (void*)setPathData},
11432995223a85a3b774789091d97987dfacc1e9ef3John Reck    {"nCreatePathFromPathData", "(JJ)V", (void*)setSkPathFromPathData},
115cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu};
116cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu
117cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liuint register_android_util_PathParser(JNIEnv* env) {
118cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu    return RegisterMethodsOrDie(env, "android/util/PathParser", gMethods, NELEM(gMethods));
119cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu}
120cdd23f9d45ea2974c3f295754b89f5462bdd2c0dDoris Liu};
121