1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package android.util;
16 
17 import android.compat.annotation.UnsupportedAppUsage;
18 import android.graphics.Path;
19 
20 import dalvik.annotation.optimization.FastNative;
21 
22 /**
23  * @hide
24  */
25 public class PathParser {
26     static final String LOGTAG = PathParser.class.getSimpleName();
27 
28     /**
29      * @param pathString The string representing a path, the same as "d" string in svg file.
30      * @return the generated Path object.
31      */
32     @UnsupportedAppUsage
createPathFromPathData(String pathString)33     public static Path createPathFromPathData(String pathString) {
34         if (pathString == null) {
35             throw new IllegalArgumentException("Path string can not be null.");
36         }
37         Path path = new Path();
38         nParseStringForPath(path.mNativePath, pathString, pathString.length());
39         return path;
40     }
41 
42     /**
43      * Interpret PathData as path commands and insert the commands to the given path.
44      *
45      * @param data The source PathData to be converted.
46      * @param outPath The Path object where path commands will be inserted.
47      */
createPathFromPathData(Path outPath, PathData data)48     public static void createPathFromPathData(Path outPath, PathData data) {
49         nCreatePathFromPathData(outPath.mNativePath, data.mNativePathData);
50     }
51 
52     /**
53      * @param pathDataFrom The source path represented in PathData
54      * @param pathDataTo The target path represented in PathData
55      * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
56      */
canMorph(PathData pathDataFrom, PathData pathDataTo)57     public static boolean canMorph(PathData pathDataFrom, PathData pathDataTo) {
58         return nCanMorph(pathDataFrom.mNativePathData, pathDataTo.mNativePathData);
59     }
60 
61     /**
62      * PathData class is a wrapper around the native PathData object, which contains
63      * the result of parsing a path string. Specifically, there are verbs and points
64      * associated with each verb stored in PathData. This data can then be used to
65      * generate commands to manipulate a Path.
66      */
67     public static class PathData {
68         long mNativePathData = 0;
PathData()69         public PathData() {
70             mNativePathData = nCreateEmptyPathData();
71         }
72 
PathData(PathData data)73         public PathData(PathData data) {
74             mNativePathData = nCreatePathData(data.mNativePathData);
75         }
76 
PathData(String pathString)77         public PathData(String pathString) {
78             mNativePathData = nCreatePathDataFromString(pathString, pathString.length());
79             if (mNativePathData == 0) {
80                 throw new IllegalArgumentException("Invalid pathData: " + pathString);
81             }
82         }
83 
getNativePtr()84         public long getNativePtr() {
85             return mNativePathData;
86         }
87 
88         /**
89          * Update the path data to match the source.
90          * Before calling this, make sure canMorph(target, source) is true.
91          *
92          * @param source The source path represented in PathData
93          */
setPathData(PathData source)94         public void setPathData(PathData source) {
95             nSetPathData(mNativePathData, source.mNativePathData);
96         }
97 
98         @Override
finalize()99         protected void finalize() throws Throwable {
100             if (mNativePathData != 0) {
101                 nFinalize(mNativePathData);
102                 mNativePathData = 0;
103             }
104             super.finalize();
105         }
106     }
107 
108     /**
109      * Interpolate between the <code>fromData</code> and <code>toData</code> according to the
110      * <code>fraction</code>, and put the resulting path data into <code>outData</code>.
111      *
112      * @param outData The resulting PathData of the interpolation
113      * @param fromData The start value as a PathData.
114      * @param toData The end value as a PathData
115      * @param fraction The fraction to interpolate.
116      */
interpolatePathData(PathData outData, PathData fromData, PathData toData, float fraction)117     public static boolean interpolatePathData(PathData outData, PathData fromData, PathData toData,
118             float fraction) {
119         return nInterpolatePathData(outData.mNativePathData, fromData.mNativePathData,
120                 toData.mNativePathData, fraction);
121     }
122 
123     // Native functions are defined below.
nParseStringForPath(long pathPtr, String pathString, int stringLength)124     private static native void nParseStringForPath(long pathPtr, String pathString,
125             int stringLength);
nCreatePathDataFromString(String pathString, int stringLength)126     private static native long nCreatePathDataFromString(String pathString, int stringLength);
127 
128     // ----------------- @FastNative -----------------------
129 
130     @FastNative
nCreatePathFromPathData(long outPathPtr, long pathData)131     private static native void nCreatePathFromPathData(long outPathPtr, long pathData);
132     @FastNative
nCreateEmptyPathData()133     private static native long nCreateEmptyPathData();
134     @FastNative
nCreatePathData(long nativePtr)135     private static native long nCreatePathData(long nativePtr);
136     @FastNative
nInterpolatePathData(long outDataPtr, long fromDataPtr, long toDataPtr, float fraction)137     private static native boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
138             long toDataPtr, float fraction);
139     @FastNative
nFinalize(long nativePtr)140     private static native void nFinalize(long nativePtr);
141     @FastNative
nCanMorph(long fromDataPtr, long toDataPtr)142     private static native boolean nCanMorph(long fromDataPtr, long toDataPtr);
143     @FastNative
nSetPathData(long outDataPtr, long fromDataPtr)144     private static native void nSetPathData(long outDataPtr, long fromDataPtr);
145 }
146 
147 
148