• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
110