1 /* 2 * Copyright (C) 2006 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 #ifndef SkPathMeasure_DEFINED 18 #define SkPathMeasure_DEFINED 19 20 #include "SkPath.h" 21 #include "SkTDArray.h" 22 23 class SkPathMeasure : SkNoncopyable { 24 public: 25 SkPathMeasure(); 26 /** Initialize the pathmeasure with the specified path. The path must remain valid 27 for the lifetime of the measure object, or until setPath() is called with 28 a different path (or null), since the measure object keeps a pointer to the 29 path object (does not copy its data). 30 */ 31 SkPathMeasure(const SkPath& path, bool forceClosed); 32 ~SkPathMeasure(); 33 34 /** Reset the pathmeasure with the specified path. The path must remain valid 35 for the lifetime of the measure object, or until setPath() is called with 36 a different path (or null), since the measure object keeps a pointer to the 37 path object (does not copy its data). 38 */ 39 void setPath(const SkPath*, bool forceClosed); 40 41 /** Return the total length of the current contour, or 0 if no path 42 is associated (e.g. resetPath(null)) 43 */ 44 SkScalar getLength(); 45 46 /** Pins distance to 0 <= distance <= getLength(), and then computes 47 the corresponding position and tangent. 48 Returns false if there is no path, or a zero-length path was specified, in which case 49 position and tangent are unchanged. 50 */ 51 bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent); 52 53 enum MatrixFlags { 54 kGetPosition_MatrixFlag = 0x01, 55 kGetTangent_MatrixFlag = 0x02, 56 kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag 57 }; 58 /** Pins distance to 0 <= distance <= getLength(), and then computes 59 the corresponding matrix (by calling getPosTan). 60 Returns false if there is no path, or a zero-length path was specified, in which case 61 matrix is unchanged. 62 */ 63 bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag); 64 /** Given a start and stop distance, return in dst the intervening segment(s). 65 If the segment is zero-length, return false, else return true. 66 startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD 67 then return false (and leave dst untouched). 68 Begin the segment with a moveTo if startWithMoveTo is true 69 */ 70 bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo); 71 72 /** Return true if the current contour is closed() 73 */ 74 bool isClosed(); 75 76 /** Move to the next contour in the path. Return true if one exists, or false if 77 we're done with the path. 78 */ 79 bool nextContour(); 80 81 #ifdef SK_DEBUG 82 void dump(); 83 #endif 84 85 private: 86 SkPath::Iter fIter; 87 const SkPath* fPath; 88 SkScalar fLength; // relative to the current contour 89 int fFirstPtIndex; // relative to the current contour 90 bool fIsClosed; // relative to the current contour 91 bool fForceClosed; 92 93 struct Segment { 94 SkScalar fDistance; // total distance up to this point 95 unsigned fPtIndex : 15; 96 unsigned fTValue : 15; 97 unsigned fType : 2; 98 99 SkScalar getScalarT() const; 100 }; 101 SkTDArray<Segment> fSegments; 102 103 static const Segment* NextSegment(const Segment*); 104 105 void buildSegments(); 106 SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance, 107 int mint, int maxt, int ptIndex); 108 SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance, 109 int mint, int maxt, int ptIndex); 110 const Segment* distanceToSegment(SkScalar distance, SkScalar* t); 111 }; 112 113 #endif 114 115