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 #include "SkIntersections.h" | 8 #include "SkIntersections.h" |
9 | 9 |
10 int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkS
calar, bool) = { | 10 int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkS
calar, bool) = { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 cubic.set(pts); | 47 cubic.set(pts); |
48 return intersectRay(cubic, line); | 48 return intersectRay(cubic, line); |
49 } | 49 } |
50 | 50 |
51 void SkIntersections::flip() { | 51 void SkIntersections::flip() { |
52 for (int index = 0; index < fUsed; ++index) { | 52 for (int index = 0; index < fUsed; ++index) { |
53 fT[1][index] = 1 - fT[1][index]; | 53 fT[1][index] = 1 - fT[1][index]; |
54 } | 54 } |
55 } | 55 } |
56 | 56 |
57 void SkIntersections::insertCoincidentPair(double s1, double e1, double s2, doub
le e2, | |
58 const SkDPoint& startPt, const SkDPoint& endPt) { | |
59 SkASSERT(s1 < e1); | |
60 SkASSERT(s2 != e2); | |
61 if (coincidentUsed() != fUsed) { // if the curve is partially coincident, tr
eat it as fully so | |
62 for (int index = fUsed - 1; index >= 0; --index) { | |
63 if (fIsCoincident[0] & (1 << index)) { | |
64 continue; | |
65 } | |
66 double nonCoinT = fT[0][index]; | |
67 if (!between(s1, nonCoinT, e1)) { | |
68 if (s1 > nonCoinT) { | |
69 s1 = nonCoinT; | |
70 } else { | |
71 e1 = nonCoinT; | |
72 } | |
73 } | |
74 nonCoinT = fT[1][index]; | |
75 if (!between(s2, nonCoinT, e2)) { | |
76 if ((s2 > nonCoinT) ^ (s2 > e2)) { | |
77 s2 = nonCoinT; | |
78 } else { | |
79 e2 = nonCoinT; | |
80 } | |
81 } | |
82 removeOne(index); | |
83 } | |
84 } | |
85 SkASSERT(coincidentUsed() == fUsed); | |
86 SkASSERT((coincidentUsed() & 1) != 1); | |
87 int i1 = 0; | |
88 int i2 = 0; | |
89 do { | |
90 while (i1 < fUsed && !(fIsCoincident[fSwap] & (1 << i1))) { | |
91 ++i1; | |
92 } | |
93 if (i1 == fUsed) { | |
94 break; | |
95 } | |
96 SkASSERT(i1 < fUsed); | |
97 int iEnd1 = i1 + 1; | |
98 while (!(fIsCoincident[fSwap] & (1 << iEnd1))) { | |
99 ++iEnd1; | |
100 } | |
101 SkASSERT(iEnd1 < fUsed); | |
102 double cs1 = fT[fSwap][i1]; | |
103 double ce1 = fT[fSwap][iEnd1]; | |
104 bool s1in = between(cs1, s1, ce1) || startPt.approximatelyEqual(fPt[i1]) | |
105 || startPt.approximatelyEqual(fPt[iEnd1]); | |
106 bool e1in = between(cs1, e1, ce1) || endPt.approximatelyEqual(fPt[i1]) | |
107 || endPt.approximatelyEqual(fPt[iEnd1]); | |
108 while (i2 < fUsed && !(fIsCoincident[fSwap ^ 1] & (1 << i2))) { | |
109 ++i2; | |
110 } | |
111 int iEnd2 = i2 + 1; | |
112 while (!(fIsCoincident[fSwap ^ 1] & (1 << iEnd2))) { | |
113 ++iEnd2; | |
114 } | |
115 SkASSERT(iEnd2 < fUsed); | |
116 double cs2 = fT[fSwap ^ 1][i2]; | |
117 double ce2 = fT[fSwap ^ 1][iEnd2]; | |
118 bool s2in = between(cs2, s2, ce2) || startPt.approximatelyEqual(fPt[i2]) | |
119 || startPt.approximatelyEqual(fPt[iEnd2]); | |
120 bool e2in = between(cs2, e2, ce2) || endPt.approximatelyEqual(fPt[i2]) | |
121 || endPt.approximatelyEqual(fPt[iEnd2]); | |
122 if ((s1in | e1in) & (s2in | e2in)) { | |
123 if (s1 < cs1) { | |
124 fT[fSwap][i1] = s1; | |
125 fPt[i1] = startPt; | |
126 } else if (e1 < cs1) { | |
127 fT[fSwap][i1] = e1; | |
128 fPt[i1] = endPt; | |
129 } | |
130 if (s1 > ce1) { | |
131 fT[fSwap][iEnd1] = s1; | |
132 fPt[iEnd1] = startPt; | |
133 } else if (e1 > ce1) { | |
134 fT[fSwap][iEnd1] = e1; | |
135 fPt[iEnd1] = endPt; | |
136 } | |
137 if (s2 > e2) { | |
138 SkTSwap(cs2, ce2); | |
139 SkTSwap(i2, iEnd2); | |
140 } | |
141 if (s2 < cs2) { | |
142 fT[fSwap ^ 1][i2] = s2; | |
143 } else if (e2 < cs2) { | |
144 fT[fSwap ^ 1][i2] = e2; | |
145 } | |
146 if (s2 > ce2) { | |
147 fT[fSwap ^ 1][iEnd2] = s2; | |
148 } else if (e2 > ce2) { | |
149 fT[fSwap ^ 1][iEnd2] = e2; | |
150 } | |
151 return; | |
152 } | |
153 } while (true); | |
154 SkASSERT(fUsed < 9); | |
155 insertCoincident(s1, s2, startPt); | |
156 insertCoincident(e1, e2, endPt); | |
157 } | |
158 | |
159 int SkIntersections::insert(double one, double two, const SkDPoint& pt) { | 57 int SkIntersections::insert(double one, double two, const SkDPoint& pt) { |
160 if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) { | 58 if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) { |
161 // For now, don't allow a mix of coincident and non-coincident intersect
ions | 59 // For now, don't allow a mix of coincident and non-coincident intersect
ions |
162 return -1; | 60 return -1; |
163 } | 61 } |
164 SkASSERT(fUsed <= 1 || fT[0][0] <= fT[0][1]); | 62 SkASSERT(fUsed <= 1 || fT[0][0] <= fT[0][1]); |
165 int index; | 63 int index; |
166 for (index = 0; index < fUsed; ++index) { | 64 for (index = 0; index < fUsed; ++index) { |
167 double oldOne = fT[0][index]; | 65 double oldOne = fT[0][index]; |
168 double oldTwo = fT[1][index]; | 66 double oldTwo = fT[1][index]; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 quad.set(a); | 180 quad.set(a); |
283 return vertical(quad, top, bottom, x, flipped); | 181 return vertical(quad, top, bottom, x, flipped); |
284 } | 182 } |
285 | 183 |
286 int SkIntersections::verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bo
ttom, | 184 int SkIntersections::verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bo
ttom, |
287 SkScalar x, bool flipped) { | 185 SkScalar x, bool flipped) { |
288 SkDCubic cubic; | 186 SkDCubic cubic; |
289 cubic.set(a); | 187 cubic.set(a); |
290 return vertical(cubic, top, bottom, x, flipped); | 188 return vertical(cubic, top, bottom, x, flipped); |
291 } | 189 } |
OLD | NEW |