Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      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 
      8 
      9 #include "SkAtomics.h"
     10 #include "SkRegionPriv.h"
     11 #include "SkTemplates.h"
     12 #include "SkUtils.h"
     13 
     14 /* Region Layout
     15  *
     16  *  TOP
     17  *
     18  *  [ Bottom, X-Intervals, [Left, Right]..., X-Sentinel ]
     19  *  ...
     20  *
     21  *  Y-Sentinel
     22  */
     23 
     24 SkDEBUGCODE(int32_t gRgnAllocCounter;)
     25 
     26 /////////////////////////////////////////////////////////////////////////////////////////////////
     27 
     28 /*  Pass in the beginning with the intervals.
     29  *  We back up 1 to read the interval-count.
     30  *  Return the beginning of the next scanline (i.e. the next Y-value)
     31  */
     32 static SkRegion::RunType* skip_intervals(const SkRegion::RunType runs[]) {
     33     int intervals = runs[-1];
     34 #ifdef SK_DEBUG
     35     if (intervals > 0) {
     36         SkASSERT(runs[0] < runs[1]);
     37         SkASSERT(runs[1] < SkRegion::kRunTypeSentinel);
     38     } else {
     39         SkASSERT(0 == intervals);
     40         SkASSERT(SkRegion::kRunTypeSentinel == runs[0]);
     41     }
     42 #endif
     43     runs += intervals * 2 + 1;
     44     return const_cast<SkRegion::RunType*>(runs);
     45 }
     46 
     47 bool SkRegion::RunsAreARect(const SkRegion::RunType runs[], int count,
     48                             SkIRect* bounds) {
     49     assert_sentinel(runs[0], false);    // top
     50     SkASSERT(count >= kRectRegionRuns);
     51 
     52     if (count == kRectRegionRuns) {
     53         assert_sentinel(runs[1], false);    // bottom
     54         SkASSERT(1 == runs[2]);
     55         assert_sentinel(runs[3], false);    // left
     56         assert_sentinel(runs[4], false);    // right
     57         assert_sentinel(runs[5], true);
     58         assert_sentinel(runs[6], true);
     59 
     60         SkASSERT(runs[0] < runs[1]);    // valid height
     61         SkASSERT(runs[3] < runs[4]);    // valid width
     62 
     63         bounds->set(runs[3], runs[0], runs[4], runs[1]);
     64         return true;
     65     }
     66     return false;
     67 }
     68 
     69 //////////////////////////////////////////////////////////////////////////
     70 
     71 SkRegion::SkRegion() {
     72     fBounds.set(0, 0, 0, 0);
     73     fRunHead = SkRegion_gEmptyRunHeadPtr;
     74 }
     75 
     76 SkRegion::SkRegion(const SkRegion& src) {
     77     fRunHead = SkRegion_gEmptyRunHeadPtr;   // just need a value that won't trigger sk_free(fRunHead)
     78     this->setRegion(src);
     79 }
     80 
     81 SkRegion::SkRegion(const SkIRect& rect) {
     82     fRunHead = SkRegion_gEmptyRunHeadPtr;   // just need a value that won't trigger sk_free(fRunHead)
     83     this->setRect(rect);
     84 }
     85 
     86 SkRegion::~SkRegion() {
     87     this->freeRuns();
     88 }
     89 
     90 void SkRegion::freeRuns() {
     91     if (this->isComplex()) {
     92         SkASSERT(fRunHead->fRefCnt >= 1);
     93         if (sk_atomic_dec(&fRunHead->fRefCnt) == 1) {
     94             //SkASSERT(gRgnAllocCounter > 0);
     95             //SkDEBUGCODE(sk_atomic_dec(&gRgnAllocCounter));
     96             //SkDEBUGF(("************** gRgnAllocCounter::free %d\n", gRgnAllocCounter));
     97             sk_free(fRunHead);
     98         }
     99     }
    100 }
    101 
    102 void SkRegion::allocateRuns(int count, int ySpanCount, int intervalCount) {
    103     fRunHead = RunHead::Alloc(count, ySpanCount, intervalCount);
    104 }
    105 
    106 void SkRegion::allocateRuns(int count) {
    107     fRunHead = RunHead::Alloc(count);
    108 }
    109 
    110 void SkRegion::allocateRuns(const RunHead& head) {
    111     fRunHead = RunHead::Alloc(head.fRunCount,
    112                               head.getYSpanCount(),
    113                               head.getIntervalCount());
    114 }
    115 
    116 SkRegion& SkRegion::operator=(const SkRegion& src) {
    117     (void)this->setRegion(src);
    118     return *this;
    119 }
    120 
    121 void SkRegion::swap(SkRegion& other) {
    122     SkTSwap<SkIRect>(fBounds, other.fBounds);
    123     SkTSwap<RunHead*>(fRunHead, other.fRunHead);
    124 }
    125 
    126 int SkRegion::computeRegionComplexity() const {
    127   if (this->isEmpty()) {
    128     return 0;
    129   } else if (this->isRect()) {
    130     return 1;
    131   }
    132   return fRunHead->getIntervalCount();
    133 }
    134 
    135 bool SkRegion::setEmpty() {
    136     this->freeRuns();
    137     fBounds.set(0, 0, 0, 0);
    138     fRunHead = SkRegion_gEmptyRunHeadPtr;
    139     return false;
    140 }
    141 
    142 bool SkRegion::setRect(int32_t left, int32_t top,
    143                        int32_t right, int32_t bottom) {
    144     if (left >= right || top >= bottom) {
    145         return this->setEmpty();
    146     }
    147     this->freeRuns();
    148     fBounds.set(left, top, right, bottom);
    149     fRunHead = SkRegion_gRectRunHeadPtr;
    150     return true;
    151 }
    152 
    153 bool SkRegion::setRect(const SkIRect& r) {
    154     return this->setRect(r.fLeft, r.fTop, r.fRight, r.fBottom);
    155 }
    156 
    157 bool SkRegion::setRegion(const SkRegion& src) {
    158     if (this != &src) {
    159         this->freeRuns();
    160 
    161         fBounds = src.fBounds;
    162         fRunHead = src.fRunHead;
    163         if (this->isComplex()) {
    164             sk_atomic_inc(&fRunHead->fRefCnt);
    165         }
    166     }
    167     return fRunHead != SkRegion_gEmptyRunHeadPtr;
    168 }
    169 
    170 bool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op) {
    171     SkRegion tmp(rect);
    172 
    173     return this->op(tmp, rgn, op);
    174 }
    175 
    176 bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op) {
    177     SkRegion tmp(rect);
    178 
    179     return this->op(rgn, tmp, op);
    180 }
    181 
    182 ///////////////////////////////////////////////////////////////////////////////
    183 
    184 #ifdef SK_BUILD_FOR_ANDROID
    185 #include <stdio.h>
    186 char* SkRegion::toString() {
    187     Iterator iter(*this);
    188     int count = 0;
    189     while (!iter.done()) {
    190         count++;
    191         iter.next();
    192     }
    193     // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() and '\0'
    194     const int max = (count*((11*4)+5))+11+1;
    195     char* result = (char*)sk_malloc_throw(max);
    196     if (result == nullptr) {
    197         return nullptr;
    198     }
    199     count = snprintf(result, max, "SkRegion(");
    200     iter.reset(*this);
    201     while (!iter.done()) {
    202         const SkIRect& r = iter.rect();
    203         count += snprintf(result+count, max - count,
    204                 "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRight, r.fBottom);
    205         iter.next();
    206     }
    207     count += snprintf(result+count, max - count, ")");
    208     return result;
    209 }
    210 #endif
    211 
    212 ///////////////////////////////////////////////////////////////////////////////
    213 
    214 int SkRegion::count_runtype_values(int* itop, int* ibot) const {
    215     int maxT;
    216 
    217     if (this->isRect()) {
    218         maxT = 2;
    219     } else {
    220         SkASSERT(this->isComplex());
    221         maxT = fRunHead->getIntervalCount() * 2;
    222     }
    223     *itop = fBounds.fTop;
    224     *ibot = fBounds.fBottom;
    225     return maxT;
    226 }
    227 
    228 static bool isRunCountEmpty(int count) {
    229     return count <= 2;
    230 }
    231 
    232 bool SkRegion::setRuns(RunType runs[], int count) {
    233     SkDEBUGCODE(this->validate();)
    234     SkASSERT(count > 0);
    235 
    236     if (isRunCountEmpty(count)) {
    237     //  SkDEBUGF(("setRuns: empty\n"));
    238         assert_sentinel(runs[count-1], true);
    239         return this->setEmpty();
    240     }
    241 
    242     // trim off any empty spans from the top and bottom
    243     // weird I should need this, perhaps op() could be smarter...
    244     if (count > kRectRegionRuns) {
    245         RunType* stop = runs + count;
    246         assert_sentinel(runs[0], false);    // top
    247         assert_sentinel(runs[1], false);    // bottom
    248         // runs[2] is uncomputed intervalCount
    249 
    250         if (runs[3] == SkRegion::kRunTypeSentinel) {  // should be first left...
    251             runs += 3;  // skip empty initial span
    252             runs[0] = runs[-2]; // set new top to prev bottom
    253             assert_sentinel(runs[1], false);    // bot: a sentinal would mean two in a row
    254             assert_sentinel(runs[2], false);    // intervalcount
    255             assert_sentinel(runs[3], false);    // left
    256             assert_sentinel(runs[4], false);    // right
    257         }
    258 
    259         assert_sentinel(stop[-1], true);
    260         assert_sentinel(stop[-2], true);
    261 
    262         // now check for a trailing empty span
    263         if (stop[-5] == SkRegion::kRunTypeSentinel) { // eek, stop[-4] was a bottom with no x-runs
    264             stop[-4] = SkRegion::kRunTypeSentinel;    // kill empty last span
    265             stop -= 3;
    266             assert_sentinel(stop[-1], true);    // last y-sentinel
    267             assert_sentinel(stop[-2], true);    // last x-sentinel
    268             assert_sentinel(stop[-3], false);   // last right
    269             assert_sentinel(stop[-4], false);   // last left
    270             assert_sentinel(stop[-5], false);   // last interval-count
    271             assert_sentinel(stop[-6], false);   // last bottom
    272         }
    273         count = (int)(stop - runs);
    274     }
    275 
    276     SkASSERT(count >= kRectRegionRuns);
    277 
    278     if (SkRegion::RunsAreARect(runs, count, &fBounds)) {
    279         return this->setRect(fBounds);
    280     }
    281 
    282     //  if we get here, we need to become a complex region
    283 
    284     if (!this->isComplex() || fRunHead->fRunCount != count) {
    285         this->freeRuns();
    286         this->allocateRuns(count);
    287         SkASSERT(this->isComplex());
    288     }
    289 
    290     // must call this before we can write directly into runs()
    291     // in case we are sharing the buffer with another region (copy on write)
    292     fRunHead = fRunHead->ensureWritable();
    293     memcpy(fRunHead->writable_runs(), runs, count * sizeof(RunType));
    294     fRunHead->computeRunBounds(&fBounds);
    295 
    296     SkDEBUGCODE(this->validate();)
    297 
    298     return true;
    299 }
    300 
    301 void SkRegion::BuildRectRuns(const SkIRect& bounds,
    302                              RunType runs[kRectRegionRuns]) {
    303     runs[0] = bounds.fTop;
    304     runs[1] = bounds.fBottom;
    305     runs[2] = 1;    // 1 interval for this scanline
    306     runs[3] = bounds.fLeft;
    307     runs[4] = bounds.fRight;
    308     runs[5] = kRunTypeSentinel;
    309     runs[6] = kRunTypeSentinel;
    310 }
    311 
    312 bool SkRegion::contains(int32_t x, int32_t y) const {
    313     SkDEBUGCODE(this->validate();)
    314 
    315     if (!fBounds.contains(x, y)) {
    316         return false;
    317     }
    318     if (this->isRect()) {
    319         return true;
    320     }
    321     SkASSERT(this->isComplex());
    322 
    323     const RunType* runs = fRunHead->findScanline(y);
    324 
    325     // Skip the Bottom and IntervalCount
    326     runs += 2;
    327 
    328     // Just walk this scanline, checking each interval. The X-sentinel will
    329     // appear as a left-inteval (runs[0]) and should abort the search.
    330     //
    331     // We could do a bsearch, using interval-count (runs[1]), but need to time
    332     // when that would be worthwhile.
    333     //
    334     for (;;) {
    335         if (x < runs[0]) {
    336             break;
    337         }
    338         if (x < runs[1]) {
    339             return true;
    340         }
    341         runs += 2;
    342     }
    343     return false;
    344 }
    345 
    346 static SkRegion::RunType scanline_bottom(const SkRegion::RunType runs[]) {
    347     return runs[0];
    348 }
    349 
    350 static const SkRegion::RunType* scanline_next(const SkRegion::RunType runs[]) {
    351     // skip [B N [L R]... S]
    352     return runs + 2 + runs[1] * 2 + 1;
    353 }
    354 
    355 static bool scanline_contains(const SkRegion::RunType runs[],
    356                               SkRegion::RunType L, SkRegion::RunType R) {
    357     runs += 2;  // skip Bottom and IntervalCount
    358     for (;;) {
    359         if (L < runs[0]) {
    360             break;
    361         }
    362         if (R <= runs[1]) {
    363             return true;
    364         }
    365         runs += 2;
    366     }
    367     return false;
    368 }
    369 
    370 bool SkRegion::contains(const SkIRect& r) const {
    371     SkDEBUGCODE(this->validate();)
    372 
    373     if (!fBounds.contains(r)) {
    374         return false;
    375     }
    376     if (this->isRect()) {
    377         return true;
    378     }
    379     SkASSERT(this->isComplex());
    380 
    381     const RunType* scanline = fRunHead->findScanline(r.fTop);
    382     for (;;) {
    383         if (!scanline_contains(scanline, r.fLeft, r.fRight)) {
    384             return false;
    385         }
    386         if (r.fBottom <= scanline_bottom(scanline)) {
    387             break;
    388         }
    389         scanline = scanline_next(scanline);
    390     }
    391     return true;
    392 }
    393 
    394 bool SkRegion::contains(const SkRegion& rgn) const {
    395     SkDEBUGCODE(this->validate();)
    396     SkDEBUGCODE(rgn.validate();)
    397 
    398     if (this->isEmpty() || rgn.isEmpty() || !fBounds.contains(rgn.fBounds)) {
    399         return false;
    400     }
    401     if (this->isRect()) {
    402         return true;
    403     }
    404     if (rgn.isRect()) {
    405         return this->contains(rgn.getBounds());
    406     }
    407 
    408     /*
    409      *  A contains B is equivalent to
    410      *  B - A == 0
    411      */
    412     return !Oper(rgn, *this, kDifference_Op, nullptr);
    413 }
    414 
    415 const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[],
    416                                            int* intervals) const {
    417     SkASSERT(tmpStorage && intervals);
    418     const RunType* runs = tmpStorage;
    419 
    420     if (this->isEmpty()) {
    421         tmpStorage[0] = kRunTypeSentinel;
    422         *intervals = 0;
    423     } else if (this->isRect()) {
    424         BuildRectRuns(fBounds, tmpStorage);
    425         *intervals = 1;
    426     } else {
    427         runs = fRunHead->readonly_runs();
    428         *intervals = fRunHead->getIntervalCount();
    429     }
    430     return runs;
    431 }
    432 
    433 ///////////////////////////////////////////////////////////////////////////////
    434 
    435 static bool scanline_intersects(const SkRegion::RunType runs[],
    436                                 SkRegion::RunType L, SkRegion::RunType R) {
    437     runs += 2;  // skip Bottom and IntervalCount
    438     for (;;) {
    439         if (R <= runs[0]) {
    440             break;
    441         }
    442         if (L < runs[1]) {
    443             return true;
    444         }
    445         runs += 2;
    446     }
    447     return false;
    448 }
    449 
    450 bool SkRegion::intersects(const SkIRect& r) const {
    451     SkDEBUGCODE(this->validate();)
    452 
    453     if (this->isEmpty() || r.isEmpty()) {
    454         return false;
    455     }
    456 
    457     SkIRect sect;
    458     if (!sect.intersect(fBounds, r)) {
    459         return false;
    460     }
    461     if (this->isRect()) {
    462         return true;
    463     }
    464     SkASSERT(this->isComplex());
    465 
    466     const RunType* scanline = fRunHead->findScanline(sect.fTop);
    467     for (;;) {
    468         if (scanline_intersects(scanline, sect.fLeft, sect.fRight)) {
    469             return true;
    470         }
    471         if (sect.fBottom <= scanline_bottom(scanline)) {
    472             break;
    473         }
    474         scanline = scanline_next(scanline);
    475     }
    476     return false;
    477 }
    478 
    479 bool SkRegion::intersects(const SkRegion& rgn) const {
    480     if (this->isEmpty() || rgn.isEmpty()) {
    481         return false;
    482     }
    483 
    484     if (!SkIRect::Intersects(fBounds, rgn.fBounds)) {
    485         return false;
    486     }
    487 
    488     bool weAreARect = this->isRect();
    489     bool theyAreARect = rgn.isRect();
    490 
    491     if (weAreARect && theyAreARect) {
    492         return true;
    493     }
    494     if (weAreARect) {
    495         return rgn.intersects(this->getBounds());
    496     }
    497     if (theyAreARect) {
    498         return this->intersects(rgn.getBounds());
    499     }
    500 
    501     // both of us are complex
    502     return Oper(*this, rgn, kIntersect_Op, nullptr);
    503 }
    504 
    505 ///////////////////////////////////////////////////////////////////////////////
    506 
    507 bool SkRegion::operator==(const SkRegion& b) const {
    508     SkDEBUGCODE(validate();)
    509     SkDEBUGCODE(b.validate();)
    510 
    511     if (this == &b) {
    512         return true;
    513     }
    514     if (fBounds != b.fBounds) {
    515         return false;
    516     }
    517 
    518     const SkRegion::RunHead* ah = fRunHead;
    519     const SkRegion::RunHead* bh = b.fRunHead;
    520 
    521     // this catches empties and rects being equal
    522     if (ah == bh) {
    523         return true;
    524     }
    525     // now we insist that both are complex (but different ptrs)
    526     if (!this->isComplex() || !b.isComplex()) {
    527         return false;
    528     }
    529     return  ah->fRunCount == bh->fRunCount &&
    530             !memcmp(ah->readonly_runs(), bh->readonly_runs(),
    531                     ah->fRunCount * sizeof(SkRegion::RunType));
    532 }
    533 
    534 void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
    535     SkDEBUGCODE(this->validate();)
    536 
    537     if (nullptr == dst) {
    538         return;
    539     }
    540     if (this->isEmpty()) {
    541         dst->setEmpty();
    542     } else if (this->isRect()) {
    543         dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy,
    544                      fBounds.fRight + dx, fBounds.fBottom + dy);
    545     } else {
    546         if (this == dst) {
    547             dst->fRunHead = dst->fRunHead->ensureWritable();
    548         } else {
    549             SkRegion    tmp;
    550             tmp.allocateRuns(*fRunHead);
    551             SkASSERT(tmp.isComplex());
    552             tmp.fBounds = fBounds;
    553             dst->swap(tmp);
    554         }
    555 
    556         dst->fBounds.offset(dx, dy);
    557 
    558         const RunType*  sruns = fRunHead->readonly_runs();
    559         RunType*        druns = dst->fRunHead->writable_runs();
    560 
    561         *druns++ = (SkRegion::RunType)(*sruns++ + dy);    // top
    562         for (;;) {
    563             int bottom = *sruns++;
    564             if (bottom == kRunTypeSentinel) {
    565                 break;
    566             }
    567             *druns++ = (SkRegion::RunType)(bottom + dy);  // bottom;
    568             *druns++ = *sruns++;    // copy intervalCount;
    569             for (;;) {
    570                 int x = *sruns++;
    571                 if (x == kRunTypeSentinel) {
    572                     break;
    573                 }
    574                 *druns++ = (SkRegion::RunType)(x + dx);
    575                 *druns++ = (SkRegion::RunType)(*sruns++ + dx);
    576             }
    577             *druns++ = kRunTypeSentinel;    // x sentinel
    578         }
    579         *druns++ = kRunTypeSentinel;    // y sentinel
    580 
    581         SkASSERT(sruns - fRunHead->readonly_runs() == fRunHead->fRunCount);
    582         SkASSERT(druns - dst->fRunHead->readonly_runs() == dst->fRunHead->fRunCount);
    583     }
    584 
    585     SkDEBUGCODE(this->validate();)
    586 }
    587 
    588 ///////////////////////////////////////////////////////////////////////////////
    589 
    590 bool SkRegion::setRects(const SkIRect rects[], int count) {
    591     if (0 == count) {
    592         this->setEmpty();
    593     } else {
    594         this->setRect(rects[0]);
    595         for (int i = 1; i < count; i++) {
    596             this->op(rects[i], kUnion_Op);
    597         }
    598     }
    599     return !this->isEmpty();
    600 }
    601 
    602 ///////////////////////////////////////////////////////////////////////////////
    603 
    604 #if defined _WIN32  // disable warning : local variable used without having been initialized
    605 #pragma warning ( push )
    606 #pragma warning ( disable : 4701 )
    607 #endif
    608 
    609 #ifdef SK_DEBUG
    610 static void assert_valid_pair(int left, int rite)
    611 {
    612     SkASSERT(left == SkRegion::kRunTypeSentinel || left < rite);
    613 }
    614 #else
    615     #define assert_valid_pair(left, rite)
    616 #endif
    617 
    618 struct spanRec {
    619     const SkRegion::RunType*    fA_runs;
    620     const SkRegion::RunType*    fB_runs;
    621     int                         fA_left, fA_rite, fB_left, fB_rite;
    622     int                         fLeft, fRite, fInside;
    623 
    624     void init(const SkRegion::RunType a_runs[],
    625               const SkRegion::RunType b_runs[]) {
    626         fA_left = *a_runs++;
    627         fA_rite = *a_runs++;
    628         fB_left = *b_runs++;
    629         fB_rite = *b_runs++;
    630 
    631         fA_runs = a_runs;
    632         fB_runs = b_runs;
    633     }
    634 
    635     bool done() const {
    636         SkASSERT(fA_left <= SkRegion::kRunTypeSentinel);
    637         SkASSERT(fB_left <= SkRegion::kRunTypeSentinel);
    638         return fA_left == SkRegion::kRunTypeSentinel &&
    639                fB_left == SkRegion::kRunTypeSentinel;
    640     }
    641 
    642     void next() {
    643         assert_valid_pair(fA_left, fA_rite);
    644         assert_valid_pair(fB_left, fB_rite);
    645 
    646         int     inside, left, rite SK_INIT_TO_AVOID_WARNING;
    647         bool    a_flush = false;
    648         bool    b_flush = false;
    649 
    650         int a_left = fA_left;
    651         int a_rite = fA_rite;
    652         int b_left = fB_left;
    653         int b_rite = fB_rite;
    654 
    655         if (a_left < b_left) {
    656             inside = 1;
    657             left = a_left;
    658             if (a_rite <= b_left) {   // [...] <...>
    659                 rite = a_rite;
    660                 a_flush = true;
    661             } else { // [...<..]...> or [...<...>...]
    662                 rite = a_left = b_left;
    663             }
    664         } else if (b_left < a_left) {
    665             inside = 2;
    666             left = b_left;
    667             if (b_rite <= a_left) {   // [...] <...>
    668                 rite = b_rite;
    669                 b_flush = true;
    670             } else {    // [...<..]...> or [...<...>...]
    671                 rite = b_left = a_left;
    672             }
    673         } else {    // a_left == b_left
    674             inside = 3;
    675             left = a_left;  // or b_left
    676             if (a_rite <= b_rite) {
    677                 rite = b_left = a_rite;
    678                 a_flush = true;
    679             }
    680             if (b_rite <= a_rite) {
    681                 rite = a_left = b_rite;
    682                 b_flush = true;
    683             }
    684         }
    685 
    686         if (a_flush) {
    687             a_left = *fA_runs++;
    688             a_rite = *fA_runs++;
    689         }
    690         if (b_flush) {
    691             b_left = *fB_runs++;
    692             b_rite = *fB_runs++;
    693         }
    694 
    695         SkASSERT(left <= rite);
    696 
    697         // now update our state
    698         fA_left = a_left;
    699         fA_rite = a_rite;
    700         fB_left = b_left;
    701         fB_rite = b_rite;
    702 
    703         fLeft = left;
    704         fRite = rite;
    705         fInside = inside;
    706     }
    707 };
    708 
    709 static SkRegion::RunType* operate_on_span(const SkRegion::RunType a_runs[],
    710                                           const SkRegion::RunType b_runs[],
    711                                           SkRegion::RunType dst[],
    712                                           int min, int max) {
    713     spanRec rec;
    714     bool    firstInterval = true;
    715 
    716     rec.init(a_runs, b_runs);
    717 
    718     while (!rec.done()) {
    719         rec.next();
    720 
    721         int left = rec.fLeft;
    722         int rite = rec.fRite;
    723 
    724         // add left,rite to our dst buffer (checking for coincidence
    725         if ((unsigned)(rec.fInside - min) <= (unsigned)(max - min) &&
    726                 left < rite) {    // skip if equal
    727             if (firstInterval || dst[-1] < left) {
    728                 *dst++ = (SkRegion::RunType)(left);
    729                 *dst++ = (SkRegion::RunType)(rite);
    730                 firstInterval = false;
    731             } else {
    732                 // update the right edge
    733                 dst[-1] = (SkRegion::RunType)(rite);
    734             }
    735         }
    736     }
    737 
    738     *dst++ = SkRegion::kRunTypeSentinel;
    739     return dst;
    740 }
    741 
    742 #if defined _WIN32
    743 #pragma warning ( pop )
    744 #endif
    745 
    746 static const struct {
    747     uint8_t fMin;
    748     uint8_t fMax;
    749 } gOpMinMax[] = {
    750     { 1, 1 },   // Difference
    751     { 3, 3 },   // Intersection
    752     { 1, 3 },   // Union
    753     { 1, 2 }    // XOR
    754 };
    755 
    756 class RgnOper {
    757 public:
    758     RgnOper(int top, SkRegion::RunType dst[], SkRegion::Op op) {
    759         // need to ensure that the op enum lines up with our minmax array
    760         SkASSERT(SkRegion::kDifference_Op == 0);
    761         SkASSERT(SkRegion::kIntersect_Op == 1);
    762         SkASSERT(SkRegion::kUnion_Op == 2);
    763         SkASSERT(SkRegion::kXOR_Op == 3);
    764         SkASSERT((unsigned)op <= 3);
    765 
    766         fStartDst = dst;
    767         fPrevDst = dst + 1;
    768         fPrevLen = 0;       // will never match a length from operate_on_span
    769         fTop = (SkRegion::RunType)(top);    // just a first guess, we might update this
    770 
    771         fMin = gOpMinMax[op].fMin;
    772         fMax = gOpMinMax[op].fMax;
    773     }
    774 
    775     void addSpan(int bottom, const SkRegion::RunType a_runs[],
    776                  const SkRegion::RunType b_runs[]) {
    777         // skip X values and slots for the next Y+intervalCount
    778         SkRegion::RunType*  start = fPrevDst + fPrevLen + 2;
    779         // start points to beginning of dst interval
    780         SkRegion::RunType*  stop = operate_on_span(a_runs, b_runs, start, fMin, fMax);
    781         size_t              len = stop - start;
    782         SkASSERT(len >= 1 && (len & 1) == 1);
    783         SkASSERT(SkRegion::kRunTypeSentinel == stop[-1]);
    784 
    785         if (fPrevLen == len &&
    786             (1 == len || !memcmp(fPrevDst, start,
    787                                  (len - 1) * sizeof(SkRegion::RunType)))) {
    788             // update Y value
    789             fPrevDst[-2] = (SkRegion::RunType)(bottom);
    790         } else {    // accept the new span
    791             if (len == 1 && fPrevLen == 0) {
    792                 fTop = (SkRegion::RunType)(bottom); // just update our bottom
    793             } else {
    794                 start[-2] = (SkRegion::RunType)(bottom);
    795                 start[-1] = SkToS32(len >> 1);
    796                 fPrevDst = start;
    797                 fPrevLen = len;
    798             }
    799         }
    800     }
    801 
    802     int flush() {
    803         fStartDst[0] = fTop;
    804         fPrevDst[fPrevLen] = SkRegion::kRunTypeSentinel;
    805         return (int)(fPrevDst - fStartDst + fPrevLen + 1);
    806     }
    807 
    808     bool isEmpty() const { return 0 == fPrevLen; }
    809 
    810     uint8_t fMin, fMax;
    811 
    812 private:
    813     SkRegion::RunType*  fStartDst;
    814     SkRegion::RunType*  fPrevDst;
    815     size_t              fPrevLen;
    816     SkRegion::RunType   fTop;
    817 };
    818 
    819 // want a unique value to signal that we exited due to quickExit
    820 #define QUICK_EXIT_TRUE_COUNT   (-1)
    821 
    822 static int operate(const SkRegion::RunType a_runs[],
    823                    const SkRegion::RunType b_runs[],
    824                    SkRegion::RunType dst[],
    825                    SkRegion::Op op,
    826                    bool quickExit) {
    827     const SkRegion::RunType gEmptyScanline[] = {
    828         0,  // dummy bottom value
    829         0,  // zero intervals
    830         SkRegion::kRunTypeSentinel,
    831         // just need a 2nd value, since spanRec.init() reads 2 values, even
    832         // though if the first value is the sentinel, it ignores the 2nd value.
    833         // w/o the 2nd value here, we might read uninitialized memory.
    834         // This happens when we are using gSentinel, which is pointing at
    835         // our sentinel value.
    836         0
    837     };
    838     const SkRegion::RunType* const gSentinel = &gEmptyScanline[2];
    839 
    840     int a_top = *a_runs++;
    841     int a_bot = *a_runs++;
    842     int b_top = *b_runs++;
    843     int b_bot = *b_runs++;
    844 
    845     a_runs += 1;    // skip the intervalCount;
    846     b_runs += 1;    // skip the intervalCount;
    847 
    848     // Now a_runs and b_runs to their intervals (or sentinel)
    849 
    850     assert_sentinel(a_top, false);
    851     assert_sentinel(a_bot, false);
    852     assert_sentinel(b_top, false);
    853     assert_sentinel(b_bot, false);
    854 
    855     RgnOper oper(SkMin32(a_top, b_top), dst, op);
    856 
    857     int prevBot = SkRegion::kRunTypeSentinel; // so we fail the first test
    858 
    859     while (a_bot < SkRegion::kRunTypeSentinel ||
    860            b_bot < SkRegion::kRunTypeSentinel) {
    861         int                         top, bot SK_INIT_TO_AVOID_WARNING;
    862         const SkRegion::RunType*    run0 = gSentinel;
    863         const SkRegion::RunType*    run1 = gSentinel;
    864         bool                        a_flush = false;
    865         bool                        b_flush = false;
    866 
    867         if (a_top < b_top) {
    868             top = a_top;
    869             run0 = a_runs;
    870             if (a_bot <= b_top) {   // [...] <...>
    871                 bot = a_bot;
    872                 a_flush = true;
    873             } else {  // [...<..]...> or [...<...>...]
    874                 bot = a_top = b_top;
    875             }
    876         } else if (b_top < a_top) {
    877             top = b_top;
    878             run1 = b_runs;
    879             if (b_bot <= a_top) {   // [...] <...>
    880                 bot = b_bot;
    881                 b_flush = true;
    882             } else {    // [...<..]...> or [...<...>...]
    883                 bot = b_top = a_top;
    884             }
    885         } else {    // a_top == b_top
    886             top = a_top;    // or b_top
    887             run0 = a_runs;
    888             run1 = b_runs;
    889             if (a_bot <= b_bot) {
    890                 bot = b_top = a_bot;
    891                 a_flush = true;
    892             }
    893             if (b_bot <= a_bot) {
    894                 bot = a_top = b_bot;
    895                 b_flush = true;
    896             }
    897         }
    898 
    899         if (top > prevBot) {
    900             oper.addSpan(top, gSentinel, gSentinel);
    901         }
    902         oper.addSpan(bot, run0, run1);
    903 
    904         if (quickExit && !oper.isEmpty()) {
    905             return QUICK_EXIT_TRUE_COUNT;
    906         }
    907 
    908         if (a_flush) {
    909             a_runs = skip_intervals(a_runs);
    910             a_top = a_bot;
    911             a_bot = *a_runs++;
    912             a_runs += 1;    // skip uninitialized intervalCount
    913             if (a_bot == SkRegion::kRunTypeSentinel) {
    914                 a_top = a_bot;
    915             }
    916         }
    917         if (b_flush) {
    918             b_runs = skip_intervals(b_runs);
    919             b_top = b_bot;
    920             b_bot = *b_runs++;
    921             b_runs += 1;    // skip uninitialized intervalCount
    922             if (b_bot == SkRegion::kRunTypeSentinel) {
    923                 b_top = b_bot;
    924             }
    925         }
    926 
    927         prevBot = bot;
    928     }
    929     return oper.flush();
    930 }
    931 
    932 ///////////////////////////////////////////////////////////////////////////////
    933 
    934 /*  Given count RunTypes in a complex region, return the worst case number of
    935     logical intervals that represents (i.e. number of rects that would be
    936     returned from the iterator).
    937 
    938     We could just return count/2, since there must be at least 2 values per
    939     interval, but we can first trim off the const overhead of the initial TOP
    940     value, plus the final BOTTOM + 2 sentinels.
    941  */
    942 #if 0 // UNUSED
    943 static int count_to_intervals(int count) {
    944     SkASSERT(count >= 6);   // a single rect is 6 values
    945     return (count - 4) >> 1;
    946 }
    947 #endif
    948 
    949 /*  Given a number of intervals, what is the worst case representation of that
    950     many intervals?
    951 
    952     Worst case (from a storage perspective), is a vertical stack of single
    953     intervals:  TOP + N * (BOTTOM INTERVALCOUNT LEFT RIGHT SENTINEL) + SENTINEL
    954  */
    955 static int intervals_to_count(int intervals) {
    956     return 1 + intervals * 5 + 1;
    957 }
    958 
    959 /*  Given the intervalCounts of RunTypes in two regions, return the worst-case number
    960     of RunTypes need to store the result after a region-op.
    961  */
    962 static int compute_worst_case_count(int a_intervals, int b_intervals) {
    963     // Our heuristic worst case is ai * (bi + 1) + bi * (ai + 1)
    964     int intervals = 2 * a_intervals * b_intervals + a_intervals + b_intervals;
    965     // convert back to number of RunType values
    966     return intervals_to_count(intervals);
    967 }
    968 
    969 static bool setEmptyCheck(SkRegion* result) {
    970     return result ? result->setEmpty() : false;
    971 }
    972 
    973 static bool setRectCheck(SkRegion* result, const SkIRect& rect) {
    974     return result ? result->setRect(rect) : !rect.isEmpty();
    975 }
    976 
    977 static bool setRegionCheck(SkRegion* result, const SkRegion& rgn) {
    978     return result ? result->setRegion(rgn) : !rgn.isEmpty();
    979 }
    980 
    981 bool SkRegion::Oper(const SkRegion& rgnaOrig, const SkRegion& rgnbOrig, Op op,
    982                     SkRegion* result) {
    983     SkASSERT((unsigned)op < kOpCount);
    984 
    985     if (kReplace_Op == op) {
    986         return setRegionCheck(result, rgnbOrig);
    987     }
    988 
    989     // swith to using pointers, so we can swap them as needed
    990     const SkRegion* rgna = &rgnaOrig;
    991     const SkRegion* rgnb = &rgnbOrig;
    992     // after this point, do not refer to rgnaOrig or rgnbOrig!!!
    993 
    994     // collaps difference and reverse-difference into just difference
    995     if (kReverseDifference_Op == op) {
    996         SkTSwap<const SkRegion*>(rgna, rgnb);
    997         op = kDifference_Op;
    998     }
    999 
   1000     SkIRect bounds;
   1001     bool    a_empty = rgna->isEmpty();
   1002     bool    b_empty = rgnb->isEmpty();
   1003     bool    a_rect = rgna->isRect();
   1004     bool    b_rect = rgnb->isRect();
   1005 
   1006     switch (op) {
   1007     case kDifference_Op:
   1008         if (a_empty) {
   1009             return setEmptyCheck(result);
   1010         }
   1011         if (b_empty || !SkIRect::IntersectsNoEmptyCheck(rgna->fBounds,
   1012                                                         rgnb->fBounds)) {
   1013             return setRegionCheck(result, *rgna);
   1014         }
   1015         if (b_rect && rgnb->fBounds.containsNoEmptyCheck(rgna->fBounds)) {
   1016             return setEmptyCheck(result);
   1017         }
   1018         break;
   1019 
   1020     case kIntersect_Op:
   1021         if ((a_empty | b_empty)
   1022                 || !bounds.intersect(rgna->fBounds, rgnb->fBounds)) {
   1023             return setEmptyCheck(result);
   1024         }
   1025         if (a_rect & b_rect) {
   1026             return setRectCheck(result, bounds);
   1027         }
   1028         if (a_rect && rgna->fBounds.contains(rgnb->fBounds)) {
   1029             return setRegionCheck(result, *rgnb);
   1030         }
   1031         if (b_rect && rgnb->fBounds.contains(rgna->fBounds)) {
   1032             return setRegionCheck(result, *rgna);
   1033         }
   1034         break;
   1035 
   1036     case kUnion_Op:
   1037         if (a_empty) {
   1038             return setRegionCheck(result, *rgnb);
   1039         }
   1040         if (b_empty) {
   1041             return setRegionCheck(result, *rgna);
   1042         }
   1043         if (a_rect && rgna->fBounds.contains(rgnb->fBounds)) {
   1044             return setRegionCheck(result, *rgna);
   1045         }
   1046         if (b_rect && rgnb->fBounds.contains(rgna->fBounds)) {
   1047             return setRegionCheck(result, *rgnb);
   1048         }
   1049         break;
   1050 
   1051     case kXOR_Op:
   1052         if (a_empty) {
   1053             return setRegionCheck(result, *rgnb);
   1054         }
   1055         if (b_empty) {
   1056             return setRegionCheck(result, *rgna);
   1057         }
   1058         break;
   1059     default:
   1060         SkDEBUGFAIL("unknown region op");
   1061         return false;
   1062     }
   1063 
   1064     RunType tmpA[kRectRegionRuns];
   1065     RunType tmpB[kRectRegionRuns];
   1066 
   1067     int a_intervals, b_intervals;
   1068     const RunType* a_runs = rgna->getRuns(tmpA, &a_intervals);
   1069     const RunType* b_runs = rgnb->getRuns(tmpB, &b_intervals);
   1070 
   1071     int dstCount = compute_worst_case_count(a_intervals, b_intervals);
   1072     SkAutoSTMalloc<256, RunType> array(dstCount);
   1073 
   1074 #ifdef SK_DEBUG
   1075 //  Sometimes helpful to seed everything with a known value when debugging
   1076 //  sk_memset32((uint32_t*)array.get(), 0x7FFFFFFF, dstCount);
   1077 #endif
   1078 
   1079     int count = operate(a_runs, b_runs, array.get(), op, nullptr == result);
   1080     SkASSERT(count <= dstCount);
   1081 
   1082     if (result) {
   1083         SkASSERT(count >= 0);
   1084         return result->setRuns(array.get(), count);
   1085     } else {
   1086         return (QUICK_EXIT_TRUE_COUNT == count) || !isRunCountEmpty(count);
   1087     }
   1088 }
   1089 
   1090 bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) {
   1091     SkDEBUGCODE(this->validate();)
   1092     return SkRegion::Oper(rgna, rgnb, op, this);
   1093 }
   1094 
   1095 ///////////////////////////////////////////////////////////////////////////////
   1096 
   1097 #include "SkBuffer.h"
   1098 
   1099 size_t SkRegion::writeToMemory(void* storage) const {
   1100     if (nullptr == storage) {
   1101         size_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount
   1102         if (!this->isEmpty()) {
   1103             size += sizeof(fBounds);
   1104             if (this->isComplex()) {
   1105                 size += 2 * sizeof(int32_t);    // ySpanCount + intervalCount
   1106                 size += fRunHead->fRunCount * sizeof(RunType);
   1107             }
   1108         }
   1109         return size;
   1110     }
   1111 
   1112     SkWBuffer   buffer(storage);
   1113 
   1114     if (this->isEmpty()) {
   1115         buffer.write32(-1);
   1116     } else {
   1117         bool isRect = this->isRect();
   1118 
   1119         buffer.write32(isRect ? 0 : fRunHead->fRunCount);
   1120         buffer.write(&fBounds, sizeof(fBounds));
   1121 
   1122         if (!isRect) {
   1123             buffer.write32(fRunHead->getYSpanCount());
   1124             buffer.write32(fRunHead->getIntervalCount());
   1125             buffer.write(fRunHead->readonly_runs(),
   1126                          fRunHead->fRunCount * sizeof(RunType));
   1127         }
   1128     }
   1129     return buffer.pos();
   1130 }
   1131 
   1132 // Validate that a memory sequence is a valid region.
   1133 // Try to check all possible errors.
   1134 // never read beyond &runs[runCount-1].
   1135 static bool validate_run(const int32_t* runs,
   1136                          int runCount,
   1137                          const SkIRect& givenBounds,
   1138                          int32_t ySpanCount,
   1139                          int32_t intervalCount) {
   1140     // Region Layout:
   1141     //    Top ( Bottom Span_Interval_Count ( Left Right )* Sentinel )+ Sentinel
   1142     if (ySpanCount < 1 || intervalCount < 2 || runCount != 2 + 3 * ySpanCount + 2 * intervalCount) {
   1143         return false;
   1144     }
   1145     SkASSERT(runCount >= 7);  // 7==SkRegion::kRectRegionRuns
   1146     // quick sanity check:
   1147     if (runs[runCount - 1] != SkRegion::kRunTypeSentinel ||
   1148         runs[runCount - 2] != SkRegion::kRunTypeSentinel) {
   1149         return false;
   1150     }
   1151     const int32_t* const end = runs + runCount;
   1152     SkIRect bounds = {0, 0, 0 ,0};  // calulated bounds
   1153     SkIRect rect = {0, 0, 0, 0};    // current rect
   1154     rect.fTop = *runs++;
   1155     if (rect.fTop == SkRegion::kRunTypeSentinel) {
   1156         return false;  // no rect can contain SkRegion::kRunTypeSentinel
   1157     }
   1158     if (rect.fTop != givenBounds.fTop) {
   1159         return false;  // Must not begin with empty span that does not contribute to bounds.
   1160     }
   1161     do {
   1162         --ySpanCount;
   1163         if (ySpanCount < 0) {
   1164             return false;  // too many yspans
   1165         }
   1166         rect.fBottom = *runs++;
   1167         if (rect.fBottom == SkRegion::kRunTypeSentinel) {
   1168             return false;
   1169         }
   1170         if (rect.fBottom > givenBounds.fBottom) {
   1171             return false;  // Must not end with empty span that does not contribute to bounds.
   1172         }
   1173         if (rect.fBottom <= rect.fTop) {
   1174             return false;  // y-intervals must be ordered; rects must be non-empty.
   1175         }
   1176 
   1177         int32_t xIntervals = *runs++;
   1178         SkASSERT(runs < end);
   1179         if (xIntervals < 0 || runs + 1 + 2 * xIntervals > end) {
   1180             return false;
   1181         }
   1182         intervalCount -= xIntervals;
   1183         if (intervalCount < 0) {
   1184             return false;  // too many intervals
   1185         }
   1186         bool firstInterval = true;
   1187         int32_t lastRight;  // check that x-intervals are distinct and ordered.
   1188         while (xIntervals-- > 0) {
   1189             rect.fLeft = *runs++;
   1190             rect.fRight = *runs++;
   1191             if (rect.fLeft == SkRegion::kRunTypeSentinel ||
   1192                 rect.fRight == SkRegion::kRunTypeSentinel ||
   1193                 rect.fLeft >= rect.fRight ||  // check non-empty rect
   1194                 (!firstInterval && rect.fLeft <= lastRight)) {
   1195                 return false;
   1196             }
   1197             lastRight = rect.fRight;
   1198             firstInterval = false;
   1199             bounds.join(rect);
   1200         }
   1201         if (*runs++ != SkRegion::kRunTypeSentinel) {
   1202             return false;  // required check sentinal.
   1203         }
   1204         rect.fTop = rect.fBottom;
   1205         SkASSERT(runs < end);
   1206     } while (*runs != SkRegion::kRunTypeSentinel);
   1207     ++runs;
   1208     if (ySpanCount != 0 || intervalCount != 0 || givenBounds != bounds) {
   1209         return false;
   1210     }
   1211     SkASSERT(runs == end);  // if ySpanCount && intervalCount are right, must be correct length.
   1212     return true;
   1213 }
   1214 size_t SkRegion::readFromMemory(const void* storage, size_t length) {
   1215     SkRBuffer   buffer(storage, length);
   1216     SkRegion    tmp;
   1217     int32_t     count;
   1218 
   1219     // Serialized Region Format:
   1220     //    Empty:
   1221     //       -1
   1222     //    Simple Rect:
   1223     //       0  LEFT TOP RIGHT BOTTOM
   1224     //    Complex Region:
   1225     //       COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT [RUNS....]
   1226     if (!buffer.readS32(&count) || count < -1) {
   1227         return 0;
   1228     }
   1229     if (count >= 0) {
   1230         if (!buffer.read(&tmp.fBounds, sizeof(tmp.fBounds)) || tmp.fBounds.isEmpty()) {
   1231             return 0;  // Short buffer or bad bounds for non-empty region; report failure.
   1232         }
   1233         if (count == 0) {
   1234             tmp.fRunHead = SkRegion_gRectRunHeadPtr;
   1235         } else {
   1236             int32_t ySpanCount, intervalCount;
   1237             if (!buffer.readS32(&ySpanCount) ||
   1238                 !buffer.readS32(&intervalCount) ||
   1239                 buffer.available() < count * sizeof(int32_t)) {
   1240                 return 0;
   1241             }
   1242             if (!validate_run((const int32_t*)((const char*)storage + buffer.pos()), count,
   1243                               tmp.fBounds, ySpanCount, intervalCount)) {
   1244                 return 0;  // invalid runs, don't even allocate
   1245             }
   1246             tmp.allocateRuns(count, ySpanCount, intervalCount);
   1247             SkASSERT(tmp.isComplex());
   1248             SkAssertResult(buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(int32_t)));
   1249         }
   1250     }
   1251     SkASSERT(tmp.isValid());
   1252     SkASSERT(buffer.isValid());
   1253     this->swap(tmp);
   1254     return buffer.pos();
   1255 }
   1256 
   1257 ///////////////////////////////////////////////////////////////////////////////
   1258 
   1259 const SkRegion& SkRegion::GetEmptyRegion() {
   1260     static SkRegion gEmpty;
   1261     return gEmpty;
   1262 }
   1263 
   1264 ///////////////////////////////////////////////////////////////////////////////
   1265 
   1266 bool SkRegion::isValid() const {
   1267     if (this->isEmpty()) {
   1268         return fBounds == SkIRect{0, 0, 0, 0};
   1269     }
   1270     if (fBounds.isEmpty()) {
   1271         return false;
   1272     }
   1273     if (this->isRect()) {
   1274         return true;
   1275     }
   1276     return fRunHead && fRunHead->fRefCnt > 0 &&
   1277            validate_run(fRunHead->readonly_runs(), fRunHead->fRunCount, fBounds,
   1278                         fRunHead->getYSpanCount(), fRunHead->getIntervalCount());
   1279 }
   1280 
   1281 #ifdef SK_DEBUG
   1282 void SkRegion::validate() const { SkASSERT(this->isValid()); }
   1283 
   1284 void SkRegion::dump() const {
   1285     if (this->isEmpty()) {
   1286         SkDebugf("  rgn: empty\n");
   1287     } else {
   1288         SkDebugf("  rgn: [%d %d %d %d]", fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom);
   1289         if (this->isComplex()) {
   1290             const RunType* runs = fRunHead->readonly_runs();
   1291             for (int i = 0; i < fRunHead->fRunCount; i++)
   1292                 SkDebugf(" %d", runs[i]);
   1293         }
   1294         SkDebugf("\n");
   1295     }
   1296 }
   1297 
   1298 #endif
   1299 
   1300 ///////////////////////////////////////////////////////////////////////////////
   1301 
   1302 SkRegion::Iterator::Iterator(const SkRegion& rgn) {
   1303     this->reset(rgn);
   1304 }
   1305 
   1306 bool SkRegion::Iterator::rewind() {
   1307     if (fRgn) {
   1308         this->reset(*fRgn);
   1309         return true;
   1310     }
   1311     return false;
   1312 }
   1313 
   1314 void SkRegion::Iterator::reset(const SkRegion& rgn) {
   1315     fRgn = &rgn;
   1316     if (rgn.isEmpty()) {
   1317         fDone = true;
   1318     } else {
   1319         fDone = false;
   1320         if (rgn.isRect()) {
   1321             fRect = rgn.fBounds;
   1322             fRuns = nullptr;
   1323         } else {
   1324             fRuns = rgn.fRunHead->readonly_runs();
   1325             fRect.set(fRuns[3], fRuns[0], fRuns[4], fRuns[1]);
   1326             fRuns += 5;
   1327             // Now fRuns points to the 2nd interval (or x-sentinel)
   1328         }
   1329     }
   1330 }
   1331 
   1332 void SkRegion::Iterator::next() {
   1333     if (fDone) {
   1334         return;
   1335     }
   1336 
   1337     if (fRuns == nullptr) {   // rect case
   1338         fDone = true;
   1339         return;
   1340     }
   1341 
   1342     const RunType* runs = fRuns;
   1343 
   1344     if (runs[0] < kRunTypeSentinel) { // valid X value
   1345         fRect.fLeft = runs[0];
   1346         fRect.fRight = runs[1];
   1347         runs += 2;
   1348     } else {    // we're at the end of a line
   1349         runs += 1;
   1350         if (runs[0] < kRunTypeSentinel) { // valid Y value
   1351             int intervals = runs[1];
   1352             if (0 == intervals) {    // empty line
   1353                 fRect.fTop = runs[0];
   1354                 runs += 3;
   1355             } else {
   1356                 fRect.fTop = fRect.fBottom;
   1357             }
   1358 
   1359             fRect.fBottom = runs[0];
   1360             assert_sentinel(runs[2], false);
   1361             assert_sentinel(runs[3], false);
   1362             fRect.fLeft = runs[2];
   1363             fRect.fRight = runs[3];
   1364             runs += 4;
   1365         } else {    // end of rgn
   1366             fDone = true;
   1367         }
   1368     }
   1369     fRuns = runs;
   1370 }
   1371 
   1372 SkRegion::Cliperator::Cliperator(const SkRegion& rgn, const SkIRect& clip)
   1373         : fIter(rgn), fClip(clip), fDone(true) {
   1374     const SkIRect& r = fIter.rect();
   1375 
   1376     while (!fIter.done()) {
   1377         if (r.fTop >= clip.fBottom) {
   1378             break;
   1379         }
   1380         if (fRect.intersect(clip, r)) {
   1381             fDone = false;
   1382             break;
   1383         }
   1384         fIter.next();
   1385     }
   1386 }
   1387 
   1388 void SkRegion::Cliperator::next() {
   1389     if (fDone) {
   1390         return;
   1391     }
   1392 
   1393     const SkIRect& r = fIter.rect();
   1394 
   1395     fDone = true;
   1396     fIter.next();
   1397     while (!fIter.done()) {
   1398         if (r.fTop >= fClip.fBottom) {
   1399             break;
   1400         }
   1401         if (fRect.intersect(fClip, r)) {
   1402             fDone = false;
   1403             break;
   1404         }
   1405         fIter.next();
   1406     }
   1407 }
   1408 
   1409 ///////////////////////////////////////////////////////////////////////////////
   1410 
   1411 SkRegion::Spanerator::Spanerator(const SkRegion& rgn, int y, int left,
   1412                                  int right) {
   1413     SkDEBUGCODE(rgn.validate();)
   1414 
   1415     const SkIRect& r = rgn.getBounds();
   1416 
   1417     fDone = true;
   1418     if (!rgn.isEmpty() && y >= r.fTop && y < r.fBottom &&
   1419             right > r.fLeft && left < r.fRight) {
   1420         if (rgn.isRect()) {
   1421             if (left < r.fLeft) {
   1422                 left = r.fLeft;
   1423             }
   1424             if (right > r.fRight) {
   1425                 right = r.fRight;
   1426             }
   1427             fLeft = left;
   1428             fRight = right;
   1429             fRuns = nullptr;    // means we're a rect, not a rgn
   1430             fDone = false;
   1431         } else {
   1432             const SkRegion::RunType* runs = rgn.fRunHead->findScanline(y);
   1433             runs += 2;  // skip Bottom and IntervalCount
   1434             for (;;) {
   1435                 // runs[0..1] is to the right of the span, so we're done
   1436                 if (runs[0] >= right) {
   1437                     break;
   1438                 }
   1439                 // runs[0..1] is to the left of the span, so continue
   1440                 if (runs[1] <= left) {
   1441                     runs += 2;
   1442                     continue;
   1443                 }
   1444                 // runs[0..1] intersects the span
   1445                 fRuns = runs;
   1446                 fLeft = left;
   1447                 fRight = right;
   1448                 fDone = false;
   1449                 break;
   1450             }
   1451         }
   1452     }
   1453 }
   1454 
   1455 bool SkRegion::Spanerator::next(int* left, int* right) {
   1456     if (fDone) {
   1457         return false;
   1458     }
   1459 
   1460     if (fRuns == nullptr) {   // we're a rect
   1461         fDone = true;   // ok, now we're done
   1462         if (left) {
   1463             *left = fLeft;
   1464         }
   1465         if (right) {
   1466             *right = fRight;
   1467         }
   1468         return true;    // this interval is legal
   1469     }
   1470 
   1471     const SkRegion::RunType* runs = fRuns;
   1472 
   1473     if (runs[0] >= fRight) {
   1474         fDone = true;
   1475         return false;
   1476     }
   1477 
   1478     SkASSERT(runs[1] > fLeft);
   1479 
   1480     if (left) {
   1481         *left = SkMax32(fLeft, runs[0]);
   1482     }
   1483     if (right) {
   1484         *right = SkMin32(fRight, runs[1]);
   1485     }
   1486     fRuns = runs + 2;
   1487     return true;
   1488 }
   1489 
   1490 ///////////////////////////////////////////////////////////////////////////////
   1491 
   1492 #ifdef SK_DEBUG
   1493 
   1494 bool SkRegion::debugSetRuns(const RunType runs[], int count) {
   1495     // we need to make a copy, since the real method may modify the array, and
   1496     // so it cannot be const.
   1497 
   1498     SkAutoTArray<RunType> storage(count);
   1499     memcpy(storage.get(), runs, count * sizeof(RunType));
   1500     return this->setRuns(storage.get(), count);
   1501 }
   1502 
   1503 #endif
   1504