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
15package android.util;
16
17import android.graphics.Path;
18
19import dalvik.annotation.optimization.FastNative;
20
21/**
22 * @hide
23 */
24public class PathParser {
25    static final String LOGTAG = PathParser.class.getSimpleName();
26
27    /**
28     * @param pathString The string representing a path, the same as "d" string in svg file.
29     * @return the generated Path object.
30     */
31    public static Path createPathFromPathData(String pathString) {
32        if (pathString == null) {
33            throw new IllegalArgumentException("Path string can not be null.");
34        }
35        Path path = new Path();
36        nParseStringForPath(path.mNativePath, pathString, pathString.length());
37        return path;
38    }
39
40    /**
41     * Interpret PathData as path commands and insert the commands to the given path.
42     *
43     * @param data The source PathData to be converted.
44     * @param outPath The Path object where path commands will be inserted.
45     */
46    public static void createPathFromPathData(Path outPath, PathData data) {
47        nCreatePathFromPathData(outPath.mNativePath, data.mNativePathData);
48    }
49
50    /**
51     * @param pathDataFrom The source path represented in PathData
52     * @param pathDataTo The target path represented in PathData
53     * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
54     */
55    public static boolean canMorph(PathData pathDataFrom, PathData pathDataTo) {
56        return nCanMorph(pathDataFrom.mNativePathData, pathDataTo.mNativePathData);
57    }
58
59    /**
60     * PathData class is a wrapper around the native PathData object, which contains
61     * the result of parsing a path string. Specifically, there are verbs and points
62     * associated with each verb stored in PathData. This data can then be used to
63     * generate commands to manipulate a Path.
64     */
65    public static class PathData {
66        long mNativePathData = 0;
67        public PathData() {
68            mNativePathData = nCreateEmptyPathData();
69        }
70
71        public PathData(PathData data) {
72            mNativePathData = nCreatePathData(data.mNativePathData);
73        }
74
75        public PathData(String pathString) {
76            mNativePathData = nCreatePathDataFromString(pathString, pathString.length());
77            if (mNativePathData == 0) {
78                throw new IllegalArgumentException("Invalid pathData: " + pathString);
79            }
80        }
81
82        public long getNativePtr() {
83            return mNativePathData;
84        }
85
86        /**
87         * Update the path data to match the source.
88         * Before calling this, make sure canMorph(target, source) is true.
89         *
90         * @param source The source path represented in PathData
91         */
92        public void setPathData(PathData source) {
93            nSetPathData(mNativePathData, source.mNativePathData);
94        }
95
96        @Override
97        protected void finalize() throws Throwable {
98            if (mNativePathData != 0) {
99                nFinalize(mNativePathData);
100                mNativePathData = 0;
101            }
102            super.finalize();
103        }
104    }
105
106    /**
107     * Interpolate between the <code>fromData</code> and <code>toData</code> according to the
108     * <code>fraction</code>, and put the resulting path data into <code>outData</code>.
109     *
110     * @param outData The resulting PathData of the interpolation
111     * @param fromData The start value as a PathData.
112     * @param toData The end value as a PathData
113     * @param fraction The fraction to interpolate.
114     */
115    public static boolean interpolatePathData(PathData outData, PathData fromData, PathData toData,
116            float fraction) {
117        return nInterpolatePathData(outData.mNativePathData, fromData.mNativePathData,
118                toData.mNativePathData, fraction);
119    }
120
121    // Native functions are defined below.
122    private static native void nParseStringForPath(long pathPtr, String pathString,
123            int stringLength);
124    private static native long nCreatePathDataFromString(String pathString, int stringLength);
125
126    // ----------------- @FastNative -----------------------
127
128    @FastNative
129    private static native void nCreatePathFromPathData(long outPathPtr, long pathData);
130    @FastNative
131    private static native long nCreateEmptyPathData();
132    @FastNative
133    private static native long nCreatePathData(long nativePtr);
134    @FastNative
135    private static native boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
136            long toDataPtr, float fraction);
137    @FastNative
138    private static native void nFinalize(long nativePtr);
139    @FastNative
140    private static native boolean nCanMorph(long fromDataPtr, long toDataPtr);
141    @FastNative
142    private static native void nSetPathData(long outDataPtr, long fromDataPtr);
143}
144
145
146