xref: /aosp_15_r20/external/skia/include/core/SkPathMeasure.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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