11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRegionPriv.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkThread.h"
1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDEBUGCODE(int32_t gRgnAllocCounter;)
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////////
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*  Pass in a scanline, beginning with the Left value of the pair (i.e. not the Y beginning)
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* skip_scanline(const SkRegion::RunType runs[])
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (runs[0] != SkRegion::kRunTypeSentinel)
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(runs[0] < runs[1]);    // valid span
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += 2;
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (SkRegion::RunType*)(runs + 1);  // return past the X-sentinel
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns true if runs are just a rect
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::ComputeRunBounds(const SkRegion::RunType runs[], int count, SkIRect* bounds)
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    assert_sentinel(runs[0], false);    // top
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count == kRectRegionRuns)
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[1], false);    // bottom
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[2], false);    // left
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[3], false);    // right
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[4], true);
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[5], true);
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(runs[0] < runs[1]);    // valid height
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(runs[2] < runs[3]);    // valid width
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bounds->set(runs[2], runs[0], runs[3], runs[1]);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left = SK_MaxS32;
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int rite = SK_MinS32;
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int bot;
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->fTop = *runs++;
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bot = *runs++;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (*runs < SkRegion::kRunTypeSentinel)
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (left > *runs)
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                left = *runs;
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs = skip_scanline(runs);
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (rite < runs[-2])
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = runs[-2];
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += 1;  // skip X-sentinel
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (runs[0] < SkRegion::kRunTypeSentinel);
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->fLeft = left;
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->fRight = rite;
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->fBottom = bot;
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7687b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkRegion::SkRegion() {
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBounds.set(0, 0, 0, 0);
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = SkRegion_gEmptyRunHeadPtr;
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkRegion::SkRegion(const SkRegion& src) {
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = SkRegion_gEmptyRunHeadPtr;   // just need a value that won't trigger sk_free(fRunHead)
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setRegion(src);
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8687b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkRegion::SkRegion(const SkIRect& rect) {
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = SkRegion_gEmptyRunHeadPtr;   // just need a value that won't trigger sk_free(fRunHead)
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setRect(rect);
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkRegion::~SkRegion() {
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->freeRuns();
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkRegion::freeRuns() {
9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (fRunHead->isComplex()) {
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fRunHead->fRefCnt >= 1);
9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        if (sk_atomic_dec(&fRunHead->fRefCnt) == 1) {
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            //SkASSERT(gRgnAllocCounter > 0);
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            //SkDEBUGCODE(sk_atomic_dec(&gRgnAllocCounter));
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            //SkDEBUGF(("************** gRgnAllocCounter::free %d\n", gRgnAllocCounter));
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            sk_free(fRunHead);
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkRegion::allocateRuns(int count) {
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = RunHead::Alloc(count);
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkRegion& SkRegion::operator=(const SkRegion& src) {
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    (void)this->setRegion(src);
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkRegion::swap(SkRegion& other) {
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTSwap<SkIRect>(fBounds, other.fBounds);
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTSwap<RunHead*>(fRunHead, other.fRunHead);
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::setEmpty() {
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->freeRuns();
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBounds.set(0, 0, 0, 0);
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = SkRegion_gEmptyRunHeadPtr;
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::setRect(int32_t left, int32_t top,
12987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                       int32_t right, int32_t bottom) {
13087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (left >= right || top >= bottom) {
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->setEmpty();
13287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->freeRuns();
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBounds.set(left, top, right, bottom);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = SkRegion_gRectRunHeadPtr;
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::setRect(const SkIRect& r) {
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->setRect(r.fLeft, r.fTop, r.fRight, r.fBottom);
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::setRegion(const SkRegion& src) {
14487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (this != &src) {
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->freeRuns();
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBounds = src.fBounds;
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fRunHead = src.fRunHead;
14987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        if (fRunHead->isComplex()) {
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            sk_atomic_inc(&fRunHead->fRefCnt);
15187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        }
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fRunHead != SkRegion_gEmptyRunHeadPtr;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op) {
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion tmp(rect);
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->op(tmp, rgn, op);
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerbool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op) {
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion tmp(rect);
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->op(rgn, tmp, op);
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1719221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onoratochar* SkRegion::toString()
1729221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato{
1739221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    Iterator iter(*this);
1749221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    int count = 0;
1759221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    while (!iter.done()) {
1769221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        count++;
1779221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        iter.next();
1789221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    }
1799221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() and '\0'
1809221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    const int max = (count*((11*4)+5))+11+1;
1819221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    char* result = (char*)malloc(max);
1829221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    if (result == NULL) {
1839221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        return NULL;
1849221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    }
1859221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    count = sprintf(result, "SkRegion(");
1869221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    iter.reset(*this);
1879221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    while (!iter.done()) {
1889221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        const SkIRect& r = iter.rect();
1899221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRight, r.fBottom);
1909221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato        iter.next();
1919221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    }
1929221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    count += sprintf(result+count, ")");
1939221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    return result;
1949221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato}
19505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
1969221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato
1979221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato//////////////////////////////////////////////////////////////////////////////////////
1989221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkRegion::count_runtype_values(int* itop, int* ibot) const
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this == NULL)
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *itop = SK_MinS32;
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *ibot = SK_MaxS32;
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int maxT;
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isRect())
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        maxT = 2;
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->isComplex());
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // skip the top
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const RunType*  runs = fRunHead->readonly_runs() + 1;
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        maxT = 0;
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const RunType* next = skip_scanline(runs + 1);
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(next > runs);
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int         T = (int)(next - runs - 1);
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (maxT < T)
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                maxT = T;
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs = next;
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (runs[0] < SkRegion::kRunTypeSentinel);
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *itop = fBounds.fTop;
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *ibot = fBounds.fBottom;
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return maxT;
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setRuns(RunType runs[], int count)
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(this->validate();)
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count <= 2)
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  SkDEBUGF(("setRuns: empty\n"));
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[count-1], true);
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->setEmpty();
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // trim off any empty spans from the top and bottom
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // weird I should need this, perhaps op() could be smarter...
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count > kRectRegionRuns)
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        RunType* stop = runs + count;
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[0], false);    // top
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(runs[1], false);    // bottom
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (runs[2] == SkRegion::kRunTypeSentinel)    // should be first left...
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += 2;  // skip empty initial span
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs[0] = runs[-1]; // set new top to prev bottom
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(runs[1], false);    // bot: a sentinal would mean two in a row
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(runs[2], false);    // left
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(runs[3], false);    // right
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now check for a trailing empty span
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(stop[-1], true);
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(stop[-2], true);
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_sentinel(stop[-3], false);   // should be last right
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (stop[-4] == SkRegion::kRunTypeSentinel)   // eek, stop[-3] was a bottom with no x-runs
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            stop[-3] = SkRegion::kRunTypeSentinel;    // kill empty last span
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            stop -= 2;
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(stop[-1], true);
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(stop[-2], true);
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(stop[-3], false);
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(stop[-4], false);
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(stop[-5], false);
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        count = (int)(stop - runs);
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count >= kRectRegionRuns);
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ComputeRunBounds(runs, count, &fBounds))
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  SkDEBUGF(("setRuns: rect[%d %d %d %d]\n", fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom));
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->setRect(fBounds);
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //  if we get here, we need to become a complex region
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!fRunHead->isComplex() || fRunHead->fRunCount != count)
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUGx
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("setRuns: rgn [");
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const RunType* r = runs;
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkDebugf(" top: %d\n", *r++);
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (*r < SkRegion::kRunTypeSentinel)
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkDebugf(" bottom: %d", *r++);
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                while (*r < SkRegion::kRunTypeSentinel)
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkDebugf(" [%d %d]", r[0], r[1]);
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    r += 2;
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkDebugf("\n");
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->freeRuns();
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->allocateRuns(count);
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // must call this before we can write directly into runs()
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // in case we are sharing the buffer with another region (copy on write)
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRunHead = fRunHead->ensureWritable();
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(fRunHead->writable_runs(), runs, count * sizeof(RunType));
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(this->validate();)
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::BuildRectRuns(const SkIRect& bounds,
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             RunType runs[kRectRegionRuns])
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[0] = bounds.fTop;
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[1] = bounds.fBottom;
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[2] = bounds.fLeft;
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[3] = bounds.fRight;
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[4] = kRunTypeSentinel;
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs[5] = kRunTypeSentinel;
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* find_scanline(const SkRegion::RunType runs[], int y)
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(y >= runs[0]); // if this fails, we didn't do a quick check on the boudns
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    runs += 1;  // skip top-Y
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (;;)
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (runs[0] == SkRegion::kRunTypeSentinel)
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (y < runs[0])
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return (SkRegion::RunType*)&runs[1];
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs = skip_scanline(runs + 1); // skip the Y value before calling
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3492c497e64d20a73267eb92ae88fdc51ba2a356b55Mike Reedbool SkRegion::contains(int32_t x, int32_t y) const
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!fBounds.contains(x, y))
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isRect())
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(this->isComplex());
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType* runs = find_scanline(fRunHead->readonly_runs(), y);
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (runs)
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {   for (;;)
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {   if (x < runs[0])
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (x < runs[1])
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                return true;
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += 2;
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::contains(const SkIRect& r) const
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion tmp(r);
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->contains(tmp);
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::contains(const SkRegion& rgn) const
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty() || rgn.isEmpty() || !fBounds.contains(rgn.fBounds))
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isRect())
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion    tmp;
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    tmp.op(*this, rgn, kUnion_Op);
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return tmp == *this;
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[], int* count) const
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(tmpStorage && count);
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType* runs = tmpStorage;
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty())
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        tmpStorage[0] = kRunTypeSentinel;
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 1;
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else if (this->isRect())
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        BuildRectRuns(fBounds, tmpStorage);
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = kRectRegionRuns;
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = fRunHead->fRunCount;
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs = fRunHead->readonly_runs();
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return runs;
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::intersects(const SkIRect& r) const {
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty() || r.isEmpty()) {
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!SkIRect::Intersects(fBounds, r)) {
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isRect()) {
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // we are complex
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion tmp;
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return tmp.op(*this, r, kIntersect_Op);
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::intersects(const SkRegion& rgn) const {
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty() || rgn.isEmpty()) {
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!SkIRect::Intersects(fBounds, rgn.fBounds)) {
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isRect() && rgn.isRect()) {
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // one or both of us is complex
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // TODO: write a faster version that aborts as soon as we write the first
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //       non-empty span, to avoid build the entire result
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion tmp;
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return tmp.op(*this, rgn, kIntersect_Op);
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkRegion::operator==(const SkRegion& b) const {
4594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkDEBUGCODE(validate();)
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(b.validate();)
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (this == &b) {
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
46487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
4654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (fBounds != b.fBounds) {
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
46787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const SkRegion::RunHead* ah = fRunHead;
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion::RunHead* bh = b.fRunHead;
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // this catches empties and rects being equal
47387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (ah == bh) {
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
47587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now we insist that both are complex (but different ptrs)
47787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (!ah->isComplex() || !bh->isComplex()) {
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
47987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return  ah->fRunCount == bh->fRunCount &&
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            !memcmp(ah->readonly_runs(), bh->readonly_runs(),
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    ah->fRunCount * sizeof(SkRegion::RunType));
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
48587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkRegion::translate(int dx, int dy, SkRegion* dst) const {
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(this->validate();)
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
48887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (NULL == dst) {
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
49087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
49187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (this->isEmpty()) {
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->setEmpty();
49387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else if (this->isRect()) {
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy,
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                     fBounds.fRight + dx, fBounds.fBottom + dy);
49687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
49787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        if (this == dst) {
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst->fRunHead = dst->fRunHead->ensureWritable();
49987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        } else {
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkRegion    tmp;
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            tmp.allocateRuns(fRunHead->fRunCount);
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            tmp.fBounds = fBounds;
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst->swap(tmp);
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->fBounds.offset(dx, dy);
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const RunType*  sruns = fRunHead->readonly_runs();
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        RunType*        druns = dst->fRunHead->writable_runs();
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *druns++ = (SkRegion::RunType)(*sruns++ + dy);    // top
51287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        for (;;) {
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int bottom = *sruns++;
51487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            if (bottom == kRunTypeSentinel) {
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
51687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            }
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *druns++ = (SkRegion::RunType)(bottom + dy);  // bottom;
51887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            for (;;) {
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                int x = *sruns++;
52087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                if (x == kRunTypeSentinel) {
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
52287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                }
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *druns++ = (SkRegion::RunType)(x + dx);
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *druns++ = (SkRegion::RunType)(*sruns++ + dx);
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *druns++ = kRunTypeSentinel;    // x sentinel
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *druns++ = kRunTypeSentinel;    // y sentinel
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(sruns - fRunHead->readonly_runs() == fRunHead->fRunCount);
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(druns - dst->fRunHead->readonly_runs() == dst->fRunHead->fRunCount);
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(this->validate();)
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
53740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
53840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
53940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkRegion::setRects(const SkIRect rects[], int count) {
54040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (0 == count) {
54140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        this->setEmpty();
54240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
54340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        this->setRect(rects[0]);
54440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        for (int i = 1; i < count; i++) {
54540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            this->op(rects[i], kUnion_Op);
54640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
54740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
54840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return !this->isEmpty();
54940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
55040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
55140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( push )
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( disable : 4701 )
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void assert_valid_pair(int left, int rite)
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(left == SkRegion::kRunTypeSentinel || left < rite);
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    #define assert_valid_pair(left, rite)
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstruct spanRec {
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion::RunType*    fA_runs;
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion::RunType*    fB_runs;
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int                         fA_left, fA_rite, fB_left, fB_rite;
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int                         fLeft, fRite, fInside;
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void init(const SkRegion::RunType a_runs[], const SkRegion::RunType b_runs[])
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fA_left = *a_runs++;
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fA_rite = *a_runs++;
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fB_left = *b_runs++;
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fB_rite = *b_runs++;
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fA_runs = a_runs;
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fB_runs = b_runs;
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool done() const
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fA_left <= SkRegion::kRunTypeSentinel);
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fB_left <= SkRegion::kRunTypeSentinel);
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return fA_left == SkRegion::kRunTypeSentinel && fB_left == SkRegion::kRunTypeSentinel;
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void next()
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_valid_pair(fA_left, fA_rite);
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        assert_valid_pair(fB_left, fB_rite);
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int     inside, left, rite SK_INIT_TO_AVOID_WARNING;
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    a_flush = false;
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    b_flush = false;
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int a_left = fA_left;
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int a_rite = fA_rite;
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int b_left = fB_left;
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int b_rite = fB_rite;
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_left < b_left)
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            inside = 1;
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            left = a_left;
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (a_rite <= b_left)   // [...] <...>
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = a_rite;
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                a_flush = true;
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else // [...<..]...> or [...<...>...]
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = a_left = b_left;
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (b_left < a_left)
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            inside = 2;
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            left = b_left;
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (b_rite <= a_left)   // [...] <...>
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = b_rite;
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                b_flush = true;
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else // [...<..]...> or [...<...>...]
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = b_left = a_left;
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else    // a_left == b_left
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            inside = 3;
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            left = a_left;  // or b_left
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (a_rite <= b_rite)
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = b_left = a_rite;
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                a_flush = true;
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (b_rite <= a_rite)
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite = a_left = b_rite;
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                b_flush = true;
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_flush)
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            a_left = *fA_runs++;
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            a_rite = *fA_runs++;
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (b_flush)
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b_left = *fB_runs++;
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b_rite = *fB_runs++;
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left <= rite);
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now update our state
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fA_left = a_left;
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fA_rite = a_rite;
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fB_left = b_left;
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fB_rite = b_rite;
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fLeft = left;
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fRite = rite;
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fInside = inside;
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* operate_on_span(const SkRegion::RunType a_runs[],
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                          const SkRegion::RunType b_runs[],
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                          SkRegion::RunType dst[],
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                          int min, int max)
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    spanRec rec;
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    firstInterval = true;
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec.init(a_runs, b_runs);
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!rec.done())
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.next();
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int left = rec.fLeft;
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rite = rec.fRite;
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // add left,rite to our dst buffer (checking for coincidence
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((unsigned)(rec.fInside - min) <= (unsigned)(max - min) &&
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            left < rite)    // skip if equal
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (firstInterval || dst[-1] < left)
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *dst++ = (SkRegion::RunType)(left);
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *dst++ = (SkRegion::RunType)(rite);
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                firstInterval = false;
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else    // update the right edge
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                dst[-1] = (SkRegion::RunType)(rite);
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *dst++ = SkRegion::kRunTypeSentinel;
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return dst;
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if defined _WIN32 && _MSC_VER >= 1300
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( pop )
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const struct {
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint8_t fMin;
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint8_t fMax;
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} gOpMinMax[] = {
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    { 1, 1 },   // Difference
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    { 3, 3 },   // Intersection
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    { 1, 3 },   // Union
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    { 1, 2 }    // XOR
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass RgnOper {
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RgnOper(int top, SkRegion::RunType dst[], SkRegion::Op op)
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // need to ensure that the op enum lines up with our minmax array
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkRegion::kDifference_Op == 0);
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkRegion::kIntersect_Op == 1);
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkRegion::kUnion_Op == 2);
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkRegion::kXOR_Op == 3);
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)op <= 3);
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStartDst = dst;
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevDst = dst + 1;
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevLen = 0;       // will never match a length from operate_on_span
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTop = (SkRegion::RunType)(top);    // just a first guess, we might update this
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMin = gOpMinMax[op].fMin;
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMax = gOpMinMax[op].fMax;
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void addSpan(int bottom, const SkRegion::RunType a_runs[], const SkRegion::RunType b_runs[])
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkRegion::RunType*  start = fPrevDst + fPrevLen + 1;    // skip X values and slot for the next Y
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkRegion::RunType*  stop = operate_on_span(a_runs, b_runs, start, fMin, fMax);
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t              len = stop - start;
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fPrevLen == len && !memcmp(fPrevDst, start, len * sizeof(SkRegion::RunType)))   // update Y value
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fPrevDst[-1] = (SkRegion::RunType)(bottom);
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else    // accept the new span
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (len == 1 && fPrevLen == 0) {
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fTop = (SkRegion::RunType)(bottom); // just update our bottom
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                start[-1] = (SkRegion::RunType)(bottom);
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fPrevDst = start;
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fPrevLen = len;
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int flush()
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStartDst[0] = fTop;
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevDst[fPrevLen] = SkRegion::kRunTypeSentinel;
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return (int)(fPrevDst - fStartDst + fPrevLen + 1);
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint8_t fMin, fMax;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::RunType*  fStartDst;
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::RunType*  fPrevDst;
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t              fPrevLen;
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::RunType   fTop;
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int operate(const SkRegion::RunType a_runs[],
7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   const SkRegion::RunType b_runs[],
7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   SkRegion::RunType dst[],
7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   SkRegion::Op op) {
7804c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed    const SkRegion::RunType gSentinel[] = {
7814c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        SkRegion::kRunTypeSentinel,
7824c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        // just need a 2nd value, since spanRec.init() reads 2 values, even
7834c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        // though if the first value is the sentinel, it ignores the 2nd value.
7844c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        // w/o the 2nd value here, we might read uninitialized memory.
7854c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        0,
7864c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed    };
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int a_top = *a_runs++;
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int a_bot = *a_runs++;
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int b_top = *b_runs++;
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int b_bot = *b_runs++;
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    assert_sentinel(a_top, false);
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    assert_sentinel(a_bot, false);
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    assert_sentinel(b_top, false);
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    assert_sentinel(b_bot, false);
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RgnOper oper(SkMin32(a_top, b_top), dst, op);
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool firstInterval = true;
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int prevBot = SkRegion::kRunTypeSentinel; // so we fail the first test
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    while (a_bot < SkRegion::kRunTypeSentinel ||
8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger           b_bot < SkRegion::kRunTypeSentinel) {
8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int                         top, bot SK_INIT_TO_AVOID_WARNING;
8064c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        const SkRegion::RunType*    run0 = gSentinel;
8074c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed        const SkRegion::RunType*    run1 = gSentinel;
8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool                        a_flush = false;
8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool                        b_flush = false;
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (a_top < b_top) {
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            top = a_top;
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            run0 = a_runs;
8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (a_bot <= b_top) {   // [...] <...>
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = a_bot;
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                a_flush = true;
8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {  // [...<..]...> or [...<...>...]
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = a_top = b_top;
8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (b_top < a_top) {
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            top = b_top;
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            run1 = b_runs;
8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (b_bot <= a_top) {   // [...] <...>
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = b_bot;
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                b_flush = true;
8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {    // [...<..]...> or [...<...>...]
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = b_top = a_top;
8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {    // a_top == b_top
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            top = a_top;    // or b_top
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            run0 = a_runs;
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            run1 = b_runs;
8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (a_bot <= b_bot) {
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = b_top = a_bot;
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                a_flush = true;
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (b_bot <= a_bot) {
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bot = a_top = b_bot;
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                b_flush = true;
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (top > prevBot) {
8444c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed            oper.addSpan(top, gSentinel, gSentinel);
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        oper.addSpan(bot, run0, run1);
8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        firstInterval = false;
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (a_flush) {
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            a_runs = skip_scanline(a_runs);
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            a_top = a_bot;
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            a_bot = *a_runs++;
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (a_bot == SkRegion::kRunTypeSentinel) {
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                a_top = a_bot;
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (b_flush) {
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b_runs = skip_scanline(b_runs);
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b_top = b_bot;
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b_bot = *b_runs++;
8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (b_bot == SkRegion::kRunTypeSentinel) {
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                b_top = b_bot;
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevBot = bot;
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return oper.flush();
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*  Given count RunTypes in a complex region, return the worst case number of
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    logical intervals that represents (i.e. number of rects that would be
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    returned from the iterator).
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    We could just return count/2, since there must be at least 2 values per
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    interval, but we can first trim off the const overhead of the initial TOP
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value, plus the final BOTTOM + 2 sentinels.
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int count_to_intervals(int count) {
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count >= 6);   // a single rect is 6 values
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (count - 4) >> 1;
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*  Given a number of intervals, what is the worst case representation of that
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    many intervals?
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Worst case (from a storage perspective), is a vertical stack of single
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    intervals:  TOP + N * (BOTTOM LEFT RIGHT SENTINEL) + SENTINEL
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int intervals_to_count(int intervals) {
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return 1 + intervals * 4 + 1;
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*  Given the counts of RunTypes in two regions, return the worst-case number
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    of RunTypes need to store the result after a region-op.
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int compute_worst_case_count(int a_count, int b_count) {
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int a_intervals = count_to_intervals(a_count);
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int b_intervals = count_to_intervals(b_count);
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // Our heuristic worst case is ai * (bi + 1) + bi * (ai + 1)
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int intervals = 2 * a_intervals * b_intervals + a_intervals + b_intervals;
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // convert back to number of RunType values
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return intervals_to_count(intervals);
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::op(const SkRegion& rgnaOrig, const SkRegion& rgnbOrig, Op op)
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(this->validate();)
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT((unsigned)op < kOpCount);
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kReplace_Op == op)
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->set(rgnbOrig);
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // swith to using pointers, so we can swap them as needed
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion* rgna = &rgnaOrig;
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion* rgnb = &rgnbOrig;
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // after this point, do not refer to rgnaOrig or rgnbOrig!!!
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // collaps difference and reverse-difference into just difference
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kReverseDifference_Op == op)
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkTSwap<const SkRegion*>(rgna, rgnb);
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        op = kDifference_Op;
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect bounds;
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    a_empty = rgna->isEmpty();
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    b_empty = rgnb->isEmpty();
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    a_rect = rgna->isRect();
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    b_rect = rgnb->isRect();
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (op) {
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case kDifference_Op:
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_empty)
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setEmpty();
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (b_empty || !SkIRect::Intersects(rgna->fBounds, rgnb->fBounds))
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgna);
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case kIntersect_Op:
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((a_empty | b_empty)
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                || !bounds.intersect(rgna->fBounds, rgnb->fBounds))
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setEmpty();
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_rect & b_rect)
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRect(bounds);
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case kUnion_Op:
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_empty)
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgnb);
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (b_empty)
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgna);
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_rect && rgna->fBounds.contains(rgnb->fBounds))
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgna);
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (b_rect && rgnb->fBounds.contains(rgna->fBounds))
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgnb);
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case kXOR_Op:
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (a_empty)
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgnb);
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (b_empty)
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->setRegion(*rgna);
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDEBUGFAIL("unknown region op");
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return !this->isEmpty();
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RunType tmpA[kRectRegionRuns];
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RunType tmpB[kRectRegionRuns];
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int a_count, b_count;
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType* a_runs = rgna->getRuns(tmpA, &a_count);
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType* b_runs = rgnb->getRuns(tmpB, &b_count);
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int dstCount = compute_worst_case_count(a_count, b_count);
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoSTMalloc<32, RunType> array(dstCount);
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int count = operate(a_runs, b_runs, array.get(), op);
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count <= dstCount);
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->setRuns(array.get(), count);
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////////////////////////////////
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h"
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint32_t SkRegion::flatten(void* storage) const {
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == storage) {
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        uint32_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (!this->isEmpty()) {
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            size += sizeof(fBounds);
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (this->isComplex()) {
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                size += fRunHead->fRunCount * sizeof(RunType);
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return size;
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkWBuffer   buffer(storage);
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty()) {
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(-1);
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool isRect = this->isRect();
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(isRect ? 0 : fRunHead->fRunCount);
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write(&fBounds, sizeof(fBounds));
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (!isRect) {
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            buffer.write(fRunHead->readonly_runs(),
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                         fRunHead->fRunCount * sizeof(RunType));
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return buffer.pos();
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint32_t SkRegion::unflatten(const void* storage) {
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRBuffer   buffer(storage);
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion    tmp;
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int32_t     count;
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    count = buffer.readS32();
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count >= 0) {
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.read(&tmp.fBounds, sizeof(tmp.fBounds));
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (count == 0) {
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            tmp.fRunHead = SkRegion_gRectRunHeadPtr;
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            tmp.allocateRuns(count);
10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(RunType));
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->swap(tmp);
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return buffer.pos();
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
104187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
104287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
104387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerconst SkRegion& SkRegion::GetEmptyRegion() {
104487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    static SkRegion gEmpty;
104587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    return gEmpty;
104687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger}
104787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
104887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkRegion::RunType* validate_line(const SkRegion::RunType run[], const SkIRect& bounds)
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // *run is the bottom of the current span
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(*run > bounds.fTop);
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(*run <= bounds.fBottom);
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    run += 1;
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // check for empty span
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (*run != SkRegion::kRunTypeSentinel)
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int prevRite = bounds.fLeft - 1;
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left = *run++;
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite = *run++;
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(left < rite);
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(left > prevRite);
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(rite <= bounds.fRight);
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            prevRite = rite;
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (*run < SkRegion::kRunTypeSentinel);
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return run + 1; // skip sentinel
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::validate() const
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty())
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // check for explicit empty (the zero rect), so we can compare rects to know when
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // two regions are equal (i.e. emptyRectA == emptyRectB)
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this is stricter than just asserting fBounds.isEmpty()
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fBounds.fLeft == 0 && fBounds.fTop == 0 && fBounds.fRight == 0 && fBounds.fBottom == 0);
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!fBounds.isEmpty());
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (!this->isRect())
10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(fRunHead->fRefCnt >= 1);
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(fRunHead->fRunCount >= kRectRegionRuns);
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const RunType* run = fRunHead->readonly_runs();
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const RunType* stop = run + fRunHead->fRunCount;
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // check that our bounds match our runs
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIRect bounds;
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bool isARect = ComputeRunBounds(run, stop - run, &bounds);
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(!isARect);
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(bounds == fBounds);
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(*run == fBounds.fTop);
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            run++;
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            do {
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                run = validate_line(run, fBounds);
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } while (*run < kRunTypeSentinel);
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(run + 1 == stop);
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::dump() const
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isEmpty())
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("  rgn: empty\n");
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("  rgn: [%d %d %d %d]", fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom);
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isComplex())
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const RunType* runs = fRunHead->readonly_runs();
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (int i = 0; i < fRunHead->fRunCount; i++)
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkDebugf(" %d", runs[i]);
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("\n");
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::Iterator::Iterator(const SkRegion& rgn) {
11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->reset(rgn);
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::Iterator::rewind() {
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fRgn) {
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->reset(*fRgn);
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Iterator::reset(const SkRegion& rgn) {
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRgn = &rgn;
11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (rgn.isEmpty()) {
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fDone = true;
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fDone = false;
11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (rgn.isRect()) {
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRect = rgn.fBounds;
11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRuns = NULL;
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRuns = rgn.fRunHead->readonly_runs();
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRect.set(fRuns[2], fRuns[0], fRuns[3], fRuns[1]);
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRuns += 4;
11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Iterator::next() {
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fDone) {
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fRuns == NULL) {   // rect case
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fDone = true;
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType* runs = fRuns;
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (runs[0] < kRunTypeSentinel) { // valid X value
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fRect.fLeft = runs[0];
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fRect.fRight = runs[1];
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += 2;
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // we're at the end of a line
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += 1;
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (runs[0] < kRunTypeSentinel) { // valid Y value
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (runs[1] == kRunTypeSentinel) {    // empty line
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fRect.fTop = runs[0];
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                runs += 2;
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fRect.fTop = fRect.fBottom;
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRect.fBottom = runs[0];
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            assert_sentinel(runs[1], false);
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRect.fLeft = runs[1];
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRect.fRight = runs[2];
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += 3;
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {    // end of rgn
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fDone = true;
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRuns = runs;
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::Cliperator::Cliperator(const SkRegion& rgn, const SkIRect& clip)
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : fIter(rgn), fClip(clip), fDone(true) {
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect& r = fIter.rect();
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!fIter.done()) {
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (r.fTop >= clip.fBottom) {
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fRect.intersect(clip, r)) {
12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fDone = false;
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fIter.next();
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Cliperator::next() {
12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fDone) {
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect& r = fIter.rect();
12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDone = true;
12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fIter.next();
12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!fIter.done()) {
12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (r.fTop >= fClip.fBottom) {
12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fRect.intersect(fClip, r)) {
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fDone = false;
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fIter.next();
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
123840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
124040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkRegion::RunType* find_y(const SkRegion::RunType runs[], int y) {
124140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    int top = *runs++;
124240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (top <= y) {
124340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        for (;;) {
124440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            int bot = *runs++;
124540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (bot > y) {
124640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (bot == SkRegion::kRunTypeSentinel ||
124740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    *runs == SkRegion::kRunTypeSentinel) {
124840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    break;
124940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger				}
125040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                return (SkRegion::RunType*)runs;
125140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
125240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            runs = skip_scanline(runs);
125340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
125440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
125540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return NULL;
125640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
125740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
125840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRegion::Spanerator::Spanerator(const SkRegion& rgn, int y, int left,
125940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                 int right) {
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(rgn.validate();)
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect& r = rgn.getBounds();
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDone = true;
126540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!rgn.isEmpty() && y >= r.fTop && y < r.fBottom &&
126640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            right > r.fLeft && left < r.fRight) {
126740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (rgn.isRect()) {
126840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (left < r.fLeft) {
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                left = r.fLeft;
127040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
127140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (right > r.fRight) {
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                right = r.fRight;
127340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fLeft = left;
12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRight = right;
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRuns = NULL;    // means we're a rect, not a rgn
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fDone = false;
127840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
127940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            const SkRegion::RunType* runs = find_y(
128040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                              rgn.fRunHead->readonly_runs(), y);
128140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (runs) {
128240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                for (;;) {
128340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    // runs[0..1] is to the right of the span, so we're done
128440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    if (runs[0] >= right) {
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        break;
128640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    }
128740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    // runs[0..1] is to the left of the span, so continue
128840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    if (runs[1] <= left) {
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        runs += 2;
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        continue;
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    // runs[0..1] intersects the span
12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    fRuns = runs;
12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    fLeft = left;
12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    fRight = right;
12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    fDone = false;
12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    break;
12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkRegion::Spanerator::next(int* left, int* right) {
130540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (fDone) {
130640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        return false;
130740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (fRuns == NULL) {   // we're a rect
13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fDone = true;   // ok, now we're done
131140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (left) {
131240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            *left = fLeft;
131340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
131440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (right) {
131540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            *right = fRight;
131640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;    // this interval is legal
13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkRegion::RunType* runs = fRuns;
13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
132240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (runs[0] >= fRight) {
13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fDone = true;
13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(runs[1] > fLeft);
13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
132940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (left) {
13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *left = SkMax32(fLeft, runs[0]);
133140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
133240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (right) {
13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *right = SkMin32(fRight, runs[1]);
133440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRuns = runs + 2;
13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::debugSetRuns(const RunType runs[], int count) {
13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // we need to make a copy, since the real method may modify the array, and
13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // so it cannot be const.
13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoTArray<RunType> storage(count);
13480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(storage.get(), runs, count * sizeof(RunType));
13490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return this->setRuns(storage.get(), count);
13500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1353