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