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