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