| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "SkRegionPriv.h" | 8 #include "SkRegionPriv.h" |
| 9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
| 10 #include "SkScan.h" | 10 #include "SkScan.h" |
| 11 #include "SkTSort.h" |
| 11 #include "SkTDArray.h" | 12 #include "SkTDArray.h" |
| 12 #include "SkPath.h" | 13 #include "SkPath.h" |
| 13 | 14 |
| 14 // The rgnbuilder caller *seems* to pass short counts, possible often seens earl
y failure, so | 15 // The rgnbuilder caller *seems* to pass short counts, possible often seens earl
y failure, so |
| 15 // we may not want to promote this to a "std" routine just yet. | 16 // we may not want to promote this to a "std" routine just yet. |
| 16 static bool sk_memeq32(const int32_t* SK_RESTRICT a, const int32_t* SK_RESTRICT
b, int count) { | 17 static bool sk_memeq32(const int32_t* SK_RESTRICT a, const int32_t* SK_RESTRICT
b, int count) { |
| 17 for (int i = 0; i < count; ++i) { | 18 for (int i = 0; i < count; ++i) { |
| 18 if (a[i] != b[i]) { | 19 if (a[i] != b[i]) { |
| 19 return false; | 20 return false; |
| 20 } | 21 } |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 prev = edge; | 470 prev = edge; |
| 470 edge = edge->fNext; | 471 edge = edge->fNext; |
| 471 count += 1; | 472 count += 1; |
| 472 prev->fFlags = 0; | 473 prev->fFlags = 0; |
| 473 } while (edge != base); | 474 } while (edge != base); |
| 474 path->lineTo(SkIntToScalar(prev->fX), SkIntToScalar(prev->fY1)); // V | 475 path->lineTo(SkIntToScalar(prev->fX), SkIntToScalar(prev->fY1)); // V |
| 475 path->close(); | 476 path->close(); |
| 476 return count; | 477 return count; |
| 477 } | 478 } |
| 478 | 479 |
| 479 #include "SkTSearch.h" | 480 struct EdgeLT { |
| 480 | 481 bool operator()(const Edge& a, const Edge& b) const { |
| 481 static int EdgeProc(const Edge* a, const Edge* b) { | 482 return (a.fX == b.fX) ? a.top() < b.top() : a.fX < b.fX; |
| 482 return (a->fX == b->fX) ? a->top() - b->top() : a->fX - b->fX; | 483 } |
| 483 } | 484 }; |
| 484 | 485 |
| 485 bool SkRegion::getBoundaryPath(SkPath* path) const { | 486 bool SkRegion::getBoundaryPath(SkPath* path) const { |
| 486 // path could safely be NULL if we're empty, but the caller shouldn't | 487 // path could safely be NULL if we're empty, but the caller shouldn't |
| 487 // *know* that | 488 // *know* that |
| 488 SkASSERT(path); | 489 SkASSERT(path); |
| 489 | 490 |
| 490 if (this->isEmpty()) { | 491 if (this->isEmpty()) { |
| 491 return false; | 492 return false; |
| 492 } | 493 } |
| 493 | 494 |
| 494 const SkIRect& bounds = this->getBounds(); | 495 const SkIRect& bounds = this->getBounds(); |
| 495 | 496 |
| 496 if (this->isRect()) { | 497 if (this->isRect()) { |
| 497 SkRect r; | 498 SkRect r; |
| 498 r.set(bounds); // this converts the ints to scalars | 499 r.set(bounds); // this converts the ints to scalars |
| 499 path->addRect(r); | 500 path->addRect(r); |
| 500 return true; | 501 return true; |
| 501 } | 502 } |
| 502 | 503 |
| 503 SkRegion::Iterator iter(*this); | 504 SkRegion::Iterator iter(*this); |
| 504 SkTDArray<Edge> edges; | 505 SkTDArray<Edge> edges; |
| 505 | 506 |
| 506 for (const SkIRect& r = iter.rect(); !iter.done(); iter.next()) { | 507 for (const SkIRect& r = iter.rect(); !iter.done(); iter.next()) { |
| 507 Edge* edge = edges.append(2); | 508 Edge* edge = edges.append(2); |
| 508 edge[0].set(r.fLeft, r.fBottom, r.fTop); | 509 edge[0].set(r.fLeft, r.fBottom, r.fTop); |
| 509 edge[1].set(r.fRight, r.fTop, r.fBottom); | 510 edge[1].set(r.fRight, r.fTop, r.fBottom); |
| 510 } | 511 } |
| 511 qsort(edges.begin(), edges.count(), sizeof(Edge), SkCastForQSort(EdgeProc)); | |
| 512 | 512 |
| 513 int count = edges.count(); | 513 int count = edges.count(); |
| 514 Edge* start = edges.begin(); | 514 Edge* start = edges.begin(); |
| 515 Edge* stop = start + count; | 515 Edge* stop = start + count; |
| 516 SkTQSort<Edge>(start, stop - 1, EdgeLT()); |
| 517 |
| 516 Edge* e; | 518 Edge* e; |
| 517 | |
| 518 for (e = start; e != stop; e++) { | 519 for (e = start; e != stop; e++) { |
| 519 find_link(e, stop); | 520 find_link(e, stop); |
| 520 } | 521 } |
| 521 | 522 |
| 522 #ifdef SK_DEBUG | 523 #ifdef SK_DEBUG |
| 523 for (e = start; e != stop; e++) { | 524 for (e = start; e != stop; e++) { |
| 524 SkASSERT(e->fNext != NULL); | 525 SkASSERT(e->fNext != NULL); |
| 525 SkASSERT(e->fFlags == Edge::kCompleteLink); | 526 SkASSERT(e->fFlags == Edge::kCompleteLink); |
| 526 } | 527 } |
| 527 #endif | 528 #endif |
| 528 | 529 |
| 529 path->incReserve(count << 1); | 530 path->incReserve(count << 1); |
| 530 do { | 531 do { |
| 531 SkASSERT(count > 1); | 532 SkASSERT(count > 1); |
| 532 count -= extract_path(start, stop, path); | 533 count -= extract_path(start, stop, path); |
| 533 } while (count > 0); | 534 } while (count > 0); |
| 534 | 535 |
| 535 return true; | 536 return true; |
| 536 } | 537 } |
| OLD | NEW |