1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkPathMeasure_DEFINED 9 #define SkPathMeasure_DEFINED 10 11 #include "include/core/SkContourMeasure.h" 12 #include "include/core/SkPoint.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/core/SkScalar.h" 15 #include "include/private/base/SkAPI.h" 16 #include "include/private/base/SkDebug.h" 17 18 class SkMatrix; 19 class SkPath; 20 21 class SK_API SkPathMeasure { 22 public: 23 SkPathMeasure(); 24 /** Initialize the pathmeasure with the specified path. The parts of the path that are needed 25 * are copied, so the client is free to modify/delete the path after this call. 26 * 27 * resScale controls the precision of the measure. values > 1 increase the 28 * precision (and possibly slow down the computation). 29 */ 30 SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1); 31 ~SkPathMeasure(); 32 33 SkPathMeasure(SkPathMeasure&&) = default; 34 SkPathMeasure& operator=(SkPathMeasure&&) = default; 35 36 /** Reset the pathmeasure with the specified path. The parts of the path that are needed 37 * are copied, so the client is free to modify/delete the path after this call.. 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 [[nodiscard]] 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 59 /** Pins distance to 0 <= distance <= getLength(), and then computes 60 the corresponding matrix (by calling getPosTan). 61 Returns false if there is no path, or a zero-length path was specified, in which case 62 matrix is unchanged. 63 */ 64 [[nodiscard]] bool getMatrix(SkScalar distance, SkMatrix* matrix, 65 MatrixFlags flags = kGetPosAndTan_MatrixFlag); 66 67 /** Given a start and stop distance, return in dst the intervening segment(s). 68 If the segment is zero-length, return false, else return true. 69 startD and stopD are pinned to legal values (0..getLength()). If startD > stopD 70 then return false (and leave dst untouched). 71 Begin the segment with a moveTo if startWithMoveTo is true 72 */ 73 bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo); 74 75 /** Return true if the current contour is closed() 76 */ 77 bool isClosed(); 78 79 /** Move to the next contour in the path. Return true if one exists, or false if 80 we're done with the path. 81 */ 82 bool nextContour(); 83 84 #ifdef SK_DEBUG 85 void dump(); 86 #endif 87 currentMeasure()88 const SkContourMeasure* currentMeasure() const { return fContour.get(); } 89 90 private: 91 SkContourMeasureIter fIter; 92 sk_sp<SkContourMeasure> fContour; 93 }; 94 95 #endif 96