1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics; 18 19 public class PathMeasure { 20 private Path mPath; 21 22 /** 23 * Create an empty PathMeasure object. To uses this to measure the length 24 * of a path, and/or to find the position and tangent along it, call 25 * setPath. 26 * 27 * Note that once a path is associated with the measure object, it is 28 * undefined if the path is subsequently modified and the the measure object 29 * is used. If the path is modified, you must call setPath with the path. 30 */ PathMeasure()31 public PathMeasure() { 32 mPath = null; 33 native_instance = native_create(0, false); 34 } 35 36 /** 37 * Create a PathMeasure object associated with the specified path object 38 * (already created and specified). The measure object can now return the 39 * path's length, and the position and tangent of any position along the 40 * path. 41 * 42 * Note that once a path is associated with the measure object, it is 43 * undefined if the path is subsequently modified and the the measure object 44 * is used. If the path is modified, you must call setPath with the path. 45 * 46 * @param path The path that will be measured by this object 47 * @param forceClosed If true, then the path will be considered as "closed" 48 * even if its contour was not explicitly closed. 49 */ PathMeasure(Path path, boolean forceClosed)50 public PathMeasure(Path path, boolean forceClosed) { 51 // The native implementation does not copy the path, prevent it from being GC'd 52 mPath = path; 53 native_instance = native_create(path != null ? path.ni() : 0, 54 forceClosed); 55 } 56 57 /** 58 * Assign a new path, or null to have none. 59 */ setPath(Path path, boolean forceClosed)60 public void setPath(Path path, boolean forceClosed) { 61 mPath = path; 62 native_setPath(native_instance, 63 path != null ? path.ni() : 0, 64 forceClosed); 65 } 66 67 /** 68 * Return the total length of the current contour, or 0 if no path is 69 * associated with this measure object. 70 */ getLength()71 public float getLength() { 72 return native_getLength(native_instance); 73 } 74 75 /** 76 * Pins distance to 0 <= distance <= getLength(), and then computes the 77 * corresponding position and tangent. Returns false if there is no path, 78 * or a zero-length path was specified, in which case position and tangent 79 * are unchanged. 80 * 81 * @param distance The distance along the current contour to sample 82 * @param pos If not null, eturns the sampled position (x==[0], y==[1]) 83 * @param tan If not null, returns the sampled tangent (x==[0], y==[1]) 84 * @return false if there was no path associated with this measure object 85 */ getPosTan(float distance, float pos[], float tan[])86 public boolean getPosTan(float distance, float pos[], float tan[]) { 87 if (pos != null && pos.length < 2 || 88 tan != null && tan.length < 2) { 89 throw new ArrayIndexOutOfBoundsException(); 90 } 91 return native_getPosTan(native_instance, distance, pos, tan); 92 } 93 94 public static final int POSITION_MATRIX_FLAG = 0x01; // must match flags in SkPathMeasure.h 95 public static final int TANGENT_MATRIX_FLAG = 0x02; // must match flags in SkPathMeasure.h 96 97 /** 98 * Pins distance to 0 <= distance <= getLength(), and then computes the 99 * corresponding matrix. Returns false if there is no path, or a zero-length 100 * path was specified, in which case matrix is unchanged. 101 * 102 * @param distance The distance along the associated path 103 * @param matrix Allocated by the caller, this is set to the transformation 104 * associated with the position and tangent at the specified distance 105 * @param flags Specified what aspects should be returned in the matrix. 106 */ getMatrix(float distance, Matrix matrix, int flags)107 public boolean getMatrix(float distance, Matrix matrix, int flags) { 108 return native_getMatrix(native_instance, distance, matrix.native_instance, flags); 109 } 110 111 /** 112 * Given a start and stop distance, return in dst the intervening 113 * segment(s). If the segment is zero-length, return false, else return 114 * true. startD and stopD are pinned to legal values (0..getLength()). 115 * If startD <= stopD then return false (and leave dst untouched). 116 * Begin the segment with a moveTo if startWithMoveTo is true. 117 * 118 * <p>On {@link android.os.Build.VERSION_CODES#KITKAT} and earlier 119 * releases, the resulting path may not display on a hardware-accelerated 120 * Canvas. A simple workaround is to add a single operation to this path, 121 * such as <code>dst.rLineTo(0, 0)</code>.</p> 122 */ getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)123 public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) { 124 dst.isSimplePath = false; 125 return native_getSegment(native_instance, startD, stopD, dst.ni(), startWithMoveTo); 126 } 127 128 /** 129 * Return true if the current contour is closed() 130 */ isClosed()131 public boolean isClosed() { 132 return native_isClosed(native_instance); 133 } 134 135 /** 136 * Move to the next contour in the path. Return true if one exists, or 137 * false if we're done with the path. 138 */ nextContour()139 public boolean nextContour() { 140 return native_nextContour(native_instance); 141 } 142 finalize()143 protected void finalize() throws Throwable { 144 native_destroy(native_instance); 145 } 146 native_create(long native_path, boolean forceClosed)147 private static native long native_create(long native_path, boolean forceClosed); native_setPath(long native_instance, long native_path, boolean forceClosed)148 private static native void native_setPath(long native_instance, long native_path, boolean forceClosed); native_getLength(long native_instance)149 private static native float native_getLength(long native_instance); native_getPosTan(long native_instance, float distance, float pos[], float tan[])150 private static native boolean native_getPosTan(long native_instance, float distance, float pos[], float tan[]); native_getMatrix(long native_instance, float distance, long native_matrix, int flags)151 private static native boolean native_getMatrix(long native_instance, float distance, long native_matrix, int flags); native_getSegment(long native_instance, float startD, float stopD, long native_path, boolean startWithMoveTo)152 private static native boolean native_getSegment(long native_instance, float startD, float stopD, long native_path, boolean startWithMoveTo); native_isClosed(long native_instance)153 private static native boolean native_isClosed(long native_instance); native_nextContour(long native_instance)154 private static native boolean native_nextContour(long native_instance); native_destroy(long native_instance)155 private static native void native_destroy(long native_instance); 156 157 /* package */private final long native_instance; 158 } 159 160