Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(821)

Unified Diff: src/core/SkDeviceLooper.cpp

Issue 23618005: fix state machine so we know simple only loops once, but we can call maprect in debug mode (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkDeviceLooper.h ('k') | src/core/SkDraw.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkDeviceLooper.cpp
diff --git a/src/core/SkDeviceLooper.cpp b/src/core/SkDeviceLooper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4122fd7aaf30335fcb188b2c8a6d89e129b37ee1
--- /dev/null
+++ b/src/core/SkDeviceLooper.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkDeviceLooper.h"
+
+SkDeviceLooper::SkDeviceLooper(const SkBitmap& base,
+ const SkRasterClip& rc,
+ const SkIRect& bounds, bool aa)
+: fBaseBitmap(base)
+, fBaseRC(rc)
+, fDelta(aa ? kAA_Delta : kBW_Delta)
+{
+ // sentinels that next() has not yet been called, and so our mapper functions
+ // should not be called either.
+ fCurrBitmap = NULL;
+ fCurrRC = NULL;
+
+ SkIRect bitmapBounds = SkIRect::MakeWH(base.width(), base.height());
+ if (!fClippedBounds.intersect(bounds, bitmapBounds)) {
+ fState = kDone_State;
+ } else if (this->fitsInDelta(bounds)) {
+ fState = kSimple_State;
+ } else {
+ // back up by 1 DX, so that next() will put us in a correct starting
+ // position.
+ fCurrOffset.set(fClippedBounds.left() - fDelta,
+ fClippedBounds.top());
+ fState = kComplex_State;
+ }
+}
+
+SkDeviceLooper::~SkDeviceLooper() {
+}
+
+void SkDeviceLooper::mapRect(SkRect* dst, const SkRect& src) const {
+ SkASSERT(kDone_State != fState);
+ SkASSERT(fCurrBitmap);
+ SkASSERT(fCurrRC);
+
+ *dst = src;
+ dst->offset(SkIntToScalar(-fCurrOffset.fX),
+ SkIntToScalar(-fCurrOffset.fY));
+}
+
+void SkDeviceLooper::mapMatrix(SkMatrix* dst, const SkMatrix& src) const {
+ SkASSERT(kDone_State != fState);
+ SkASSERT(fCurrBitmap);
+ SkASSERT(fCurrRC);
+
+ *dst = src;
+ dst->postTranslate(SkIntToScalar(-fCurrOffset.fX),
+ SkIntToScalar(-fCurrOffset.fY));
+}
+
+bool SkDeviceLooper::computeCurrBitmapAndClip() {
+ SkASSERT(kComplex_State == fState);
+
+ SkIRect r = SkIRect::MakeXYWH(fCurrOffset.x(), fCurrOffset.y(),
+ fDelta, fDelta);
+ if (!fBaseBitmap.extractSubset(&fSubsetBitmap, r)) {
+ fState = kDone_State;
+ return false;
+ }
+ 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;
+}
+
+bool SkDeviceLooper::next() {
+ switch (fState) {
+ case kDone_State:
+ // in theory, we should not get called here, since we must have
+ // previously returned false, but we check anyway.
+ break;
+
+ case kSimple_State:
+ // first time for simple
+ if (NULL == fCurrBitmap) {
+ fCurrBitmap = &fBaseBitmap;
+ fCurrRC = &fBaseRC;
+ fCurrOffset.set(0, 0);
+ return true;
+ }
+ // 2nd time for simple, we are done
+ break;
+
+ case kComplex_State:
+ // 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();
+ }
+ break;
+ }
+
+ fState = kDone_State;
+ return false;
+}
« no previous file with comments | « src/core/SkDeviceLooper.h ('k') | src/core/SkDraw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698