add isRect() check to AAClip, to detect if a soft-clip is really just an irect

taken from (https://codereview.chromium.org/445233006/)

fix: don't assume that the first yoffset is 0, since we may have performed a translate and not
re-alloced our data.

This reverts commit 0aeea6d344f12e35e29a79f4bbc48af88f913204.

TBR=

Author: reed@google.com

Review URL: https://codereview.chromium.org/443353004
diff --git a/src/core/SkAAClip.cpp b/src/core/SkAAClip.cpp
index 14152f8..5d21a47 100644
--- a/src/core/SkAAClip.cpp
+++ b/src/core/SkAAClip.cpp
@@ -684,6 +684,34 @@
 #endif
 }
 
+bool SkAAClip::isRect() const {
+    if (this->isEmpty()) {
+        return false;
+    }
+
+    const RunHead* head = fRunHead;
+    if (head->fRowCount != 1) {
+        return false;
+    }
+    const YOffset* yoff = head->yoffsets();
+    if (yoff->fY != fBounds.fBottom - 1) {
+        return false;
+    }
+
+    const uint8_t* row = head->data() + yoff->fOffset;
+    int width = fBounds.width();
+    do {
+        if (row[1] != 0xFF) {
+            return false;
+        }
+        int n = row[0];
+        SkASSERT(n <= width);
+        width -= n;
+        row += 2;
+    } while (width > 0);
+    return true;
+}
+
 bool SkAAClip::setRect(const SkRect& r, bool doAA) {
     if (r.isEmpty()) {
         return this->setEmpty();
diff --git a/src/core/SkAAClip.h b/src/core/SkAAClip.h
index f2cde62..c36a3e9 100644
--- a/src/core/SkAAClip.h
+++ b/src/core/SkAAClip.h
@@ -29,6 +29,10 @@
     bool isEmpty() const { return NULL == fRunHead; }
     const SkIRect& getBounds() const { return fBounds; }
 
+    // Returns true iff the clip is not empty, and is just a hard-edged rect (no partial alpha).
+    // If true, getBounds() can be used in place of this clip.
+    bool isRect() const;
+
     bool setEmpty();
     bool setRect(const SkIRect&);
     bool setRect(const SkRect&, bool doAA = true);
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp
index 664211f..d1615a3 100644
--- a/src/core/SkRasterClip.cpp
+++ b/src/core/SkRasterClip.cpp
@@ -222,7 +222,10 @@
     SkASSERT(fIsBW);
     fAA.setRegion(fBW);
     fIsBW = false;
-    (void)this->updateCacheAndReturnNonEmpty();
+    
+    // since we are being explicitly asked to convert-to-aa, we pass false so we don't "optimize"
+    // ourselves back to BW.
+    (void)this->updateCacheAndReturnNonEmpty(false);
 }
 
 #ifdef SK_DEBUG
diff --git a/src/core/SkRasterClip.h b/src/core/SkRasterClip.h
index 0c27233..29a925f 100644
--- a/src/core/SkRasterClip.h
+++ b/src/core/SkRasterClip.h
@@ -89,11 +89,19 @@
     }
 
     bool computeIsRect() const {
-        return fIsBW ? fBW.isRect() : false;
+        return fIsBW ? fBW.isRect() : fAA.isRect();
     }
 
-    bool updateCacheAndReturnNonEmpty() {
+    bool updateCacheAndReturnNonEmpty(bool detectAARect = true) {
         fIsEmpty = this->computeIsEmpty();
+
+        // detect that our computed AA is really just a (hard-edged) rect
+        if (detectAARect && !fIsEmpty && !fIsBW && fAA.isRect()) {
+            fBW.setRect(fAA.getBounds());
+            fAA.setEmpty(); // don't need this guy anymore
+            fIsBW = true;
+        }
+
         fIsRect = this->computeIsRect();
         return !fIsEmpty;
     }