10a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/* 20a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Copyright 2013 Google Inc. 30a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 40a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 50a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * found in the LICENSE file. 60a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 70a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 80a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkDeviceLooper.h" 90a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 100a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerSkDeviceLooper::SkDeviceLooper(const SkBitmap& base, 110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkRasterClip& rc, 120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkIRect& bounds, bool aa) 130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger: fBaseBitmap(base) 140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger, fBaseRC(rc) 150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger, fDelta(aa ? kAA_Delta : kBW_Delta) 160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger{ 170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // sentinels that next() has not yet been called, and so our mapper functions 180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // should not be called either. 190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrBitmap = NULL; 200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrRC = NULL; 210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!rc.isEmpty()) { 230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // clip must be contained by the bitmap 240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(SkIRect::MakeWH(base.width(), base.height()).contains(rc.getBounds())); 250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (rc.isEmpty() || !fClippedBounds.intersect(bounds, rc.getBounds())) { 280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fState = kDone_State; 290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } else if (this->fitsInDelta(fClippedBounds)) { 300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fState = kSimple_State; 310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } else { 320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // back up by 1 DX, so that next() will put us in a correct starting 330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // position. 340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrOffset.set(fClippedBounds.left() - fDelta, 350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fClippedBounds.top()); 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fState = kComplex_State; 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 400a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerSkDeviceLooper::~SkDeviceLooper() { 410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid SkDeviceLooper::mapRect(SkRect* dst, const SkRect& src) const { 440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(kDone_State != fState); 450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrBitmap); 460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrRC); 470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger *dst = src; 490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst->offset(SkIntToScalar(-fCurrOffset.fX), 500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkIntToScalar(-fCurrOffset.fY)); 510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid SkDeviceLooper::mapMatrix(SkMatrix* dst, const SkMatrix& src) const { 540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(kDone_State != fState); 550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrBitmap); 560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrRC); 570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger *dst = src; 590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger dst->postTranslate(SkIntToScalar(-fCurrOffset.fX), 600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkIntToScalar(-fCurrOffset.fY)); 610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkDeviceLooper::computeCurrBitmapAndClip() { 640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(kComplex_State == fState); 650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkIRect r = SkIRect::MakeXYWH(fCurrOffset.x(), fCurrOffset.y(), 670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fDelta, fDelta); 680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (!fBaseBitmap.extractSubset(&fSubsetBitmap, r)) { 690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fSubsetRC.setEmpty(); 700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } else { 710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fSubsetBitmap.lockPixels(); 720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fBaseRC.translate(-r.left(), -r.top(), &fSubsetRC); 730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger (void)fSubsetRC.op(SkIRect::MakeWH(fDelta, fDelta), 740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkRegion::kIntersect_Op); 750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrBitmap = &fSubsetBitmap; 780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrRC = &fSubsetRC; 790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return !fCurrRC->isEmpty(); 800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool next_tile(const SkIRect& boundary, int delta, SkIPoint* offset) { 830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // can we move to the right? 840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (offset->x() + delta < boundary.right()) { 850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger offset->fX += delta; 860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // reset to the left, but move down a row 900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger offset->fX = boundary.left(); 910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (offset->y() + delta < boundary.bottom()) { 920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger offset->fY += delta; 930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // offset is now outside of boundary, so we're done 970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return false; 980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerbool SkDeviceLooper::next() { 1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger switch (fState) { 1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger case kDone_State: 1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // in theory, we should not get called here, since we must have 1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // previously returned false, but we check anyway. 1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger break; 1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger case kSimple_State: 1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // first time for simple 1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (NULL == fCurrBitmap) { 1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrBitmap = &fBaseBitmap; 1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrRC = &fBaseRC; 1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fCurrOffset.set(0, 0); 1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 1140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // 2nd time for simple, we are done 1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger break; 1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger case kComplex_State: 1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // need to propogate fCurrOffset through clippedbounds 1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // left to right, until we wrap around and move down 1210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger while (next_tile(fClippedBounds, fDelta, &fCurrOffset)) { 1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (this->computeCurrBitmapAndClip()) { 1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return true; 1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger break; 1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger fState = kDone_State; 1300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return false; 1310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 132