SkRegion.cpp revision 9221e8085d77b0850a07c6585275ec7bb7e0931a
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/corecg/SkRegion.cpp 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License. 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRegionPriv.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h" 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkThread.h" 219221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato#include <stdio.h> 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDEBUGCODE(int32_t gRgnAllocCounter;) 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////////////// 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* Pass in a scanline, beginning with the Left value of the pair (i.e. not the Y beginning) 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* skip_scanline(const SkRegion::RunType runs[]) 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (runs[0] != SkRegion::kRunTypeSentinel) 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(runs[0] < runs[1]); // valid span 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (SkRegion::RunType*)(runs + 1); // return past the X-sentinel 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* find_y(const SkRegion::RunType runs[], int y) 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int top = *runs++; 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (top <= y) 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (;;) 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int bot = *runs++; 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bot > y) 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bot == SkRegion::kRunTypeSentinel || *runs == SkRegion::kRunTypeSentinel) 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (SkRegion::RunType*)runs; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project top = bot; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs = skip_scanline(runs); 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns true if runs are just a rect 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::ComputeRunBounds(const SkRegion::RunType runs[], int count, SkIRect* bounds) 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[0], false); // top 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count == kRectRegionRuns) 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[1], false); // bottom 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[2], false); // left 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[3], false); // right 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[4], true); 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[5], true); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(runs[0] < runs[1]); // valid height 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(runs[2] < runs[3]); // valid width 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(runs[2], runs[0], runs[3], runs[1]); 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left = SK_MaxS32; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite = SK_MinS32; 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int bot; 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fTop = *runs++; 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = *runs++; 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (*runs < SkRegion::kRunTypeSentinel) 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left > *runs) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = *runs; 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs = skip_scanline(runs); 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (rite < runs[-2]) 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = runs[-2]; 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 1; // skip X-sentinel 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (runs[0] < SkRegion::kRunTypeSentinel); 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fLeft = left; 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fRight = rite; 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fBottom = bot; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////// 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::SkRegion() 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.set(0, 0, 0, 0); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = SkRegion_gEmptyRunHeadPtr; 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::SkRegion(const SkRegion& src) 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead) 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->setRegion(src); 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::SkRegion(const SkIRect& rect) 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead) 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->setRect(rect); 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::~SkRegion() 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->freeRuns(); 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::freeRuns() 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRunHead->isComplex()) 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRunHead->fRefCnt >= 1); 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (sk_atomic_dec(&fRunHead->fRefCnt) == 1) 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project //SkASSERT(gRgnAllocCounter > 0); 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project //SkDEBUGCODE(sk_atomic_dec(&gRgnAllocCounter)); 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project //SkDEBUGF(("************** gRgnAllocCounter::free %d\n", gRgnAllocCounter)); 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(fRunHead); 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::allocateRuns(int count) 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = RunHead::Alloc(count); 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion& SkRegion::operator=(const SkRegion& src) 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (void)this->setRegion(src); 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return *this; 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::swap(SkRegion& other) 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTSwap<SkIRect>(fBounds, other.fBounds); 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTSwap<RunHead*>(fRunHead, other.fRunHead); 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setEmpty() 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->freeRuns(); 1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.set(0, 0, 0, 0); 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = SkRegion_gEmptyRunHeadPtr; 1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setRect(int32_t left, int32_t top, int32_t right, int32_t bottom) 1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left >= right || top >= bottom) 1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setEmpty(); 1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->freeRuns(); 1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.set(left, top, right, bottom); 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = SkRegion_gRectRunHeadPtr; 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setRect(const SkIRect& r) 1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRect(r.fLeft, r.fTop, r.fRight, r.fBottom); 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setRegion(const SkRegion& src) 1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this != &src) 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->freeRuns(); 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds = src.fBounds; 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = src.fRunHead; 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRunHead->isComplex()) 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_atomic_inc(&fRunHead->fRefCnt); 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fRunHead != SkRegion_gEmptyRunHeadPtr; 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::op(const SkIRect& rect, const SkRegion& rgn, Op op) 2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp(rect); 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->op(tmp, rgn, op); 2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op) 2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp(rect); 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->op(rgn, tmp, op); 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////// 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2159221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onoratochar* SkRegion::toString() 2169221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato{ 2179221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato Iterator iter(*this); 2189221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato int count = 0; 2199221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato while (!iter.done()) { 2209221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato count++; 2219221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato iter.next(); 2229221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato } 2239221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() and '\0' 2249221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato const int max = (count*((11*4)+5))+11+1; 2259221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato char* result = (char*)malloc(max); 2269221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato if (result == NULL) { 2279221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato return NULL; 2289221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato } 2299221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato count = sprintf(result, "SkRegion("); 2309221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato iter.reset(*this); 2319221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato while (!iter.done()) { 2329221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato const SkIRect& r = iter.rect(); 2339221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRight, r.fBottom); 2349221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato iter.next(); 2359221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato } 2369221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato count += sprintf(result+count, ")"); 2379221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato return result; 2389221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato} 2399221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato 2409221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato////////////////////////////////////////////////////////////////////////////////////// 2419221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkRegion::count_runtype_values(int* itop, int* ibot) const 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this == NULL) 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *itop = SK_MinS32; 2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *ibot = SK_MaxS32; 2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int maxT; 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isRect()) 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project maxT = 2; 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->isComplex()); 2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // skip the top 2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* runs = fRunHead->readonly_runs() + 1; 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project maxT = 0; 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* next = skip_scanline(runs + 1); 2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(next > runs); 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int T = (int)(next - runs - 1); 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (maxT < T) 2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project maxT = T; 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs = next; 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (runs[0] < SkRegion::kRunTypeSentinel); 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *itop = fBounds.fTop; 2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *ibot = fBounds.fBottom; 2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return maxT; 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::setRuns(RunType runs[], int count) 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(this->validate();) 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count > 0); 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count <= 2) 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // SkDEBUGF(("setRuns: empty\n")); 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[count-1], true); 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setEmpty(); 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // trim off any empty spans from the top and bottom 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // weird I should need this, perhaps op() could be smarter... 2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > kRectRegionRuns) 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType* stop = runs + count; 2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[0], false); // top 2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[1], false); // bottom 2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[2] == SkRegion::kRunTypeSentinel) // should be first left... 2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; // skip empty initial span 2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[0] = runs[-1]; // set new top to prev bottom 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[1], false); // bot: a sentinal would mean two in a row 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[2], false); // left 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[3], false); // right 3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now check for a trailing empty span 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-1], true); 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-2], true); 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-3], false); // should be last right 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (stop[-4] == SkRegion::kRunTypeSentinel) // eek, stop[-3] was a bottom with no x-runs 3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project stop[-3] = SkRegion::kRunTypeSentinel; // kill empty last span 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project stop -= 2; 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-1], true); 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-2], true); 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-3], false); 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-4], false); 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(stop[-5], false); 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = (int)(stop - runs); 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count >= kRectRegionRuns); 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ComputeRunBounds(runs, count, &fBounds)) 3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // SkDEBUGF(("setRuns: rect[%d %d %d %d]\n", fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom)); 3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRect(fBounds); 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we get here, we need to become a complex region 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!fRunHead->isComplex() || fRunHead->fRunCount != count) 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUGx 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("setRuns: rgn ["); 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* r = runs; 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" top: %d\n", *r++); 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (*r < SkRegion::kRunTypeSentinel) 3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" bottom: %d", *r++); 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (*r < SkRegion::kRunTypeSentinel) 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" [%d %d]", r[0], r[1]); 3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project r += 2; 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("\n"); 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->freeRuns(); 3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->allocateRuns(count); 3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // must call this before we can write directly into runs() 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // in case we are sharing the buffer with another region (copy on write) 3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead = fRunHead->ensureWritable(); 3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(fRunHead->writable_runs(), runs, count * sizeof(RunType)); 3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(this->validate();) 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::BuildRectRuns(const SkIRect& bounds, 3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType runs[kRectRegionRuns]) 3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[0] = bounds.fTop; 3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[1] = bounds.fBottom; 3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[2] = bounds.fLeft; 3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[3] = bounds.fRight; 3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[4] = kRunTypeSentinel; 3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs[5] = kRunTypeSentinel; 3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* find_scanline(const SkRegion::RunType runs[], int y) 3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(y >= runs[0]); // if this fails, we didn't do a quick check on the boudns 3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 1; // skip top-Y 3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (;;) 3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[0] == SkRegion::kRunTypeSentinel) 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (y < runs[0]) 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (SkRegion::RunType*)&runs[1]; 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs = skip_scanline(runs + 1); // skip the Y value before calling 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3922c497e64d20a73267eb92ae88fdc51ba2a356b55Mike Reedbool SkRegion::contains(int32_t x, int32_t y) const 3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!fBounds.contains(x, y)) 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isRect()) 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->isComplex()); 4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* runs = find_scanline(fRunHead->readonly_runs(), y); 4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs) 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { for (;;) 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { if (x < runs[0]) 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x < runs[1]) 4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; 4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::contains(const SkIRect& r) const 4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp(r); 4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->contains(tmp); 4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::contains(const SkRegion& rgn) const 4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty() || rgn.isEmpty() || !fBounds.contains(rgn.fBounds)) 4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 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 SkRegion tmp; 4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp.op(*this, rgn, kUnion_Op); 4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return tmp == *this; 4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[], int* count) const 4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(tmpStorage && count); 4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* runs = tmpStorage; 4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty()) 4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmpStorage[0] = kRunTypeSentinel; 4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = 1; 4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (this->isRect()) 4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project BuildRectRuns(fBounds, tmpStorage); 4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = kRectRegionRuns; 4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = fRunHead->fRunCount; 4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs = fRunHead->readonly_runs(); 4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return runs; 4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////// 4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::intersects(const SkIRect& r) const { 4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty() || r.isEmpty()) { 4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!SkIRect::Intersects(fBounds, r)) { 4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isRect()) { 4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we are complex 4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp; 4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return tmp.op(*this, r, kIntersect_Op); 4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::intersects(const SkRegion& rgn) const { 4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty() || rgn.isEmpty()) { 4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!SkIRect::Intersects(fBounds, rgn.fBounds)) { 4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isRect() && rgn.isRect()) { 4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // one or both of us is complex 4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // TODO: write a faster version that aborts as soon as we write the first 4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // non-empty span, to avoid build the entire result 4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp; 4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return tmp.op(*this, rgn, kIntersect_Op); 4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////// 5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint operator==(const SkRegion& a, const SkRegion& b) 5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(a.validate();) 5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(b.validate();) 5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (&a == &b) 5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a.fBounds != b.fBounds) 5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunHead* ah = a.fRunHead; 5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunHead* bh = b.fRunHead; 5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this catches empties and rects being equal 5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ah == bh) 5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now we insist that both are complex (but different ptrs) 5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!ah->isComplex() || !bh->isComplex()) 5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return ah->fRunCount == bh->fRunCount && 5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project !memcmp(ah->readonly_runs(), bh->readonly_runs(), 5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ah->fRunCount * sizeof(SkRegion::RunType)); 5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::translate(int dx, int dy, SkRegion* dst) const 5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(this->validate();) 5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == dst) 5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty()) 5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->setEmpty(); 5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (this->isRect()) 5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy, 5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.fRight + dx, fBounds.fBottom + dy); 5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this == dst) 5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->fRunHead = dst->fRunHead->ensureWritable(); 5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp; 5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp.allocateRuns(fRunHead->fRunCount); 5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp.fBounds = fBounds; 5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->swap(tmp); 5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->fBounds.offset(dx, dy); 5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* sruns = fRunHead->readonly_runs(); 5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType* druns = dst->fRunHead->writable_runs(); 5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = (SkRegion::RunType)(*sruns++ + dy); // top 5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (;;) 5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int bottom = *sruns++; 5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bottom == kRunTypeSentinel) 5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = (SkRegion::RunType)(bottom + dy); // bottom; 5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (;;) 5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int x = *sruns++; 5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x == kRunTypeSentinel) 5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = (SkRegion::RunType)(x + dx); 5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = (SkRegion::RunType)(*sruns++ + dx); 5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = kRunTypeSentinel; // x sentinel 5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *druns++ = kRunTypeSentinel; // y sentinel 5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(sruns - fRunHead->readonly_runs() == fRunHead->fRunCount); 5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(druns - dst->fRunHead->readonly_runs() == dst->fRunHead->fRunCount); 5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(this->validate();) 5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////// 5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if defined _WIN32 && _MSC_VER >= 1300 // disable warning : local variable used without having been initialized 5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( push ) 5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( disable : 4701 ) 5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void assert_valid_pair(int left, int rite) 5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left == SkRegion::kRunTypeSentinel || left < rite); 5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project #define assert_valid_pair(left, rite) 5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstruct spanRec { 6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* fA_runs; 6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* fB_runs; 6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int fA_left, fA_rite, fB_left, fB_rite; 6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int fLeft, fRite, fInside; 6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void init(const SkRegion::RunType a_runs[], const SkRegion::RunType b_runs[]) 6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fA_left = *a_runs++; 6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fA_rite = *a_runs++; 6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fB_left = *b_runs++; 6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fB_rite = *b_runs++; 6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fA_runs = a_runs; 6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fB_runs = b_runs; 6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool done() const 6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fA_left <= SkRegion::kRunTypeSentinel); 6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fB_left <= SkRegion::kRunTypeSentinel); 6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fA_left == SkRegion::kRunTypeSentinel && fB_left == SkRegion::kRunTypeSentinel; 6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void next() 6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_valid_pair(fA_left, fA_rite); 6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_valid_pair(fB_left, fB_rite); 6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int inside, left, rite SK_INIT_TO_AVOID_WARNING; 6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool a_flush = false; 6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool b_flush = false; 6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_left = fA_left; 6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_rite = fA_rite; 6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int b_left = fB_left; 6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int b_rite = fB_rite; 6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_left < b_left) 6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 1; 6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = a_left; 6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_rite <= b_left) // [...] <...> 6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = a_rite; 6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_flush = true; 6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // [...<..]...> or [...<...>...] 6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = a_left = b_left; 6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (b_left < a_left) 6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 2; 6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = b_left; 6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_rite <= a_left) // [...] <...> 6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = b_rite; 6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_flush = true; 6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // [...<..]...> or [...<...>...] 6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = b_left = a_left; 6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // a_left == b_left 6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 3; 6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = a_left; // or b_left 6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_rite <= b_rite) 6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = b_left = a_rite; 6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_flush = true; 6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_rite <= a_rite) 6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rite = a_left = b_rite; 6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_flush = true; 6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_flush) 6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_left = *fA_runs++; 6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_rite = *fA_runs++; 6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_flush) 6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_left = *fB_runs++; 6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_rite = *fB_runs++; 6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left <= rite); 6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now update our state 6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fA_left = a_left; 6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fA_rite = a_rite; 6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fB_left = b_left; 6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fB_rite = b_rite; 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLeft = left; 6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRite = rite; 6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fInside = inside; 7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkRegion::RunType* operate_on_span(const SkRegion::RunType a_runs[], 7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType b_runs[], 7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType dst[], 7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int min, int max) 7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project spanRec rec; 7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool firstInterval = true; 7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.init(a_runs, b_runs); 7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!rec.done()) 7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.next(); 7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left = rec.fLeft; 7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite = rec.fRite; 7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // add left,rite to our dst buffer (checking for coincidence 7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((unsigned)(rec.fInside - min) <= (unsigned)(max - min) && 7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left < rite) // skip if equal 7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (firstInterval || dst[-1] < left) 7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = (SkRegion::RunType)(left); 7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = (SkRegion::RunType)(rite); 7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project firstInterval = false; 7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // update the right edge 7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst[-1] = (SkRegion::RunType)(rite); 7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = SkRegion::kRunTypeSentinel; 7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if defined _WIN32 && _MSC_VER >= 1300 7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#pragma warning ( pop ) 7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const struct { 7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint8_t fMin; 7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint8_t fMax; 7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} gOpMinMax[] = { 7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1, 1 }, // Difference 7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 3, 3 }, // Intersection 7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1, 3 }, // Union 7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1, 2 } // XOR 7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass RgnOper { 7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RgnOper(int top, SkRegion::RunType dst[], SkRegion::Op op) 7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // need to ensure that the op enum lines up with our minmax array 7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkRegion::kDifference_Op == 0); 7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkRegion::kIntersect_Op == 1); 7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkRegion::kUnion_Op == 2); 7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkRegion::kXOR_Op == 3); 7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)op <= 3); 7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStartDst = dst; 7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevDst = dst + 1; 7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevLen = 0; // will never match a length from operate_on_span 7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTop = (SkRegion::RunType)(top); // just a first guess, we might update this 7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMin = gOpMinMax[op].fMin; 7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMax = gOpMinMax[op].fMax; 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void addSpan(int bottom, const SkRegion::RunType a_runs[], const SkRegion::RunType b_runs[]) 7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType* start = fPrevDst + fPrevLen + 1; // skip X values and slot for the next Y 7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType* stop = operate_on_span(a_runs, b_runs, start, fMin, fMax); 7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t len = stop - start; 7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fPrevLen == len && !memcmp(fPrevDst, start, len * sizeof(SkRegion::RunType))) // update Y value 7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevDst[-1] = (SkRegion::RunType)(bottom); 7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // accept the new span 7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (len == 1 && fPrevLen == 0) { 7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTop = (SkRegion::RunType)(bottom); // just update our bottom 7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project start[-1] = (SkRegion::RunType)(bottom); 7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevDst = start; 7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevLen = len; 7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int flush() 7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStartDst[0] = fTop; 7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevDst[fPrevLen] = SkRegion::kRunTypeSentinel; 7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (int)(fPrevDst - fStartDst + fPrevLen + 1); 7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint8_t fMin, fMax; 8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType* fStartDst; 8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType* fPrevDst; 8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t fPrevLen; 8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType fTop; 8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int operate( const SkRegion::RunType a_runs[], 8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType b_runs[], 8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::RunType dst[], 8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion::Op op) 8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 8144c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed const SkRegion::RunType gSentinel[] = { 8154c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed SkRegion::kRunTypeSentinel, 8164c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed // just need a 2nd value, since spanRec.init() reads 2 values, even 8174c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed // though if the first value is the sentinel, it ignores the 2nd value. 8184c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed // w/o the 2nd value here, we might read uninitialized memory. 8194c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed 0, 8204c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed }; 8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_top = *a_runs++; 8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_bot = *a_runs++; 8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int b_top = *b_runs++; 8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int b_bot = *b_runs++; 8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(a_top, false); 8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(a_bot, false); 8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(b_top, false); 8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(b_bot, false); 8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RgnOper oper(SkMin32(a_top, b_top), dst, op); 8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool firstInterval = true; 8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int prevBot = SkRegion::kRunTypeSentinel; // so we fail the first test 8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (a_bot < SkRegion::kRunTypeSentinel || b_bot < SkRegion::kRunTypeSentinel) 8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int top, bot SK_INIT_TO_AVOID_WARNING; 8404c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed const SkRegion::RunType* run0 = gSentinel; 8414c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed const SkRegion::RunType* run1 = gSentinel; 8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool a_flush = false; 8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool b_flush = false; 8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int inside; 8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_top < b_top) 8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 1; 8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project top = a_top; 8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run0 = a_runs; 8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_bot <= b_top) // [...] <...> 8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = a_bot; 8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_flush = true; 8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // [...<..]...> or [...<...>...] 8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = a_top = b_top; 8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (b_top < a_top) 8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 2; 8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project top = b_top; 8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run1 = b_runs; 8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_bot <= a_top) // [...] <...> 8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = b_bot; 8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_flush = true; 8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // [...<..]...> or [...<...>...] 8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = b_top = a_top; 8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // a_top == b_top 8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project inside = 3; 8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project top = a_top; // or b_top 8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run0 = a_runs; 8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run1 = b_runs; 8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_bot <= b_bot) 8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = b_top = a_bot; 8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_flush = true; 8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_bot <= a_bot) 8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bot = a_top = b_bot; 8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_flush = true; 8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (top > prevBot) 8914c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed oper.addSpan(top, gSentinel, gSentinel); 8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// if ((unsigned)(inside - oper.fMin) <= (unsigned)(oper.fMax - oper.fMin)) 8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project oper.addSpan(bot, run0, run1); 8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project firstInterval = false; 8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_flush) 9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_runs = skip_scanline(a_runs); 9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_top = a_bot; 9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_bot = *a_runs++; 9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_bot == SkRegion::kRunTypeSentinel) 9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project a_top = a_bot; 9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_flush) 9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_runs = skip_scanline(b_runs); 9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_top = b_bot; 9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_bot = *b_runs++; 9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_bot == SkRegion::kRunTypeSentinel) 9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project b_top = b_bot; 9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevBot = bot; 9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return oper.flush(); 9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* Given count RunTypes in a complex region, return the worst case number of 9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project logical intervals that represents (i.e. number of rects that would be 9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project returned from the iterator). 9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project We could just return count/2, since there must be at least 2 values per 9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project interval, but we can first trim off the const overhead of the initial TOP 9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project value, plus the final BOTTOM + 2 sentinels. 9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int count_to_intervals(int count) { 9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count >= 6); // a single rect is 6 values 9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (count - 4) >> 1; 9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* Given a number of intervals, what is the worst case representation of that 9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project many intervals? 9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Worst case (from a storage perspective), is a vertical stack of single 9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project intervals: TOP + N * (BOTTOM LEFT RIGHT SENTINEL) + SENTINEL 9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int intervals_to_count(int intervals) { 9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 1 + intervals * 4 + 1; 9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* Given the counts of RunTypes in two regions, return the worst-case number 9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project of RunTypes need to store the result after a region-op. 9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int compute_worst_case_count(int a_count, int b_count) { 9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_intervals = count_to_intervals(a_count); 9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int b_intervals = count_to_intervals(b_count); 9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // Our heuristic worst case is ai * (bi + 1) + bi * (ai + 1) 9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int intervals = 2 * a_intervals * b_intervals + a_intervals + b_intervals; 9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // convert back to number of RunType values 9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return intervals_to_count(intervals); 9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::op(const SkRegion& rgnaOrig, const SkRegion& rgnbOrig, Op op) 9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(this->validate();) 9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)op < kOpCount); 9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (kReplace_Op == op) 9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->set(rgnbOrig); 9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // swith to using pointers, so we can swap them as needed 9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion* rgna = &rgnaOrig; 9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion* rgnb = &rgnbOrig; 9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // after this point, do not refer to rgnaOrig or rgnbOrig!!! 9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // collaps difference and reverse-difference into just difference 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (kReverseDifference_Op == op) 9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTSwap<const SkRegion*>(rgna, rgnb); 9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project op = kDifference_Op; 9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect bounds; 9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool a_empty = rgna->isEmpty(); 9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool b_empty = rgnb->isEmpty(); 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool a_rect = rgna->isRect(); 9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool b_rect = rgnb->isRect(); 9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (op) { 9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kDifference_Op: 9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_empty) 9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setEmpty(); 9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_empty || !SkIRect::Intersects(rgna->fBounds, rgnb->fBounds)) 9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgna); 9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kIntersect_Op: 9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if ((a_empty | b_empty) 9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project || !bounds.intersect(rgna->fBounds, rgnb->fBounds)) 9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setEmpty(); 9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_rect & b_rect) 9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRect(bounds); 9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUnion_Op: 10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_empty) 10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgnb); 10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_empty) 10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgna); 10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_rect && rgna->fBounds.contains(rgnb->fBounds)) 10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgna); 10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_rect && rgnb->fBounds.contains(rgna->fBounds)) 10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgnb); 10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kXOR_Op: 10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (a_empty) 10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgnb); 10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (b_empty) 10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRegion(*rgna); 10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(!"unknown region op"); 10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return !this->isEmpty(); 10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType tmpA[kRectRegionRuns]; 10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType tmpB[kRectRegionRuns]; 10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int a_count, b_count; 10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* a_runs = rgna->getRuns(tmpA, &a_count); 10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* b_runs = rgnb->getRuns(tmpB, &b_count); 10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int dstCount = compute_worst_case_count(a_count, b_count); 10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoSTMalloc<32, RunType> array(dstCount); 10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = operate(a_runs, b_runs, array.get(), op); 10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count <= dstCount); 10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRuns(array.get(), count); 10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////// 10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBuffer.h" 10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint32_t SkRegion::flatten(void* storage) const { 10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == storage) { 10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount 10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!this->isEmpty()) { 10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size += sizeof(fBounds); 10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isComplex()) { 10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size += fRunHead->fRunCount * sizeof(RunType); 10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return size; 10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkWBuffer buffer(storage); 10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty()) { 10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(-1); 10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool isRect = this->isRect(); 10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write32(isRect ? 0 : fRunHead->fRunCount); 10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write(&fBounds, sizeof(fBounds)); 10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!isRect) { 10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write(fRunHead->readonly_runs(), 10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead->fRunCount * sizeof(RunType)); 10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return buffer.pos(); 10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectuint32_t SkRegion::unflatten(const void* storage) { 10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRBuffer buffer(storage); 10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion tmp; 10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int32_t count; 10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = buffer.readS32(); 10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count >= 0) { 10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.read(&tmp.fBounds, sizeof(tmp.fBounds)); 10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count == 0) { 10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp.fRunHead = SkRegion_gRectRunHeadPtr; 10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project tmp.allocateRuns(count); 10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(RunType)); 10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->swap(tmp); 10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return buffer.pos(); 10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////// 10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkRegion::RunType* validate_line(const SkRegion::RunType run[], const SkIRect& bounds) 10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // *run is the bottom of the current span 10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(*run > bounds.fTop); 10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(*run <= bounds.fBottom); 11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run += 1; 11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // check for empty span 11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (*run != SkRegion::kRunTypeSentinel) 11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int prevRite = bounds.fLeft - 1; 11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int left = *run++; 11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rite = *run++; 11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left < rite); 11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(left > prevRite); 11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(rite <= bounds.fRight); 11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevRite = rite; 11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (*run < SkRegion::kRunTypeSentinel); 11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return run + 1; // skip sentinel 11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::validate() const 11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty()) 11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // check for explicit empty (the zero rect), so we can compare rects to know when 11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // two regions are equal (i.e. emptyRectA == emptyRectB) 11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this is stricter than just asserting fBounds.isEmpty() 11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fBounds.fLeft == 0 && fBounds.fTop == 0 && fBounds.fRight == 0 && fBounds.fBottom == 0); 11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(!fBounds.isEmpty()); 11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!this->isRect()) 11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRunHead->fRefCnt >= 1); 11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fRunHead->fRunCount >= kRectRegionRuns); 11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* run = fRunHead->readonly_runs(); 11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* stop = run + fRunHead->fRunCount; 11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // check that our bounds match our runs 11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect bounds; 11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool isARect = ComputeRunBounds(run, stop - run, &bounds); 11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(!isARect); 11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(bounds == fBounds); 11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(*run == fBounds.fTop); 11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run++; 11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project do { 11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project run = validate_line(run, fBounds); 11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } while (*run < kRunTypeSentinel); 11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(run + 1 == stop); 11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::dump() const 11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isEmpty()) 11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" rgn: empty\n"); 11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" rgn: [%d %d %d %d]", fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom); 11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->isComplex()) 11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* runs = fRunHead->readonly_runs(); 11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (int i = 0; i < fRunHead->fRunCount; i++) 11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf(" %d", runs[i]); 11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("\n"); 11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////// 11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::Iterator::Iterator(const SkRegion& rgn) { 11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->reset(rgn); 11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::Iterator::rewind() { 11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRgn) { 11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->reset(*fRgn); 11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Iterator::reset(const SkRegion& rgn) { 11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRgn = &rgn; 11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (rgn.isEmpty()) { 11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = false; 11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (rgn.isRect()) { 11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect = rgn.fBounds; 11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = NULL; 11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = rgn.fRunHead->readonly_runs(); 12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.set(fRuns[2], fRuns[0], fRuns[3], fRuns[1]); 12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns += 4; 12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Iterator::next() { 12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fDone) { 12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRuns == NULL) { // rect case 12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* runs = fRuns; 12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[0] < kRunTypeSentinel) { // valid X value 12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fLeft = runs[0]; 12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fRight = runs[1]; 12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; 12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // we're at the end of a line 12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 1; 12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[0] < kRunTypeSentinel) { // valid Y value 12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[1] == kRunTypeSentinel) { // empty line 12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fTop = runs[0]; 12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; 12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fTop = fRect.fBottom; 12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fBottom = runs[0]; 12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project assert_sentinel(runs[1], false); 12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fLeft = runs[1]; 12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRect.fRight = runs[2]; 12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 3; 12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // end of rgn 12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = runs; 12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::Cliperator::Cliperator(const SkRegion& rgn, const SkIRect& clip) 12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : fIter(rgn), fClip(clip), fDone(true) { 12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = fIter.rect(); 12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!fIter.done()) { 12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (r.fTop >= clip.fBottom) { 12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRect.intersect(clip, r)) { 12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = false; 12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fIter.next(); 12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkRegion::Cliperator::next() { 12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fDone) { 12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = fIter.rect(); 12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fIter.next(); 12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (!fIter.done()) { 12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (r.fTop >= fClip.fBottom) { 12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRect.intersect(fClip, r)) { 12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = false; 12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fIter.next(); 12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////// 12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRegion::Spanerator::Spanerator(const SkRegion& rgn, int y, int left, int right) 12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(rgn.validate();) 12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& r = rgn.getBounds(); 12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (!rgn.isEmpty() && y >= r.fTop && y < r.fBottom && right > r.fLeft && left < r.fRight) 12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (rgn.isRect()) 12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left < r.fLeft) 12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project left = r.fLeft; 12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (right > r.fRight) 12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project right = r.fRight; 12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLeft = left; 13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRight = right; 13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = NULL; // means we're a rect, not a rgn 13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = false; 13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* runs = find_y(rgn.fRunHead->readonly_runs(), y); 13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs) 13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (;;) 13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[0] >= right) // runs[0..1] is to the right of the span, so we're done 13120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 13130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[1] <= left) // runs[0..1] is to the left of the span, so continue 13140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project runs += 2; 13160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project continue; 13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // runs[0..1] intersects the span 13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = runs; 13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLeft = left; 13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRight = right; 13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = false; 13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::Spanerator::next(int* left, int* right) 13310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 13320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fDone) return false; 13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fRuns == NULL) // we're a rect 13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; // ok, now we're done 13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left) *left = fLeft; 13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (right) *right = fRight; 13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; // this interval is legal 13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* runs = fRuns; 13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (runs[0] >= fRight) 13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fDone = true; 13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 13480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(runs[1] > fLeft); 13510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (left) 13530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *left = SkMax32(fLeft, runs[0]); 13540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (right) 13550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *right = SkMin32(fRight, runs[1]); 13560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRuns = runs + 2; 13570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 13580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 13610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 13630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkRegion::debugSetRuns(const RunType runs[], int count) { 13650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we need to make a copy, since the real method may modify the array, and 13660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // so it cannot be const. 13670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoTArray<RunType> storage(count); 13690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(storage.get(), runs, count * sizeof(RunType)); 13700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->setRuns(storage.get(), count); 13710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1374