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