1bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger/* 2bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger * Copyright 2013 Google Inc. 3bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger * 4bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger * found in the LICENSE file. 6bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger */ 7bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 8bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger#include "SkDeviceLooper.h" 9bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 10bd353162926d4e7adf5b4345552be4bf62f5397aDerek SollenbergerSkDeviceLooper::SkDeviceLooper(const SkBitmap& base, 11bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger const SkRasterClip& rc, 12bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger const SkIRect& bounds, bool aa) 13bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger: fBaseBitmap(base) 14bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger, fBaseRC(rc) 15bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger, fDelta(aa ? kAA_Delta : kBW_Delta) 16bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger{ 17bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // sentinels that next() has not yet been called, and so our mapper functions 18bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // should not be called either. 19bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrBitmap = NULL; 20bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrRC = NULL; 21bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 22bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkIRect bitmapBounds = SkIRect::MakeWH(base.width(), base.height()); 23bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (!fClippedBounds.intersect(bounds, bitmapBounds)) { 24bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fState = kDone_State; 25bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } else if (this->fitsInDelta(bounds)) { 26bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fState = kSimple_State; 27bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } else { 28bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // back up by 1 DX, so that next() will put us in a correct starting 29bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // position. 30bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrOffset.set(fClippedBounds.left() - fDelta, 31bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fClippedBounds.top()); 32bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fState = kComplex_State; 33bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 34bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 35bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 36bd353162926d4e7adf5b4345552be4bf62f5397aDerek SollenbergerSkDeviceLooper::~SkDeviceLooper() { 37bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 38bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 39bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenbergervoid SkDeviceLooper::mapRect(SkRect* dst, const SkRect& src) const { 40bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(kDone_State != fState); 41bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(fCurrBitmap); 42bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(fCurrRC); 43bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 44bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger *dst = src; 45bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger dst->offset(SkIntToScalar(-fCurrOffset.fX), 46bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkIntToScalar(-fCurrOffset.fY)); 47bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 48bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 49bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenbergervoid SkDeviceLooper::mapMatrix(SkMatrix* dst, const SkMatrix& src) const { 50bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(kDone_State != fState); 51bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(fCurrBitmap); 52bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(fCurrRC); 53bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 54bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger *dst = src; 55bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger dst->postTranslate(SkIntToScalar(-fCurrOffset.fX), 56bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkIntToScalar(-fCurrOffset.fY)); 57bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 58bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 59bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenbergerbool SkDeviceLooper::computeCurrBitmapAndClip() { 60bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkASSERT(kComplex_State == fState); 61bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 62bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkIRect r = SkIRect::MakeXYWH(fCurrOffset.x(), fCurrOffset.y(), 63bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fDelta, fDelta); 64bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (!fBaseBitmap.extractSubset(&fSubsetBitmap, r)) { 65bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fState = kDone_State; 66bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return false; 67bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 68bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fSubsetBitmap.lockPixels(); 69bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 70bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fBaseRC.translate(-r.left(), -r.top(), &fSubsetRC); 71bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger (void)fSubsetRC.op(SkIRect::MakeWH(fDelta, fDelta), SkRegion::kIntersect_Op); 72bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 73bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrBitmap = &fSubsetBitmap; 74bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrRC = &fSubsetRC; 75bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return true; 76bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 77bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 78bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenbergerbool SkDeviceLooper::next() { 79bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger switch (fState) { 80bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger case kDone_State: 81bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // in theory, we should not get called here, since we must have 82bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // previously returned false, but we check anyway. 83bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger break; 84bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 85bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger case kSimple_State: 86bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // first time for simple 87bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (NULL == fCurrBitmap) { 88bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrBitmap = &fBaseBitmap; 89bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrRC = &fBaseRC; 90bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrOffset.set(0, 0); 91bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return true; 92bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 93bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // 2nd time for simple, we are done 94bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger break; 95bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 96bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger case kComplex_State: 97bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // need to propogate fCurrOffset through clippedbounds 98bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // left to right, until we wrap around and move down 99bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 100bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (fCurrOffset.x() + fDelta < fClippedBounds.right()) { 101bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrOffset.fX += fDelta; 102bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return this->computeCurrBitmapAndClip(); 103bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 104bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrOffset.fX = fClippedBounds.left(); 105bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (fCurrOffset.y() + fDelta < fClippedBounds.bottom()) { 106bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fCurrOffset.fY += fDelta; 107bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return this->computeCurrBitmapAndClip(); 108bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 109bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger break; 110bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 111bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 112bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger fState = kDone_State; 113bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return false; 114bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 115