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 "../private/SkNoncopyable.h"
12 #include "../private/SkTDArray.h"
13 #include "SkContourMeasure.h"
14 #include "SkPath.h"
15 
16 class SK_API SkPathMeasure : SkNoncopyable {
17 public:
18     SkPathMeasure();
19     /** Initialize the pathmeasure with the specified path. The parts of the path that are needed
20      *  are copied, so the client is free to modify/delete the path after this call.
21      *
22      *  resScale controls the precision of the measure. values > 1 increase the
23      *  precision (and possible slow down the computation).
24      */
25     SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
26     ~SkPathMeasure();
27 
28     /** Reset the pathmeasure with the specified path. The parts of the path that are needed
29      *  are copied, so the client is free to modify/delete the path after this call..
30      */
31     void setPath(const SkPath*, bool forceClosed);
32 
33     /** Return the total length of the current contour, or 0 if no path
34         is associated (e.g. resetPath(null))
35     */
36     SkScalar getLength();
37 
38     /** Pins distance to 0 <= distance <= getLength(), and then computes
39         the corresponding position and tangent.
40         Returns false if there is no path, or a zero-length path was specified, in which case
41         position and tangent are unchanged.
42     */
43     bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
44                                          SkVector* tangent);
45 
46     enum MatrixFlags {
47         kGetPosition_MatrixFlag     = 0x01,
48         kGetTangent_MatrixFlag      = 0x02,
49         kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
50     };
51 
52     /** Pins distance to 0 <= distance <= getLength(), and then computes
53         the corresponding matrix (by calling getPosTan).
54         Returns false if there is no path, or a zero-length path was specified, in which case
55         matrix is unchanged.
56     */
57     bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
58                                   MatrixFlags flags = kGetPosAndTan_MatrixFlag);
59 
60     /** Given a start and stop distance, return in dst the intervening segment(s).
61         If the segment is zero-length, return false, else return true.
62         startD and stopD are pinned to legal values (0..getLength()). If startD > stopD
63         then return false (and leave dst untouched).
64         Begin the segment with a moveTo if startWithMoveTo is true
65     */
66     bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
67 
68     /** Return true if the current contour is closed()
69     */
70     bool isClosed();
71 
72     /** Move to the next contour in the path. Return true if one exists, or false if
73         we're done with the path.
74     */
75     bool nextContour();
76 
77 #ifdef SK_DEBUG
78     void    dump();
79 #endif
80 
81 private:
82     SkContourMeasureIter    fIter;
83     sk_sp<SkContourMeasure> fContour;
84 };
85 
86 #endif
87