1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/* 3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project 4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * 5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file. 7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkRegionPriv.h" 11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkBlitter.h" 12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkScan.h" 13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTDArray.h" 14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkPath.h" 15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkRgnBuilder : public SkBlitter { 17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual ~SkRgnBuilder(); 19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // returns true if it could allocate the working storage needed 21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bool init(int maxHeight, int maxTransitions); 22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void done() { 24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (fCurrScanline != NULL) { 25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurrScanline->firstX())); 26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!this->collapsWithPrev()) { // flush the last line 27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline = fCurrScanline->nextScanline(); 28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int computeRunCount() const; 33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void copyToRect(SkIRect*) const; 34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void copyToRgn(SkRegion::RunType runs[]) const; 35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void blitH(int x, int y, int width); 37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_DEBUG 39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void dump() const { 40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDebugf("SkRgnBuilder: Top = %d\n", fTop); 41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const Scanline* line = (Scanline*)fStorage; 42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (line < fCurrScanline) { 43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDebugf("SkRgnBuilder::Scanline: LastY=%d, fXCount=%d", line->fLastY, line->fXCount); 44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = 0; i < line->fXCount; i++) { 45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDebugf(" %d", line->firstX()[i]); 46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDebugf("\n"); 48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger line = line->nextScanline(); 50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger struct Scanline { 55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType fLastY; 56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType fXCount; 57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType* firstX() const { return (SkRegion::RunType*)(this + 1); } 59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Scanline* nextScanline() const { 60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (Scanline*)((SkRegion::RunType*)(this + 1) + fXCount); 61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger }; 63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType* fStorage; 64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Scanline* fCurrScanline; 65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Scanline* fPrevScanline; 66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // points at next avialable x[] in fCurrScanline 67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType* fCurrXPtr; 68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType fTop; // first Y value 69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int fStorageCount; 71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bool collapsWithPrev() { 73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (fPrevScanline != NULL && 74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fPrevScanline->fLastY + 1 == fCurrScanline->fLastY && 75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fPrevScanline->fXCount == fCurrScanline->fXCount && 76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger !memcmp(fPrevScanline->firstX(), 77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->firstX(), 78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fXCount * sizeof(SkRegion::RunType))) 79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { 80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // update the height of fPrevScanline 81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fPrevScanline->fLastY = fCurrScanline->fLastY; 82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 88f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkRgnBuilder::~SkRgnBuilder() { 89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger sk_free(fStorage); 90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkRgnBuilder::init(int maxHeight, int maxTransitions) { 93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((maxHeight | maxTransitions) < 0) { 94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Sk64 count, size; 98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // compute the count with +1 and +3 slop for the working buffer 100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger count.setMul(maxHeight + 1, 3 + maxTransitions); 101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!count.is32() || count.isNeg()) { 102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fStorageCount = count.get32(); 105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger size.setMul(fStorageCount, sizeof(SkRegion::RunType)); 107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!size.is32() || size.isNeg()) { 108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fStorage = (SkRegion::RunType*)sk_malloc_flags(size.get32(), 0); 112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == fStorage) { 113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline = NULL; // signal empty collection 117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fPrevScanline = NULL; // signal first scanline 118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkRgnBuilder::blitH(int x, int y, int width) { 122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (fCurrScanline == NULL) { // first time 123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fTop = (SkRegion::RunType)(y); 124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline = (Scanline*)fStorage; 125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fLastY = (SkRegion::RunType)(y); 126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr = fCurrScanline->firstX(); 127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(y >= fCurrScanline->fLastY); 129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (y > fCurrScanline->fLastY) { 131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // if we get here, we're done with fCurrScanline 132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurrScanline->firstX())); 133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int prevLastY = fCurrScanline->fLastY; 135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!this->collapsWithPrev()) { 136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fPrevScanline = fCurrScanline; 137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline = fCurrScanline->nextScanline(); 138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (y - 1 > prevLastY) { // insert empty run 141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fLastY = (SkRegion::RunType)(y - 1); 142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fXCount = 0; 143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline = fCurrScanline->nextScanline(); 144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // setup for the new curr line 146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrScanline->fLastY = (SkRegion::RunType)(y); 147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr = fCurrScanline->firstX(); 148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // check if we should extend the current run, or add a new one 151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (fCurrXPtr > fCurrScanline->firstX() && fCurrXPtr[-1] == x) { 152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr[-1] = (SkRegion::RunType)(x + width); 153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr[0] = (SkRegion::RunType)(x); 155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr[1] = (SkRegion::RunType)(x + width); 156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fCurrXPtr += 2; 157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(fCurrXPtr - fStorage < fStorageCount); 159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerint SkRgnBuilder::computeRunCount() const { 162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (fCurrScanline == NULL) { 163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 0; 164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkRegion::RunType* line = fStorage; 167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkRegion::RunType* stop = (const SkRegion::RunType*)fCurrScanline; 168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 2 + (int)(stop - line); 170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkRgnBuilder::copyToRect(SkIRect* r) const { 173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(fCurrScanline != NULL); 174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage == 4); 175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const Scanline* line = (const Scanline*)fStorage; 177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(line->fXCount == 2); 178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger r->set(line->firstX()[0], fTop, line->firstX()[1], line->fLastY + 1); 180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkRgnBuilder::copyToRgn(SkRegion::RunType runs[]) const { 183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(fCurrScanline != NULL); 184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage > 4); 185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const Scanline* line = (const Scanline*)fStorage; 187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const Scanline* stop = fCurrScanline; 188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *runs++ = fTop; 190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *runs++ = (SkRegion::RunType)(line->fLastY + 1); 192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = line->fXCount; 193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (count) { 194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger memcpy(runs, line->firstX(), count * sizeof(SkRegion::RunType)); 195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger runs += count; 196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *runs++ = SkRegion::kRunTypeSentinel; 198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger line = line->nextScanline(); 199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (line < stop); 200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(line == stop); 201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *runs = SkRegion::kRunTypeSentinel; 202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic int count_path_runtype_values(const SkPath& path, int* itop, int* ibot) { 205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static const uint8_t gPathVerbToInitialLastIndex[] = { 206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0, // kMove_Verb 207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1, // kLine_Verb 208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2, // kQuad_Verb 209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 3, // kCubic_Verb 210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0, // kClose_Verb 211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0 // kDone_Verb 212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger }; 213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static const uint8_t gPathVerbToMaxEdges[] = { 215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0, // kMove_Verb 216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1, // kLine_Verb 217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2, // kQuad_VerbB 218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 3, // kCubic_Verb 219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0, // kClose_Verb 220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 0 // kDone_Verb 221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger }; 222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPath::Iter iter(path, true); 224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPoint pts[4]; 225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPath::Verb verb; 226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int maxEdges = 0; 228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkScalar top = SkIntToScalar(SK_MaxS16); 229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkScalar bot = SkIntToScalar(SK_MinS16); 230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger maxEdges += gPathVerbToMaxEdges[verb]; 233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int lastIndex = gPathVerbToInitialLastIndex[verb]; 235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (lastIndex > 0) { 236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = 1; i <= lastIndex; i++) { 237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (top > pts[i].fY) { 238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger top = pts[i].fY; 239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (bot < pts[i].fY) { 240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bot = pts[i].fY; 241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (SkPath::kMove_Verb == verb) { 244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (top > pts[0].fY) { 245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger top = pts[0].fY; 246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (bot < pts[0].fY) { 247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger bot = pts[0].fY; 248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(top <= bot); 252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *itop = SkScalarRound(top); 254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *ibot = SkScalarRound(bot); 255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return maxEdges; 256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkRegion::setPath(const SkPath& path, const SkRegion& clip) { 259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDEBUGCODE(this->validate();) 260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (clip.isEmpty()) { 262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->setEmpty(); 263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (path.isEmpty()) { 266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (path.isInverseFillType()) { 267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->set(clip); 268f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->setEmpty(); 270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // compute worst-case rgn-size for the path 274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int pathTop, pathBot; 275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int pathTransitions = count_path_runtype_values(path, &pathTop, &pathBot); 276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int clipTop, clipBot; 277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int clipTransitions; 278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger clipTransitions = clip.count_runtype_values(&clipTop, &clipBot); 280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int top = SkMax32(pathTop, clipTop); 282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int bot = SkMin32(pathBot, clipBot); 283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (top >= bot) 285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->setEmpty(); 286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRgnBuilder builder; 288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (!builder.init(bot - top, SkMax32(pathTransitions, clipTransitions))) { 290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // can't allocate working space, so return false 291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->setEmpty(); 292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkScan::FillPath(path, clip, &builder); 295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger builder.done(); 296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = builder.computeRunCount(); 298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (count == 0) { 299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->setEmpty(); 300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (count == kRectRegionRuns) { 301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger builder.copyToRect(&fBounds); 302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger this->setRect(fBounds); 303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion tmp; 305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger tmp.fRunHead = RunHead::Alloc(count); 307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger builder.copyToRgn(tmp.fRunHead->writable_runs()); 308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger ComputeRunBounds(tmp.fRunHead->readonly_runs(), count, &tmp.fBounds); 309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger this->swap(tmp); 310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDEBUGCODE(this->validate();) 312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 314f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 315f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////////////////////// 316f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////////////////////// 317f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 318f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstruct Edge { 319f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger enum { 320f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger kY0Link = 0x01, 321f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger kY1Link = 0x02, 322f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 323f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger kCompleteLink = (kY0Link | kY1Link) 324f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger }; 325f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 326f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType fX; 327f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::RunType fY0, fY1; 328f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger uint8_t fFlags; 329f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* fNext; 330f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 331f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger void set(int x, int y0, int y1) { 332f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(y0 != y1); 333f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 334f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fX = (SkRegion::RunType)(x); 335f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fY0 = (SkRegion::RunType)(y0); 336f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fY1 = (SkRegion::RunType)(y1); 337f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fFlags = 0; 338f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDEBUGCODE(fNext = NULL;) 339f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 340f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 341f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int top() const { 342f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkFastMin32(fY0, fY1); 343f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 344f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 345f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 346f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void find_link(Edge* base, Edge* stop) { 347f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(base < stop); 348f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 349f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (base->fFlags == Edge::kCompleteLink) { 350f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(base->fNext); 351f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return; 352f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 353f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 354f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(base + 1 < stop); 355f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 356f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int y0 = base->fY0; 357f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int y1 = base->fY1; 358f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 359f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* e = base; 360f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((base->fFlags & Edge::kY0Link) == 0) { 361f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (;;) { 362f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e += 1; 363f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((e->fFlags & Edge::kY1Link) == 0 && y0 == e->fY1) { 364f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(NULL == e->fNext); 365f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e->fNext = base; 366f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e->fFlags = SkToU8(e->fFlags | Edge::kY1Link); 367f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 368f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 369f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 370f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 371f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 372f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e = base; 373f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((base->fFlags & Edge::kY1Link) == 0) { 374f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (;;) { 375f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e += 1; 376f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((e->fFlags & Edge::kY0Link) == 0 && y1 == e->fY0) { 377f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(NULL == base->fNext); 378f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger base->fNext = e; 379f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger e->fFlags = SkToU8(e->fFlags | Edge::kY0Link); 380f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger break; 381f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 382f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 383f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 384f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 385f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger base->fFlags = Edge::kCompleteLink; 386f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 387f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 388f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic int extract_path(Edge* edge, Edge* stop, SkPath* path) { 389f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger while (0 == edge->fFlags) { 390f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger edge++; // skip over "used" edges 391f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 392f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 393f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(edge < stop); 394f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 395f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* base = edge; 396f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* prev = edge; 397f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger edge = edge->fNext; 398f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(edge != base); 399f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 400f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = 1; 401f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->moveTo(SkIntToScalar(prev->fX), SkIntToScalar(prev->fY0)); 402f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger prev->fFlags = 0; 403f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 404f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (prev->fX != edge->fX || prev->fY1 != edge->fY0) { // skip collinear 405f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->lineTo(SkIntToScalar(prev->fX), SkIntToScalar(prev->fY1)); // V 406f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->lineTo(SkIntToScalar(edge->fX), SkIntToScalar(edge->fY0)); // H 407f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 408f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger prev = edge; 409f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger edge = edge->fNext; 410f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger count += 1; 411f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger prev->fFlags = 0; 412f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (edge != base); 413f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->lineTo(SkIntToScalar(prev->fX), SkIntToScalar(prev->fY1)); // V 414f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->close(); 415f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return count; 416f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 417f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 418f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTSearch.h" 419f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 420f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic int EdgeProc(const Edge* a, const Edge* b) { 421f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return (a->fX == b->fX) ? a->top() - b->top() : a->fX - b->fX; 422f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 423f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 424f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkRegion::getBoundaryPath(SkPath* path) const { 425f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // path could safely be NULL if we're empty, but the caller shouldn't 426f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // *know* that 427f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(path); 428f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 429f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (this->isEmpty()) { 430f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 431f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 432f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 433f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkIRect& bounds = this->getBounds(); 434f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 435f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (this->isRect()) { 436f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRect r; 437f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger r.set(bounds); // this converts the ints to scalars 438f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->addRect(r); 439f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 440f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 441f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 442f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkRegion::Iterator iter(*this); 443f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkTDArray<Edge> edges; 444f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 445f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (const SkIRect& r = iter.rect(); !iter.done(); iter.next()) { 446f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* edge = edges.append(2); 447f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger edge[0].set(r.fLeft, r.fBottom, r.fTop); 448f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger edge[1].set(r.fRight, r.fTop, r.fBottom); 449f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 450f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkQSort(edges.begin(), edges.count(), sizeof(Edge), 451f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger (SkQSortCompareProc)EdgeProc); 452f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 453f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int count = edges.count(); 454f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* start = edges.begin(); 455f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* stop = start + count; 456f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Edge* e; 457f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 458f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (e = start; e != stop; e++) { 459f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger find_link(e, stop); 460f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 461f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 462f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_DEBUG 463f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (e = start; e != stop; e++) { 464f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(e->fNext != NULL); 465f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(e->fFlags == Edge::kCompleteLink); 466f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 467f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 468f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 469f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger path->incReserve(count << 1); 470f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 471f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(count > 1); 472f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger count -= extract_path(start, stop, path); 473f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (count > 0); 474f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 475f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 476f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 477f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 478