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 |