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 #include "SkTArray.h" | |
14 | 13 |
15 struct SkDCubicPair { | 14 struct SkDCubicPair { |
16 const SkDCubic& first() const { return (const SkDCubic&) pts[0]; } | 15 const SkDCubic& first() const { return (const SkDCubic&) pts[0]; } |
17 const SkDCubic& second() const { return (const SkDCubic&) pts[3]; } | 16 const SkDCubic& second() const { return (const SkDCubic&) pts[3]; } |
18 SkDPoint pts[7]; | 17 SkDPoint pts[7]; |
19 }; | 18 }; |
20 | 19 |
21 struct SkDCubic { | 20 struct SkDCubic { |
| 21 static const int kPointCount = 4; |
| 22 static const int kPointLast = kPointCount - 1; |
| 23 static const int kMaxIntersections = 9; |
| 24 |
22 enum SearchAxis { | 25 enum SearchAxis { |
23 kXAxis, | 26 kXAxis, |
24 kYAxis | 27 kYAxis |
25 }; | 28 }; |
26 | 29 |
27 const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 4); return
fPts[n]; } | 30 bool collapsed() const { |
28 SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 4); return fPts[n]; } | 31 return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual
(fPts[2]) |
| 32 && fPts[0].approximatelyEqual(fPts[3]); |
| 33 } |
| 34 |
| 35 bool controlsInside() const { |
| 36 SkDVector v01 = fPts[0] - fPts[1]; |
| 37 SkDVector v02 = fPts[0] - fPts[2]; |
| 38 SkDVector v03 = fPts[0] - fPts[3]; |
| 39 SkDVector v13 = fPts[1] - fPts[3]; |
| 40 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; |
| 42 } |
| 43 |
| 44 static bool IsCubic() { return true; } |
| 45 |
| 46 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]; } |
29 | 48 |
30 void align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const; | 49 void align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const; |
31 double binarySearch(double min, double max, double axisIntercept, SearchAxis
xAxis) const; | 50 double binarySearch(double min, double max, double axisIntercept, SearchAxis
xAxis) const; |
32 double calcPrecision() const; | 51 double calcPrecision() const; |
33 SkDCubicPair chopAt(double t) const; | 52 SkDCubicPair chopAt(double t) const; |
34 bool clockwise() const; | 53 bool clockwise() const; |
35 static void Coefficients(const double* cubic, double* A, double* B, double*
C, double* D); | 54 static void Coefficients(const double* cubic, double* A, double* B, double*
C, double* D); |
36 bool controlsContainedByEnds() const; | 55 static bool ComplexBreak(const SkPoint pts[4], SkScalar* t); |
| 56 int convexHull(char order[kPointCount]) const; |
| 57 void dump() const; // callable from the debugger when the implementation co
de is linked in |
| 58 void dumpID(int id) const; |
| 59 void dumpInner() const; |
37 SkDVector dxdyAtT(double t) const; | 60 SkDVector dxdyAtT(double t) const; |
38 bool endsAreExtremaInXOrY() const; | 61 bool endsAreExtremaInXOrY() const; |
39 static int FindExtrema(double a, double b, double c, double d, double tValue
[2]); | 62 static int FindExtrema(double a, double b, double c, double d, double tValue
[2]); |
40 int findInflections(double tValues[2]) const; | 63 int findInflections(double tValues[2]) const; |
41 | 64 |
42 static int FindInflections(const SkPoint a[4], double tValues[2]) { | 65 static int FindInflections(const SkPoint a[kPointCount], double tValues[2])
{ |
43 SkDCubic cubic; | 66 SkDCubic cubic; |
44 cubic.set(a); | 67 cubic.set(a); |
45 return cubic.findInflections(tValues); | 68 return cubic.findInflections(tValues); |
46 } | 69 } |
47 | 70 |
48 int findMaxCurvature(double tValues[]) const; | 71 int findMaxCurvature(double tValues[]) const; |
| 72 bool hullIntersects(const SkDCubic& c2, bool* isLinear) const; |
49 bool isLinear(int startIndex, int endIndex) const; | 73 bool isLinear(int startIndex, int endIndex) const; |
50 bool monotonicInY() const; | 74 bool monotonicInY() const; |
| 75 void otherPts(int index, const SkDPoint* o1Pts[kPointCount - 1]) const; |
51 SkDPoint ptAtT(double t) const; | 76 SkDPoint ptAtT(double t) const; |
52 static int RootsReal(double A, double B, double C, double D, double t[3]); | 77 static int RootsReal(double A, double B, double C, double D, double t[3]); |
53 static int RootsValidT(const double A, const double B, const double C, doubl
e D, double s[3]); | 78 static int RootsValidT(const double A, const double B, const double C, doubl
e D, double s[3]); |
54 | 79 |
55 int searchRoots(double extremes[6], int extrema, double axisIntercept, | 80 int searchRoots(double extremes[6], int extrema, double axisIntercept, |
56 SearchAxis xAxis, double* validRoots) const; | 81 SearchAxis xAxis, double* validRoots) const; |
57 bool serpentine() const; | |
58 | 82 |
59 void set(const SkPoint pts[4]) { | 83 void set(const SkPoint pts[kPointCount]) { |
60 fPts[0] = pts[0]; | 84 fPts[0] = pts[0]; |
61 fPts[1] = pts[1]; | 85 fPts[1] = pts[1]; |
62 fPts[2] = pts[2]; | 86 fPts[2] = pts[2]; |
63 fPts[3] = pts[3]; | 87 fPts[3] = pts[3]; |
64 } | 88 } |
65 | 89 |
66 SkDCubic subDivide(double t1, double t2) const; | 90 SkDCubic subDivide(double t1, double t2) const; |
67 | 91 |
68 static SkDCubic SubDivide(const SkPoint a[4], double t1, double t2) { | 92 static SkDCubic SubDivide(const SkPoint a[kPointCount], double t1, double t2
) { |
69 SkDCubic cubic; | 93 SkDCubic cubic; |
70 cubic.set(a); | 94 cubic.set(a); |
71 return cubic.subDivide(t1, t2); | 95 return cubic.subDivide(t1, t2); |
72 } | 96 } |
73 | 97 |
74 void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, S
kDPoint p[2]) const; | 98 void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, S
kDPoint p[2]) const; |
75 | 99 |
76 static void SubDivide(const SkPoint pts[4], const SkDPoint& a, const SkDPoin
t& d, double t1, | 100 static void SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, con
st SkDPoint& d, double t1, |
77 double t2, SkDPoint p[2]) { | 101 double t2, SkDPoint p[2]) { |
78 SkDCubic cubic; | 102 SkDCubic cubic; |
79 cubic.set(pts); | 103 cubic.set(pts); |
80 cubic.subDivide(a, d, t1, t2, p); | 104 cubic.subDivide(a, d, t1, t2, p); |
81 } | 105 } |
82 | 106 |
83 SkDPoint top(double startT, double endT) const; | 107 SkDPoint top(double startT, double endT) const; |
84 void toQuadraticTs(double precision, SkTArray<double, true>* ts) const; | |
85 SkDQuad toQuad() const; | 108 SkDQuad toQuad() const; |
86 | 109 |
87 // utilities callable by the user from the debugger when the implementation
code is linked in | |
88 void dump() const; | |
89 void dumpNumber() const; | |
90 | |
91 static const int gPrecisionUnit; | 110 static const int gPrecisionUnit; |
92 | 111 |
93 SkDPoint fPts[4]; | 112 SkDPoint fPts[kPointCount]; |
94 }; | 113 }; |
95 | 114 |
| 115 /* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask |
| 116 that computes the other two. Note that: |
| 117 |
| 118 one ^ two == 3 for (0, 3), (1, 2) |
| 119 one ^ two < 3 for (0, 1), (0, 2), (1, 3), (2, 3) |
| 120 3 - (one ^ two) is either 0, 1, or 2 |
| 121 1 >> (3 - (one ^ two)) is either 0 or 1 |
| 122 thus: |
| 123 returned == 2 for (0, 3), (1, 2) |
| 124 returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3) |
| 125 given that: |
| 126 (0, 3) ^ 2 -> (2, 1) (1, 2) ^ 2 -> (3, 0) |
| 127 (0, 1) ^ 3 -> (3, 2) (0, 2) ^ 3 -> (3, 1) (1, 3) ^ 3 -> (2, 0) (2, 3) ^ 3
-> (1, 0) |
| 128 */ |
| 129 inline int other_two(int one, int two) { |
| 130 return 1 >> (3 - (one ^ two)) ^ 3; |
| 131 } |
| 132 |
96 #endif | 133 #endif |
OLD | NEW |