OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 // given a prospective edge, compute its initial winding by projecting a ray | 8 // given a prospective edge, compute its initial winding by projecting a ray |
9 // if the ray hits another edge | 9 // if the ray hits another edge |
10 // if the edge doesn't have a winding yet, hop up to that edge and start ove
r | 10 // if the edge doesn't have a winding yet, hop up to that edge and start ove
r |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 } | 75 } |
76 | 76 |
77 static bool ccw_dxdy(const SkDVector& v, SkOpRayDir dir) { | 77 static bool ccw_dxdy(const SkDVector& v, SkOpRayDir dir) { |
78 bool vPartPos = pt_dydx(v, dir) > 0; | 78 bool vPartPos = pt_dydx(v, dir) > 0; |
79 bool leftBottom = ((static_cast<int>(dir) + 1) & 2) != 0; | 79 bool leftBottom = ((static_cast<int>(dir) + 1) & 2) != 0; |
80 return vPartPos == leftBottom; | 80 return vPartPos == leftBottom; |
81 } | 81 } |
82 | 82 |
83 struct SkOpRayHit { | 83 struct SkOpRayHit { |
84 SkOpRayDir makeTestBase(SkOpSpan* span, double t) { | 84 SkOpRayDir makeTestBase(SkOpSpan* span, double t) { |
85 fNext = NULL; | 85 fNext = nullptr; |
86 fSpan = span; | 86 fSpan = span; |
87 fT = span->t() * (1 - t) + span->next()->t() * t; | 87 fT = span->t() * (1 - t) + span->next()->t() * t; |
88 SkOpSegment* segment = span->segment(); | 88 SkOpSegment* segment = span->segment(); |
89 fSlope = segment->dSlopeAtT(fT); | 89 fSlope = segment->dSlopeAtT(fT); |
90 fPt = segment->ptAtT(fT); | 90 fPt = segment->ptAtT(fT); |
91 fValid = true; | 91 fValid = true; |
92 return fabs(fSlope.fX) < fabs(fSlope.fY) ? SkOpRayDir::kLeft : SkOpRayDi
r::kTop; | 92 return fabs(fSlope.fX) < fabs(fSlope.fY) ? SkOpRayDir::kLeft : SkOpRayDi
r::kTop; |
93 } | 93 } |
94 | 94 |
95 SkOpRayHit* fNext; | 95 SkOpRayHit* fNext; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 *hits = newHit; | 184 *hits = newHit; |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 SkOpSpan* SkOpSegment::windingSpanAtT(double tHit) { | 188 SkOpSpan* SkOpSegment::windingSpanAtT(double tHit) { |
189 SkOpSpan* span = &fHead; | 189 SkOpSpan* span = &fHead; |
190 SkOpSpanBase* next; | 190 SkOpSpanBase* next; |
191 do { | 191 do { |
192 next = span->next(); | 192 next = span->next(); |
193 if (approximately_equal(tHit, next->t())) { | 193 if (approximately_equal(tHit, next->t())) { |
194 return NULL; | 194 return nullptr; |
195 } | 195 } |
196 if (tHit < next->t()) { | 196 if (tHit < next->t()) { |
197 return span; | 197 return span; |
198 } | 198 } |
199 } while (!next->final() && (span = next->upCast())); | 199 } while (!next->final() && (span = next->upCast())); |
200 return NULL; | 200 return nullptr; |
201 } | 201 } |
202 | 202 |
203 static bool hit_compare_x(const SkOpRayHit* a, const SkOpRayHit* b) { | 203 static bool hit_compare_x(const SkOpRayHit* a, const SkOpRayHit* b) { |
204 return a->fPt.fX < b->fPt.fX; | 204 return a->fPt.fX < b->fPt.fX; |
205 } | 205 } |
206 | 206 |
207 static bool reverse_hit_compare_x(const SkOpRayHit* a, const SkOpRayHit* b) { | 207 static bool reverse_hit_compare_x(const SkOpRayHit* a, const SkOpRayHit* b) { |
208 return b->fPt.fX < a->fPt.fX; | 208 return b->fPt.fX < a->fPt.fX; |
209 } | 209 } |
210 | 210 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 ? less_than(dir) ? hit_compare_y : reverse_hit_compare_y | 259 ? less_than(dir) ? hit_compare_y : reverse_hit_compare_y |
260 : less_than(dir) ? hit_compare_x : reverse_hit_compare_x); | 260 : less_than(dir) ? hit_compare_x : reverse_hit_compare_x); |
261 // verify windings | 261 // verify windings |
262 #if DEBUG_WINDING | 262 #if DEBUG_WINDING |
263 SkDebugf("%s dir=%s seg=%d t=%1.9g pt=(%1.9g,%1.9g)\n", __FUNCTION__, | 263 SkDebugf("%s dir=%s seg=%d t=%1.9g pt=(%1.9g,%1.9g)\n", __FUNCTION__, |
264 gDebugRayDirName[static_cast<int>(dir)], hitBase.fSpan->segment()->d
ebugID(), | 264 gDebugRayDirName[static_cast<int>(dir)], hitBase.fSpan->segment()->d
ebugID(), |
265 hitBase.fT, hitBase.fPt.fX, hitBase.fPt.fY); | 265 hitBase.fT, hitBase.fPt.fX, hitBase.fPt.fY); |
266 for (int index = 0; index < count; ++index) { | 266 for (int index = 0; index < count; ++index) { |
267 hit = sorted[index]; | 267 hit = sorted[index]; |
268 SkOpSpan* span = hit->fSpan; | 268 SkOpSpan* span = hit->fSpan; |
269 SkOpSegment* hitSegment = span ? span->segment() : NULL; | 269 SkOpSegment* hitSegment = span ? span->segment() : nullptr; |
270 bool operand = span ? hitSegment->operand() : false; | 270 bool operand = span ? hitSegment->operand() : false; |
271 bool ccw = ccw_dxdy(hit->fSlope, dir); | 271 bool ccw = ccw_dxdy(hit->fSlope, dir); |
272 SkDebugf("%s [%d] valid=%d operand=%d span=%d ccw=%d ", __FUNCTION__, in
dex, | 272 SkDebugf("%s [%d] valid=%d operand=%d span=%d ccw=%d ", __FUNCTION__, in
dex, |
273 hit->fValid, operand, span ? span->debugID() : -1, ccw); | 273 hit->fValid, operand, span ? span->debugID() : -1, ccw); |
274 if (span) { | 274 if (span) { |
275 hitSegment->dumpPtsInner(); | 275 hitSegment->dumpPtsInner(); |
276 } | 276 } |
277 SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g) slope=(%1.9g,%1.9g)\n", hit->fT, | 277 SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g) slope=(%1.9g,%1.9g)\n", hit->fT, |
278 hit->fPt.fX, hit->fPt.fY, hit->fSlope.fX, hit->fSlope.fY); | 278 hit->fPt.fX, hit->fPt.fY, hit->fSlope.fX, hit->fSlope.fY); |
279 } | 279 } |
280 #endif | 280 #endif |
281 const SkPoint* last = NULL; | 281 const SkPoint* last = nullptr; |
282 int wind = 0; | 282 int wind = 0; |
283 int oppWind = 0; | 283 int oppWind = 0; |
284 for (int index = 0; index < count; ++index) { | 284 for (int index = 0; index < count; ++index) { |
285 hit = sorted[index]; | 285 hit = sorted[index]; |
286 if (!hit->fValid) { | 286 if (!hit->fValid) { |
287 return false; | 287 return false; |
288 } | 288 } |
289 bool ccw = ccw_dxdy(hit->fSlope, dir); | 289 bool ccw = ccw_dxdy(hit->fSlope, dir); |
290 SkASSERT(!approximately_zero(hit->fT) || !hit->fValid); | 290 SkASSERT(!approximately_zero(hit->fT) || !hit->fValid); |
291 SkOpSpan* span = hit->fSpan; | 291 SkOpSpan* span = hit->fSpan; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 #if 0 | 338 #if 0 |
339 SkASSERT(hitSegment->oppXor() ? (oppSum & 1) == (oSpanSum & 1) : opp
Sum == oSpanSum | 339 SkASSERT(hitSegment->oppXor() ? (oppSum & 1) == (oSpanSum & 1) : opp
Sum == oSpanSum |
340 || (abs(oppWind) == abs(lastOpp) | 340 || (abs(oppWind) == abs(lastOpp) |
341 && (oppSum ^ oppWind ^ lastOpp) == oSpanSum)); | 341 && (oppSum ^ oppWind ^ lastOpp) == oSpanSum)); |
342 #endif | 342 #endif |
343 } | 343 } |
344 if (sumSet) { | 344 if (sumSet) { |
345 if (this->globalState()->phase() == SkOpGlobalState::kFixWinding) { | 345 if (this->globalState()->phase() == SkOpGlobalState::kFixWinding) { |
346 hitSegment->contour()->setCcw(ccw); | 346 hitSegment->contour()->setCcw(ccw); |
347 } else { | 347 } else { |
348 (void) hitSegment->markAndChaseWinding(span, span->next(), windS
um, oppSum, NULL); | 348 (void) hitSegment->markAndChaseWinding(span, span->next(), windS
um, oppSum, nullptr); |
349 (void) hitSegment->markAndChaseWinding(span->next(), span, windS
um, oppSum, NULL); | 349 (void) hitSegment->markAndChaseWinding(span->next(), span, windS
um, oppSum, nullptr); |
350 } | 350 } |
351 } | 351 } |
352 if (operand) { | 352 if (operand) { |
353 SkTSwap(wind, oppWind); | 353 SkTSwap(wind, oppWind); |
354 } | 354 } |
355 last = &hit->fPt; | 355 last = &hit->fPt; |
356 this->globalState()->bumpNested(); | 356 this->globalState()->bumpNested(); |
357 } | 357 } |
358 return true; | 358 return true; |
359 } | 359 } |
360 | 360 |
361 SkOpSpan* SkOpSegment::findSortableTop(SkOpContour* contourHead) { | 361 SkOpSpan* SkOpSegment::findSortableTop(SkOpContour* contourHead) { |
362 SkOpSpan* span = &fHead; | 362 SkOpSpan* span = &fHead; |
363 SkOpSpanBase* next; | 363 SkOpSpanBase* next; |
364 do { | 364 do { |
365 next = span->next(); | 365 next = span->next(); |
366 if (span->done()) { | 366 if (span->done()) { |
367 continue; | 367 continue; |
368 } | 368 } |
369 if (span->windSum() != SK_MinS32) { | 369 if (span->windSum() != SK_MinS32) { |
370 return span; | 370 return span; |
371 } | 371 } |
372 if (span->sortableTop(contourHead)) { | 372 if (span->sortableTop(contourHead)) { |
373 return span; | 373 return span; |
374 } | 374 } |
375 } while (!next->final() && (span = next->upCast())); | 375 } while (!next->final() && (span = next->upCast())); |
376 return NULL; | 376 return nullptr; |
377 } | 377 } |
378 | 378 |
379 SkOpSpan* SkOpContour::findSortableTop(SkOpContour* contourHead) { | 379 SkOpSpan* SkOpContour::findSortableTop(SkOpContour* contourHead) { |
380 SkOpSegment* testSegment = &fHead; | 380 SkOpSegment* testSegment = &fHead; |
381 do { | 381 do { |
382 if (testSegment->done()) { | 382 if (testSegment->done()) { |
383 continue; | 383 continue; |
384 } | 384 } |
385 SkOpSpan* result = testSegment->findSortableTop(contourHead); | 385 SkOpSpan* result = testSegment->findSortableTop(contourHead); |
386 if (result) { | 386 if (result) { |
387 return result; | 387 return result; |
388 } | 388 } |
389 } while ((testSegment = testSegment->next())); | 389 } while ((testSegment = testSegment->next())); |
390 return NULL; | 390 return nullptr; |
391 } | 391 } |
392 | 392 |
393 SkOpSpan* FindSortableTop(SkOpContourHead* contourHead) { | 393 SkOpSpan* FindSortableTop(SkOpContourHead* contourHead) { |
394 for (int index = 0; index < SkOpGlobalState::kMaxWindingTries; ++index) { | 394 for (int index = 0; index < SkOpGlobalState::kMaxWindingTries; ++index) { |
395 SkOpContour* contour = contourHead; | 395 SkOpContour* contour = contourHead; |
396 do { | 396 do { |
397 if (contour->done()) { | 397 if (contour->done()) { |
398 continue; | 398 continue; |
399 } | 399 } |
400 SkOpSpan* result = contour->findSortableTop(contourHead); | 400 SkOpSpan* result = contour->findSortableTop(contourHead); |
401 if (result) { | 401 if (result) { |
402 return result; | 402 return result; |
403 } | 403 } |
404 } while ((contour = contour->next())); | 404 } while ((contour = contour->next())); |
405 } | 405 } |
406 return NULL; | 406 return nullptr; |
407 } | 407 } |
OLD | NEW |