• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkPathMeasure_DEFINED
18 #define SkPathMeasure_DEFINED
19 
20 #include "SkPath.h"
21 #include "SkTDArray.h"
22 
23 class SkPathMeasure : SkNoncopyable {
24 public:
25     SkPathMeasure();
26     /** Initialize the pathmeasure with the specified path. The path must remain valid
27         for the lifetime of the measure object, or until setPath() is called with
28         a different path (or null), since the measure object keeps a pointer to the
29         path object (does not copy its data).
30     */
31     SkPathMeasure(const SkPath& path, bool forceClosed);
32     ~SkPathMeasure();
33 
34     /** Reset the pathmeasure with the specified path. The path must remain valid
35         for the lifetime of the measure object, or until setPath() is called with
36         a different path (or null), since the measure object keeps a pointer to the
37         path object (does not copy its data).
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     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     /** Pins distance to 0 <= distance <= getLength(), and then computes
59         the corresponding matrix (by calling getPosTan).
60         Returns false if there is no path, or a zero-length path was specified, in which case
61         matrix is unchanged.
62     */
63     bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
64     /** Given a start and stop distance, return in dst the intervening segment(s).
65         If the segment is zero-length, return false, else return true.
66         startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
67         then return false (and leave dst untouched).
68         Begin the segment with a moveTo if startWithMoveTo is true
69     */
70     bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
71 
72     /** Return true if the current contour is closed()
73     */
74     bool isClosed();
75 
76     /** Move to the next contour in the path. Return true if one exists, or false if
77         we're done with the path.
78     */
79     bool nextContour();
80 
81 #ifdef SK_DEBUG
82     void    dump();
83 #endif
84 
85 private:
86     SkPath::Iter    fIter;
87     const SkPath*   fPath;
88     SkScalar        fLength;            // relative to the current contour
89     int             fFirstPtIndex;      // relative to the current contour
90     bool            fIsClosed;          // relative to the current contour
91     bool            fForceClosed;
92 
93     struct Segment {
94         SkScalar    fDistance;  // total distance up to this point
95         unsigned    fPtIndex : 15;
96         unsigned    fTValue : 15;
97         unsigned    fType : 2;
98 
99         SkScalar getScalarT() const;
100     };
101     SkTDArray<Segment>  fSegments;
102 
103     static const Segment* NextSegment(const Segment*);
104 
105     void     buildSegments();
106     SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
107                                 int mint, int maxt, int ptIndex);
108     SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
109                                 int mint, int maxt, int ptIndex);
110     const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
111 };
112 
113 #endif
114 
115