OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkPathOpsCubic_DEFINED | 8 #ifndef SkPathOpsCubic_DEFINED |
9 #define SkPathOpsCubic_DEFINED | 9 #define SkPathOpsCubic_DEFINED |
10 | 10 |
11 #include "SkPath.h" | 11 #include "SkPath.h" |
12 #include "SkPathOpsPoint.h" | 12 #include "SkPathOpsPoint.h" |
13 | 13 |
14 struct SkDCubicPair { | 14 struct SkDCubicPair { |
15 const SkDCubic& first() const { return (const SkDCubic&) pts[0]; } | 15 const SkDCubic& first() const { return (const SkDCubic&) pts[0]; } |
16 const SkDCubic& second() const { return (const SkDCubic&) pts[3]; } | 16 const SkDCubic& second() const { return (const SkDCubic&) pts[3]; } |
17 SkDPoint pts[7]; | 17 SkDPoint pts[7]; |
18 }; | 18 }; |
19 | 19 |
20 struct SkDCubic { | 20 struct SkDCubic { |
21 static const int kPointCount = 4; | 21 static const int kPointCount = 4; |
22 static const int kPointLast = kPointCount - 1; | 22 static const int kPointLast = kPointCount - 1; |
23 static const int kMaxIntersections = 9; | 23 static const int kMaxIntersections = 9; |
24 | 24 |
25 enum SearchAxis { | 25 enum SearchAxis { |
26 kXAxis, | 26 kXAxis, |
27 kYAxis | 27 kYAxis |
28 }; | 28 }; |
29 | 29 |
| 30 enum CubicType { |
| 31 kUnsplit_SkDCubicType, |
| 32 kSplitAtLoop_SkDCubicType, |
| 33 kSplitAtInflection_SkDCubicType, |
| 34 kSplitAtMaxCurvature_SkDCubicType, |
| 35 }; |
| 36 |
30 bool collapsed() const { | 37 bool collapsed() const { |
31 return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual
(fPts[2]) | 38 return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual
(fPts[2]) |
32 && fPts[0].approximatelyEqual(fPts[3]); | 39 && fPts[0].approximatelyEqual(fPts[3]); |
33 } | 40 } |
34 | 41 |
35 bool controlsInside() const { | 42 bool controlsInside() const { |
36 SkDVector v01 = fPts[0] - fPts[1]; | 43 SkDVector v01 = fPts[0] - fPts[1]; |
37 SkDVector v02 = fPts[0] - fPts[2]; | 44 SkDVector v02 = fPts[0] - fPts[2]; |
38 SkDVector v03 = fPts[0] - fPts[3]; | 45 SkDVector v03 = fPts[0] - fPts[3]; |
39 SkDVector v13 = fPts[1] - fPts[3]; | 46 SkDVector v13 = fPts[1] - fPts[3]; |
40 SkDVector v23 = fPts[2] - fPts[3]; | 47 SkDVector v23 = fPts[2] - fPts[3]; |
41 return v03.dot(v01) > 0 && v03.dot(v02) > 0 && v03.dot(v13) > 0 && v03.d
ot(v23) > 0; | 48 return v03.dot(v01) > 0 && v03.dot(v02) > 0 && v03.dot(v13) > 0 && v03.d
ot(v23) > 0; |
42 } | 49 } |
43 | 50 |
44 static bool IsCubic() { return true; } | 51 static bool IsCubic() { return true; } |
45 | 52 |
46 const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount
); return fPts[n]; } | 53 const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount
); return fPts[n]; } |
47 SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fP
ts[n]; } | 54 SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fP
ts[n]; } |
48 | 55 |
49 void align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const; | 56 void align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const; |
50 double binarySearch(double min, double max, double axisIntercept, SearchAxis
xAxis) const; | 57 double binarySearch(double min, double max, double axisIntercept, SearchAxis
xAxis) const; |
51 double calcPrecision() const; | 58 double calcPrecision() const; |
52 SkDCubicPair chopAt(double t) const; | 59 SkDCubicPair chopAt(double t) const; |
53 bool clockwise() const; | 60 bool clockwise(bool* swap) const; |
| 61 static bool Clockwise(const SkPoint* pts, double startT, double endT, bool*
swap); |
54 static void Coefficients(const double* cubic, double* A, double* B, double*
C, double* D); | 62 static void Coefficients(const double* cubic, double* A, double* B, double*
C, double* D); |
55 static bool ComplexBreak(const SkPoint pts[4], SkScalar* t); | 63 static bool ComplexBreak(const SkPoint pts[4], SkScalar* t, CubicType* cubic
Type); |
56 int convexHull(char order[kPointCount]) const; | 64 int convexHull(char order[kPointCount]) const; |
57 | 65 |
58 void debugInit() { | 66 void debugInit() { |
59 sk_bzero(fPts, sizeof(fPts)); | 67 sk_bzero(fPts, sizeof(fPts)); |
60 } | 68 } |
61 | 69 |
62 void dump() const; // callable from the debugger when the implementation co
de is linked in | 70 void dump() const; // callable from the debugger when the implementation co
de is linked in |
63 void dumpID(int id) const; | 71 void dumpID(int id) const; |
64 void dumpInner() const; | 72 void dumpInner() const; |
65 SkDVector dxdyAtT(double t) const; | 73 SkDVector dxdyAtT(double t) const; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 114 |
107 void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, S
kDPoint p[2]) const; | 115 void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, S
kDPoint p[2]) const; |
108 | 116 |
109 static void SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, con
st SkDPoint& d, double t1, | 117 static void SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, con
st SkDPoint& d, double t1, |
110 double t2, SkDPoint p[2]) { | 118 double t2, SkDPoint p[2]) { |
111 SkDCubic cubic; | 119 SkDCubic cubic; |
112 cubic.set(pts); | 120 cubic.set(pts); |
113 cubic.subDivide(a, d, t1, t2, p); | 121 cubic.subDivide(a, d, t1, t2, p); |
114 } | 122 } |
115 | 123 |
116 SkDPoint top(double startT, double endT) const; | 124 SkDPoint top(double startT, double endT, double* topT) const; |
117 SkDQuad toQuad() const; | 125 SkDQuad toQuad() const; |
118 | 126 |
119 static const int gPrecisionUnit; | 127 static const int gPrecisionUnit; |
120 | 128 |
121 SkDPoint fPts[kPointCount]; | 129 SkDPoint fPts[kPointCount]; |
122 }; | 130 }; |
123 | 131 |
124 /* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask | 132 /* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask |
125 that computes the other two. Note that: | 133 that computes the other two. Note that: |
126 | 134 |
127 one ^ two == 3 for (0, 3), (1, 2) | 135 one ^ two == 3 for (0, 3), (1, 2) |
128 one ^ two < 3 for (0, 1), (0, 2), (1, 3), (2, 3) | 136 one ^ two < 3 for (0, 1), (0, 2), (1, 3), (2, 3) |
129 3 - (one ^ two) is either 0, 1, or 2 | 137 3 - (one ^ two) is either 0, 1, or 2 |
130 1 >> (3 - (one ^ two)) is either 0 or 1 | 138 1 >> (3 - (one ^ two)) is either 0 or 1 |
131 thus: | 139 thus: |
132 returned == 2 for (0, 3), (1, 2) | 140 returned == 2 for (0, 3), (1, 2) |
133 returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3) | 141 returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3) |
134 given that: | 142 given that: |
135 (0, 3) ^ 2 -> (2, 1) (1, 2) ^ 2 -> (3, 0) | 143 (0, 3) ^ 2 -> (2, 1) (1, 2) ^ 2 -> (3, 0) |
136 (0, 1) ^ 3 -> (3, 2) (0, 2) ^ 3 -> (3, 1) (1, 3) ^ 3 -> (2, 0) (2, 3) ^ 3
-> (1, 0) | 144 (0, 1) ^ 3 -> (3, 2) (0, 2) ^ 3 -> (3, 1) (1, 3) ^ 3 -> (2, 0) (2, 3) ^ 3
-> (1, 0) |
137 */ | 145 */ |
138 inline int other_two(int one, int two) { | 146 inline int other_two(int one, int two) { |
139 return 1 >> (3 - (one ^ two)) ^ 3; | 147 return 1 >> (3 - (one ^ two)) ^ 3; |
140 } | 148 } |
141 | 149 |
142 #endif | 150 #endif |
OLD | NEW |