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

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

Issue 13094010: Add implementation of path ops (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/pathops/SkAddIntersections.h ('k') | src/pathops/SkIntersectionHelper.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "SkAddIntersections.h"
8 #include "SkPathOpsBounds.h"
9
10 #if DEBUG_ADD_INTERSECTING_TS
11
12 static void debugShowLineIntersection(int pts, const SkIntersectionHelper& wt,
13 const SkIntersectionHelper& wn, const SkIn tersections& i) {
14 SkASSERT(i.used() == pts);
15 if (!pts) {
16 SkDebugf("%s no intersect " LINE_DEBUG_STR " " LINE_DEBUG_STR "\n",
17 __FUNCTION__, LINE_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts( )));
18 return;
19 }
20 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " LINE_DEBUG_STR " " PT_DEBUG_STR, __F UNCTION__,
21 i[0][0], LINE_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
22 if (pts == 2) {
23 SkDebugf(" " T_DEBUG_STR(wtTs, 1) " " PT_DEBUG_STR, i[0][1], PT_DEBUG_DA TA(i, 1));
24 }
25 SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
26 if (pts == 2) {
27 SkDebugf(" " T_DEBUG_STR(wnTs, 1), i[1][1]);
28 }
29 SkDebugf("\n");
30 }
31
32 static void debugShowQuadLineIntersection(int pts, const SkIntersectionHelper& w t,
33 const SkIntersectionHelper& wn,
34 const SkIntersections& i) {
35 SkASSERT(i.used() == pts);
36 if (!pts) {
37 SkDebugf("%s no intersect " QUAD_DEBUG_STR " " LINE_DEBUG_STR "\n",
38 __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts( )));
39 return;
40 }
41 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __F UNCTION__,
42 i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
43 for (int n = 1; n < pts; ++n) {
44 SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_D ATA(i, n));
45 }
46 SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
47 for (int n = 1; n < pts; ++n) {
48 SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
49 }
50 SkDebugf("\n");
51 }
52
53 static void debugShowQuadIntersection(int pts, const SkIntersectionHelper& wt,
54 const SkIntersectionHelper& wn, const SkIntersections& i) {
55 SkASSERT(i.used() == pts);
56 if (!pts) {
57 SkDebugf("%s no intersect " QUAD_DEBUG_STR " " QUAD_DEBUG_STR "\n",
58 __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts( )));
59 return;
60 }
61 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __F UNCTION__,
62 i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
63 for (int n = 1; n < pts; ++n) {
64 SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_D ATA(i, n));
65 }
66 SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
67 for (int n = 1; n < pts; ++n) {
68 SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
69 }
70 SkDebugf("\n");
71 }
72
73 static void debugShowCubicLineIntersection(int pts, const SkIntersectionHelper& wt,
74 const SkIntersectionHelper& wn, const SkIntersections& i) {
75 SkASSERT(i.used() == pts);
76 if (!pts) {
77 SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
78 __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts ()));
79 return;
80 }
81 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __ FUNCTION__,
82 i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
83 for (int n = 1; n < pts; ++n) {
84 SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_D ATA(i, n));
85 }
86 SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
87 for (int n = 1; n < pts; ++n) {
88 SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
89 }
90 SkDebugf("\n");
91 }
92
93 static void debugShowCubicQuadIntersection(int pts, const SkIntersectionHelper& wt,
94 const SkIntersectionHelper& wn, const SkIntersections& i) {
95 SkASSERT(i.used() == pts);
96 if (!pts) {
97 SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
98 __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts ()));
99 return;
100 }
101 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __ FUNCTION__,
102 i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
103 for (int n = 1; n < pts; ++n) {
104 SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_D ATA(i, n));
105 }
106 SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
107 for (int n = 1; n < pts; ++n) {
108 SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
109 }
110 SkDebugf("\n");
111 }
112
113 static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
114 const SkIntersectionHelper& wn, const SkIntersections& i) {
115 SkASSERT(i.used() == pts);
116 if (!pts) {
117 SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CUBIC_DEBUG_STR "\n",
118 __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CUBIC_DEBUG_DATA(wn.pt s()));
119 return;
120 }
121 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __ FUNCTION__,
122 i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
123 for (int n = 1; n < pts; ++n) {
124 SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_D ATA(i, n));
125 }
126 SkDebugf(" wnTs[0]=%g " CUBIC_DEBUG_STR, i[1][0], CUBIC_DEBUG_DATA(wn.pts()) );
127 for (int n = 1; n < pts; ++n) {
128 SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
129 }
130 SkDebugf("\n");
131 }
132
133 static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt, const SkIntersections& i) {
134 SkASSERT(i.used() == pts);
135 if (!pts) {
136 SkDebugf("%s no self intersect " CUBIC_DEBUG_STR "\n", __FUNCTION__,
137 CUBIC_DEBUG_DATA(wt.pts()));
138 return;
139 }
140 SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __ FUNCTION__,
141 i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
142 SkDebugf(" " T_DEBUG_STR(wtTs, 1), i[1][0]);
143 SkDebugf("\n");
144 }
145
146 #else
147 static void debugShowLineIntersection(int , const SkIntersectionHelper& , const SkIntersectionHelper& , const SkIntersections& ) {
148 }
149
150 static void debugShowQuadLineIntersection(int , const SkIntersectionHelper& , co nst SkIntersectionHelper& , const SkIntersections& ) {
151 }
152
153 static void debugShowQuadIntersection(int , const SkIntersectionHelper& , const SkIntersectionHelper& , const SkIntersections& ) {
154 }
155
156 static void debugShowCubicLineIntersection(int , const SkIntersectionHelper& , c onst SkIntersectionHelper& ,
157 const SkIntersections& ) {
158 }
159
160 static void debugShowCubicQuadIntersection(int , const SkIntersectionHelper& , c onst SkIntersectionHelper& ,
161 const SkIntersections& ) {
162 }
163
164 static void debugShowCubicIntersection(int , const SkIntersectionHelper& , const SkIntersectionHelper& , const SkIntersections& ) {
165 }
166
167 static void debugShowCubicIntersection(int , const SkIntersectionHelper& , const SkIntersections& ) {
168 }
169 #endif
170
171 bool AddIntersectTs(SkOpContour* test, SkOpContour* next) {
172
173 if (test != next) {
174 if (test->bounds().fBottom < next->bounds().fTop) {
175 return false;
176 }
177 if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) {
178 return true;
179 }
180 }
181 SkIntersectionHelper wt;
182 wt.init(test);
183 bool foundCommonContour = test == next;
184 do {
185 SkIntersectionHelper wn;
186 wn.init(next);
187 if (test == next && !wn.startAfter(wt)) {
188 continue;
189 }
190 do {
191 if (!SkPathOpsBounds::Intersects(wt.bounds(), wn.bounds())) {
192 continue;
193 }
194 int pts;
195 SkIntersections ts;
196 bool swap = false;
197 switch (wt.segmentType()) {
198 case SkIntersectionHelper::kHorizontalLine_Segment:
199 swap = true;
200 switch (wn.segmentType()) {
201 case SkIntersectionHelper::kHorizontalLine_Segment:
202 case SkIntersectionHelper::kVerticalLine_Segment:
203 case SkIntersectionHelper::kLine_Segment: {
204 pts = ts.lineHorizontal(wn.pts(), wt.left(),
205 wt.right(), wt.y(), wt.xFlipped());
206 debugShowLineIntersection(pts, wt, wn, ts);
207 break;
208 }
209 case SkIntersectionHelper::kQuad_Segment: {
210 pts = ts.quadHorizontal(wn.pts(), wt.left(),
211 wt.right(), wt.y(), wt.xFlipped());
212 debugShowQuadLineIntersection(pts, wn, wt, ts);
213 break;
214 }
215 case SkIntersectionHelper::kCubic_Segment: {
216 pts = ts.cubicHorizontal(wn.pts(), wt.left(),
217 wt.right(), wt.y(), wt.xFlipped());
218 debugShowCubicLineIntersection(pts, wn, wt, ts);
219 break;
220 }
221 default:
222 SkASSERT(0);
223 }
224 break;
225 case SkIntersectionHelper::kVerticalLine_Segment:
226 swap = true;
227 switch (wn.segmentType()) {
228 case SkIntersectionHelper::kHorizontalLine_Segment:
229 case SkIntersectionHelper::kVerticalLine_Segment:
230 case SkIntersectionHelper::kLine_Segment: {
231 pts = ts.lineVertical(wn.pts(), wt.top(),
232 wt.bottom(), wt.x(), wt.yFlipped());
233 debugShowLineIntersection(pts, wt, wn, ts);
234 break;
235 }
236 case SkIntersectionHelper::kQuad_Segment: {
237 pts = ts.quadVertical(wn.pts(), wt.top(),
238 wt.bottom(), wt.x(), wt.yFlipped());
239 debugShowQuadLineIntersection(pts, wn, wt, ts);
240 break;
241 }
242 case SkIntersectionHelper::kCubic_Segment: {
243 pts = ts.cubicVertical(wn.pts(), wt.top(),
244 wt.bottom(), wt.x(), wt.yFlipped());
245 debugShowCubicLineIntersection(pts, wn, wt, ts);
246 break;
247 }
248 default:
249 SkASSERT(0);
250 }
251 break;
252 case SkIntersectionHelper::kLine_Segment:
253 switch (wn.segmentType()) {
254 case SkIntersectionHelper::kHorizontalLine_Segment:
255 pts = ts.lineHorizontal(wt.pts(), wn.left(),
256 wn.right(), wn.y(), wn.xFlipped());
257 debugShowLineIntersection(pts, wt, wn, ts);
258 break;
259 case SkIntersectionHelper::kVerticalLine_Segment:
260 pts = ts.lineVertical(wt.pts(), wn.top(),
261 wn.bottom(), wn.x(), wn.yFlipped());
262 debugShowLineIntersection(pts, wt, wn, ts);
263 break;
264 case SkIntersectionHelper::kLine_Segment: {
265 pts = ts.lineLine(wt.pts(), wn.pts());
266 debugShowLineIntersection(pts, wt, wn, ts);
267 break;
268 }
269 case SkIntersectionHelper::kQuad_Segment: {
270 swap = true;
271 pts = ts.quadLine(wn.pts(), wt.pts());
272 debugShowQuadLineIntersection(pts, wn, wt, ts);
273 break;
274 }
275 case SkIntersectionHelper::kCubic_Segment: {
276 swap = true;
277 pts = ts.cubicLine(wn.pts(), wt.pts());
278 debugShowCubicLineIntersection(pts, wn, wt, ts);
279 break;
280 }
281 default:
282 SkASSERT(0);
283 }
284 break;
285 case SkIntersectionHelper::kQuad_Segment:
286 switch (wn.segmentType()) {
287 case SkIntersectionHelper::kHorizontalLine_Segment:
288 pts = ts.quadHorizontal(wt.pts(), wn.left(),
289 wn.right(), wn.y(), wn.xFlipped());
290 debugShowQuadLineIntersection(pts, wt, wn, ts);
291 break;
292 case SkIntersectionHelper::kVerticalLine_Segment:
293 pts = ts.quadVertical(wt.pts(), wn.top(),
294 wn.bottom(), wn.x(), wn.yFlipped());
295 debugShowQuadLineIntersection(pts, wt, wn, ts);
296 break;
297 case SkIntersectionHelper::kLine_Segment: {
298 pts = ts.quadLine(wt.pts(), wn.pts());
299 debugShowQuadLineIntersection(pts, wt, wn, ts);
300 break;
301 }
302 case SkIntersectionHelper::kQuad_Segment: {
303 pts = ts.quadQuad(wt.pts(), wn.pts());
304 debugShowQuadIntersection(pts, wt, wn, ts);
305 break;
306 }
307 case SkIntersectionHelper::kCubic_Segment: {
308 swap = true;
309 pts = ts.cubicQuad(wn.pts(), wt.pts());
310 debugShowCubicQuadIntersection(pts, wn, wt, ts);
311 break;
312 }
313 default:
314 SkASSERT(0);
315 }
316 break;
317 case SkIntersectionHelper::kCubic_Segment:
318 switch (wn.segmentType()) {
319 case SkIntersectionHelper::kHorizontalLine_Segment:
320 pts = ts.cubicHorizontal(wt.pts(), wn.left(),
321 wn.right(), wn.y(), wn.xFlipped());
322 debugShowCubicLineIntersection(pts, wt, wn, ts);
323 break;
324 case SkIntersectionHelper::kVerticalLine_Segment:
325 pts = ts.cubicVertical(wt.pts(), wn.top(),
326 wn.bottom(), wn.x(), wn.yFlipped());
327 debugShowCubicLineIntersection(pts, wt, wn, ts);
328 break;
329 case SkIntersectionHelper::kLine_Segment: {
330 pts = ts.cubicLine(wt.pts(), wn.pts());
331 debugShowCubicLineIntersection(pts, wt, wn, ts);
332 break;
333 }
334 case SkIntersectionHelper::kQuad_Segment: {
335 pts = ts.cubicQuad(wt.pts(), wn.pts());
336 debugShowCubicQuadIntersection(pts, wt, wn, ts);
337 break;
338 }
339 case SkIntersectionHelper::kCubic_Segment: {
340 pts = ts.cubicCubic(wt.pts(), wn.pts());
341 debugShowCubicIntersection(pts, wt, wn, ts);
342 break;
343 }
344 default:
345 SkASSERT(0);
346 }
347 break;
348 default:
349 SkASSERT(0);
350 }
351 if (!foundCommonContour && pts > 0) {
352 test->addCross(next);
353 next->addCross(test);
354 foundCommonContour = true;
355 }
356 // in addition to recording T values, record matching segment
357 if (pts == 2) {
358 if (wn.segmentType() <= SkIntersectionHelper::kLine_Segment
359 && wt.segmentType() <= SkIntersectionHelper::kLine_Segme nt) {
360 wt.addCoincident(wn, ts, swap);
361 continue;
362 }
363 if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment
364 && wt.segmentType() >= SkIntersectionHelper::kQuad_Segme nt
365 && ts.isCoincident(0)) {
366 SkASSERT(ts.coincidentUsed() == 2);
367 wt.addCoincident(wn, ts, swap);
368 continue;
369 }
370
371 }
372 for (int pt = 0; pt < pts; ++pt) {
373 SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
374 SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
375 SkPoint point = ts.pt(pt).asSkPoint();
376 int testTAt = wt.addT(wn, point, ts[swap][pt]);
377 int nextTAt = wn.addT(wt, point, ts[!swap][pt]);
378 wt.addOtherT(testTAt, ts[!swap][pt], nextTAt);
379 wn.addOtherT(nextTAt, ts[swap][pt], testTAt);
380 }
381 } while (wn.advance());
382 } while (wt.advance());
383 return true;
384 }
385
386 void AddSelfIntersectTs(SkOpContour* test) {
387 SkIntersectionHelper wt;
388 wt.init(test);
389 do {
390 if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) {
391 continue;
392 }
393 SkIntersections ts;
394 int pts = ts.cubic(wt.pts());
395 debugShowCubicIntersection(pts, wt, ts);
396 if (!pts) {
397 continue;
398 }
399 SkASSERT(pts == 1);
400 SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1);
401 SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1);
402 SkPoint point = ts.pt(0).asSkPoint();
403 int testTAt = wt.addSelfT(wt, point, ts[0][0]);
404 int nextTAt = wt.addT(wt, point, ts[1][0]);
405 wt.addOtherT(testTAt, ts[1][0], nextTAt);
406 wt.addOtherT(nextTAt, ts[0][0], testTAt);
407 } while (wt.advance());
408 }
409
410 // resolve any coincident pairs found while intersecting, and
411 // see if coincidence is formed by clipping non-concident segments
412 void CoincidenceCheck(SkTDArray<SkOpContour*>& contourList, int total) {
413 int contourCount = contourList.count();
414 #if ONE_PASS_COINCIDENCE_CHECK
415 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
416 SkOpContour* contour = contourList[cIndex];
417 contour->resolveCoincidence(contourList);
418 }
419 #else
420 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
421 SkOpContour* contour = contourList[cIndex];
422 contour->addCoincidentPoints();
423 }
424 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
425 SkOpContour* contour = contourList[cIndex];
426 contour->calcCoincidentWinding();
427 }
428 #endif
429 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
430 SkOpContour* contour = contourList[cIndex];
431 contour->findTooCloseToCall();
432 }
433 }
OLDNEW
« no previous file with comments | « src/pathops/SkAddIntersections.h ('k') | src/pathops/SkIntersectionHelper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698