| Index: src/core/SkDeviceLooper.cpp
|
| diff --git a/src/core/SkDeviceLooper.cpp b/src/core/SkDeviceLooper.cpp
|
| index 882c1f1703b462d55db2fba818ff27b31321b2ce..4cdc464a73110d25be2a7dc69c4d05beccbc7564 100644
|
| --- a/src/core/SkDeviceLooper.cpp
|
| +++ b/src/core/SkDeviceLooper.cpp
|
| @@ -19,10 +19,14 @@ SkDeviceLooper::SkDeviceLooper(const SkBitmap& base,
|
| fCurrBitmap = NULL;
|
| fCurrRC = NULL;
|
|
|
| - SkIRect bitmapBounds = SkIRect::MakeWH(base.width(), base.height());
|
| - if (!fClippedBounds.intersect(bounds, bitmapBounds)) {
|
| + if (!rc.isEmpty()) {
|
| + // clip must be contained by the bitmap
|
| + SkASSERT(SkIRect::MakeWH(base.width(), base.height()).contains(rc.getBounds()));
|
| + }
|
| +
|
| + if (rc.isEmpty() || !fClippedBounds.intersect(bounds, rc.getBounds())) {
|
| fState = kDone_State;
|
| - } else if (this->fitsInDelta(bounds)) {
|
| + } else if (this->fitsInDelta(fClippedBounds)) {
|
| fState = kSimple_State;
|
| } else {
|
| // back up by 1 DX, so that next() will put us in a correct starting
|
| @@ -62,17 +66,35 @@ bool SkDeviceLooper::computeCurrBitmapAndClip() {
|
| SkIRect r = SkIRect::MakeXYWH(fCurrOffset.x(), fCurrOffset.y(),
|
| fDelta, fDelta);
|
| if (!fBaseBitmap.extractSubset(&fSubsetBitmap, r)) {
|
| - fState = kDone_State;
|
| - return false;
|
| + fSubsetRC.setEmpty();
|
| + } else {
|
| + fSubsetBitmap.lockPixels();
|
| + fBaseRC.translate(-r.left(), -r.top(), &fSubsetRC);
|
| + (void)fSubsetRC.op(SkIRect::MakeWH(fDelta, fDelta),
|
| + SkRegion::kIntersect_Op);
|
| }
|
| - fSubsetBitmap.lockPixels();
|
| -
|
| - fBaseRC.translate(-r.left(), -r.top(), &fSubsetRC);
|
| - (void)fSubsetRC.op(SkIRect::MakeWH(fDelta, fDelta), SkRegion::kIntersect_Op);
|
|
|
| fCurrBitmap = &fSubsetBitmap;
|
| fCurrRC = &fSubsetRC;
|
| - return true;
|
| + return !fCurrRC->isEmpty();
|
| +}
|
| +
|
| +static bool next_tile(const SkIRect& boundary, int delta, SkIPoint* offset) {
|
| + // can we move to the right?
|
| + if (offset->x() + delta < boundary.right()) {
|
| + offset->fX += delta;
|
| + return true;
|
| + }
|
| +
|
| + // reset to the left, but move down a row
|
| + offset->fX = boundary.left();
|
| + if (offset->y() + delta < boundary.bottom()) {
|
| + offset->fY += delta;
|
| + return true;
|
| + }
|
| +
|
| + // offset is now outside of boundary, so we're done
|
| + return false;
|
| }
|
|
|
| bool SkDeviceLooper::next() {
|
| @@ -97,18 +119,13 @@ bool SkDeviceLooper::next() {
|
| // need to propogate fCurrOffset through clippedbounds
|
| // left to right, until we wrap around and move down
|
|
|
| - if (fCurrOffset.x() + fDelta < fClippedBounds.right()) {
|
| - fCurrOffset.fX += fDelta;
|
| - return this->computeCurrBitmapAndClip();
|
| - }
|
| - fCurrOffset.fX = fClippedBounds.left();
|
| - if (fCurrOffset.y() + fDelta < fClippedBounds.bottom()) {
|
| - fCurrOffset.fY += fDelta;
|
| - return this->computeCurrBitmapAndClip();
|
| + while (next_tile(fClippedBounds, fDelta, &fCurrOffset)) {
|
| + if (this->computeCurrBitmapAndClip()) {
|
| + return true;
|
| + }
|
| }
|
| break;
|
| }
|
| -
|
| fState = kDone_State;
|
| return false;
|
| }
|
|
|