Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: src/pathops/SkIntersections.cpp

Issue 1037573004: cumulative pathops patch (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix pathopsinverse gm Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkIntersections.h ('k') | src/pathops/SkOpAngle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 void SkIntersections::append(const SkIntersections& i) { 10 int SkIntersections::closestTo(double rangeStart, double rangeEnd, const SkDPoin t& testPt,
11 for (int index = 0; index < i.fUsed; ++index) { 11 double* closestDist) const {
12 insert(i[0][index], i[1][index], i.pt(index)); 12 int closest = -1;
13 *closestDist = SK_ScalarMax;
14 for (int index = 0; index < fUsed; ++index) {
15 if (!between(rangeStart, fT[0][index], rangeEnd)) {
16 continue;
17 }
18 const SkDPoint& iPt = fPt[index];
19 double dist = testPt.distanceSquared(iPt);
20 if (*closestDist > dist) {
21 *closestDist = dist;
22 closest = index;
23 }
13 } 24 }
25 return closest;
14 } 26 }
15 27
16 int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar, SkScal ar, SkScalar, bool) = { 28 // called only by test code
17 NULL,
18 &SkIntersections::verticalLine,
19 &SkIntersections::verticalQuad,
20 &SkIntersections::verticalCubic
21 };
22
23 int ( SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine&) = {
24 NULL,
25 &SkIntersections::lineRay,
26 &SkIntersections::quadRay,
27 &SkIntersections::cubicRay
28 };
29
30 int SkIntersections::coincidentUsed() const { 29 int SkIntersections::coincidentUsed() const {
31 if (!fIsCoincident[0]) { 30 if (!fIsCoincident[0]) {
32 SkASSERT(!fIsCoincident[1]); 31 SkASSERT(!fIsCoincident[1]);
33 return 0; 32 return 0;
34 } 33 }
35 int count = 0; 34 int count = 0;
36 SkDEBUGCODE(int count2 = 0;) 35 SkDEBUGCODE(int count2 = 0;)
37 for (int index = 0; index < fUsed; ++index) { 36 for (int index = 0; index < fUsed; ++index) {
38 if (fIsCoincident[0] & (1 << index)) { 37 if (fIsCoincident[0] & (1 << index)) {
39 ++count; 38 ++count;
40 } 39 }
41 #ifdef SK_DEBUG 40 #ifdef SK_DEBUG
42 if (fIsCoincident[1] & (1 << index)) { 41 if (fIsCoincident[1] & (1 << index)) {
43 ++count2; 42 ++count2;
44 } 43 }
45 #endif 44 #endif
46 } 45 }
47 SkASSERT(count == count2); 46 SkASSERT(count == count2);
48 return count; 47 return count;
49 } 48 }
50 49
51 int SkIntersections::cubicRay(const SkPoint pts[4], const SkDLine& line) { 50 int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar, SkScal ar, SkScalar, bool) = {
52 SkDCubic cubic; 51 NULL,
53 cubic.set(pts); 52 &SkIntersections::verticalLine,
54 fMax = 3; 53 &SkIntersections::verticalQuad,
55 return intersectRay(cubic, line); 54 &SkIntersections::verticalCubic
56 } 55 };
57 56
58 void SkIntersections::flip() { 57 void SkIntersections::flip() {
59 for (int index = 0; index < fUsed; ++index) { 58 for (int index = 0; index < fUsed; ++index) {
60 fT[1][index] = 1 - fT[1][index]; 59 fT[1][index] = 1 - fT[1][index];
61 } 60 }
62 } 61 }
63 62
64 int SkIntersections::insert(double one, double two, const SkDPoint& pt) { 63 int SkIntersections::insert(double one, double two, const SkDPoint& pt) {
65 if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) { 64 if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) {
66 // For now, don't allow a mix of coincident and non-coincident intersect ions 65 // For now, don't allow a mix of coincident and non-coincident intersect ions
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 97 }
99 if (fUsed >= fMax) { 98 if (fUsed >= fMax) {
100 SkASSERT(0); // FIXME : this error, if it is to be handled at runtime i n release, must 99 SkASSERT(0); // FIXME : this error, if it is to be handled at runtime i n release, must
101 // be propagated all the way back down to the caller, and return failure. 100 // be propagated all the way back down to the caller, and return failure.
102 fUsed = 0; 101 fUsed = 0;
103 return 0; 102 return 0;
104 } 103 }
105 int remaining = fUsed - index; 104 int remaining = fUsed - index;
106 if (remaining > 0) { 105 if (remaining > 0) {
107 memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining); 106 memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining);
108 memmove(&fPt2[index + 1], &fPt2[index], sizeof(fPt2[0]) * remaining);
109 memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining); 107 memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
110 memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining); 108 memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
111 int clearMask = ~((1 << index) - 1); 109 int clearMask = ~((1 << index) - 1);
112 fIsCoincident[0] += fIsCoincident[0] & clearMask; 110 fIsCoincident[0] += fIsCoincident[0] & clearMask;
113 fIsCoincident[1] += fIsCoincident[1] & clearMask; 111 fIsCoincident[1] += fIsCoincident[1] & clearMask;
114 } 112 }
115 fPt[index] = pt; 113 fPt[index] = pt;
116 SkASSERT(one >= 0 && one <= 1); 114 SkASSERT(one >= 0 && one <= 1);
117 SkASSERT(two >= 0 && two <= 1); 115 SkASSERT(two >= 0 && two <= 1);
118 fT[0][index] = one; 116 fT[0][index] = one;
119 fT[1][index] = two; 117 fT[1][index] = two;
120 ++fUsed; 118 ++fUsed;
121 return index; 119 return index;
122 } 120 }
123 121
124 void SkIntersections::insertNear(double one, double two, const SkDPoint& pt1, co nst SkDPoint& pt2) { 122 void SkIntersections::insertNear(double one, double two, const SkDPoint& pt1, co nst SkDPoint& pt2) {
125 SkASSERT(one == 0 || one == 1); 123 SkASSERT(one == 0 || one == 1);
126 SkASSERT(two == 0 || two == 1); 124 SkASSERT(two == 0 || two == 1);
127 SkASSERT(pt1 != pt2); 125 SkASSERT(pt1 != pt2);
128 SkASSERT(fNearlySame[(int) one]); 126 fNearlySame[one ? 1 : 0] = true;
129 (void) insert(one, two, pt1); 127 (void) insert(one, two, pt1);
130 fPt2[one ? fUsed - 1 : 0] = pt2; 128 fPt2[one ? 1 : 0] = pt2;
131 } 129 }
132 130
133 void SkIntersections::insertCoincident(double one, double two, const SkDPoint& p t) { 131 int SkIntersections::insertCoincident(double one, double two, const SkDPoint& pt ) {
134 int index = insertSwap(one, two, pt); 132 int index = insertSwap(one, two, pt);
133 if (index >= 0) {
134 setCoincident(index);
135 }
136 return index;
137 }
138
139 void SkIntersections::setCoincident(int index) {
140 SkASSERT(index >= 0);
135 int bit = 1 << index; 141 int bit = 1 << index;
136 fIsCoincident[0] |= bit; 142 fIsCoincident[0] |= bit;
137 fIsCoincident[1] |= bit; 143 fIsCoincident[1] |= bit;
138 } 144 }
139 145
140 int SkIntersections::lineRay(const SkPoint pts[2], const SkDLine& line) { 146 void SkIntersections::merge(const SkIntersections& a, int aIndex, const SkInters ections& b,
141 SkDLine l; 147 int bIndex) {
142 l.set(pts); 148 this->reset();
143 fMax = 2; 149 fT[0][0] = a.fT[0][aIndex];
144 return intersectRay(l, line); 150 fT[1][0] = b.fT[0][bIndex];
151 fPt[0] = a.fPt[aIndex];
152 fPt2[0] = b.fPt[bIndex];
153 fUsed = 1;
145 } 154 }
146 155
147 void SkIntersections::offset(int base, double start, double end) { 156 int SkIntersections::mostOutside(double rangeStart, double rangeEnd, const SkDPo int& origin) const {
148 for (int index = base; index < fUsed; ++index) { 157 int result = -1;
149 double val = fT[fSwap][index]; 158 for (int index = 0; index < fUsed; ++index) {
150 val *= end - start; 159 if (!between(rangeStart, fT[0][index], rangeEnd)) {
151 val += start; 160 continue;
152 fT[fSwap][index] = val; 161 }
162 if (result < 0) {
163 result = index;
164 continue;
165 }
166 SkDVector best = fPt[result] - origin;
167 SkDVector test = fPt[index] - origin;
168 if (test.crossCheck(best) < 0) {
169 result = index;
170 }
153 } 171 }
154 } 172 return result;
155
156 int SkIntersections::quadRay(const SkPoint pts[3], const SkDLine& line) {
157 SkDQuad quad;
158 quad.set(pts);
159 fMax = 2;
160 return intersectRay(quad, line);
161 } 173 }
162 174
163 void SkIntersections::quickRemoveOne(int index, int replace) { 175 void SkIntersections::quickRemoveOne(int index, int replace) {
164 if (index < replace) { 176 if (index < replace) {
165 fT[0][index] = fT[0][replace]; 177 fT[0][index] = fT[0][replace];
166 } 178 }
167 } 179 }
168 180
169 void SkIntersections::removeOne(int index) { 181 void SkIntersections::removeOne(int index) {
170 int remaining = --fUsed - index; 182 int remaining = --fUsed - index;
171 if (remaining <= 0) { 183 if (remaining <= 0) {
172 return; 184 return;
173 } 185 }
174 memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining); 186 memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining);
175 memmove(&fPt2[index], &fPt2[index + 1], sizeof(fPt2[0]) * remaining);
176 memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining); 187 memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining);
177 memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining); 188 memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining);
178 // SkASSERT(fIsCoincident[0] == 0); 189 // SkASSERT(fIsCoincident[0] == 0);
179 int coBit = fIsCoincident[0] & (1 << index); 190 int coBit = fIsCoincident[0] & (1 << index);
180 fIsCoincident[0] -= ((fIsCoincident[0] >> 1) & ~((1 << index) - 1)) + coBit; 191 fIsCoincident[0] -= ((fIsCoincident[0] >> 1) & ~((1 << index) - 1)) + coBit;
181 SkASSERT(!(coBit ^ (fIsCoincident[1] & (1 << index)))); 192 SkASSERT(!(coBit ^ (fIsCoincident[1] & (1 << index))));
182 fIsCoincident[1] -= ((fIsCoincident[1] >> 1) & ~((1 << index) - 1)) + coBit; 193 fIsCoincident[1] -= ((fIsCoincident[1] >> 1) & ~((1 << index) - 1)) + coBit;
183 } 194 }
184 195
185 void SkIntersections::swapPts() {
186 int index;
187 for (index = 0; index < fUsed; ++index) {
188 SkTSwap(fT[0][index], fT[1][index]);
189 }
190 }
191
192 int SkIntersections::verticalLine(const SkPoint a[2], SkScalar top, SkScalar bot tom, 196 int SkIntersections::verticalLine(const SkPoint a[2], SkScalar top, SkScalar bot tom,
193 SkScalar x, bool flipped) { 197 SkScalar x, bool flipped) {
194 SkDLine line; 198 SkDLine line;
195 line.set(a); 199 line.set(a);
196 return vertical(line, top, bottom, x, flipped); 200 return vertical(line, top, bottom, x, flipped);
197 } 201 }
198 202
199 int SkIntersections::verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bot tom, 203 int SkIntersections::verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bot tom,
200 SkScalar x, bool flipped) { 204 SkScalar x, bool flipped) {
201 SkDQuad quad; 205 SkDQuad quad;
202 quad.set(a); 206 quad.set(a);
203 return vertical(quad, top, bottom, x, flipped); 207 return vertical(quad, top, bottom, x, flipped);
204 } 208 }
205 209
206 int SkIntersections::verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bo ttom, 210 int SkIntersections::verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bo ttom,
207 SkScalar x, bool flipped) { 211 SkScalar x, bool flipped) {
208 SkDCubic cubic; 212 SkDCubic cubic;
209 cubic.set(a); 213 cubic.set(a);
210 return vertical(cubic, top, bottom, x, flipped); 214 return vertical(cubic, top, bottom, x, flipped);
211 } 215 }
OLDNEW
« no previous file with comments | « src/pathops/SkIntersections.h ('k') | src/pathops/SkOpAngle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698