fix pictures to not skip-over clip ops that might expand the clip



git-svn-id: http://skia.googlecode.com/svn/trunk@2187 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5d35f74..d78c13a 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -128,14 +128,47 @@
     this->INHERITED::setMatrix(matrix);
 }
 
+static bool regionOpExpands(SkRegion::Op op) {
+    switch (op) {
+        case SkRegion::kUnion_Op:
+        case SkRegion::kXOR_Op:
+        case SkRegion::kReverseDifference_Op:
+        case SkRegion::kReplace_Op:
+            return true;
+        case SkRegion::kIntersect_Op:
+        case SkRegion::kDifference_Op:
+            return false;
+        default:
+            SkASSERT(!"unknown region op");
+            return false;
+    }
+}
+
+void SkPictureRecord::recordOffsetForRestore(SkRegion::Op op) {
+    if (regionOpExpands(op)) {
+        // Run back through any previous clip ops, and mark their offset to
+        // be 0, disabling their ability to trigger a jump-to-restore, otherwise
+        // they could hide this clips ability to expand the clip (i.e. go from
+        // empty to non-empty).
+        uint32_t offset = fRestoreOffsetStack.top();
+        while (offset) {
+            uint32_t* peek = fWriter.peek32(offset);
+            offset = *peek;
+            *peek = 0;
+        }
+    }
+    
+    size_t offset = fWriter.size();
+    addInt(fRestoreOffsetStack.top());
+    fRestoreOffsetStack.top() = offset;
+}
+
 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op) {
     addDraw(CLIP_RECT);
     addRect(rect);
     addInt(op);
 
-    size_t offset = fWriter.size();
-    addInt(fRestoreOffsetStack.top());
-    fRestoreOffsetStack.top() = offset;
+    this->recordOffsetForRestore(op);
 
     validate();
     return this->INHERITED::clipRect(rect, op);
@@ -146,9 +179,7 @@
     addPath(path);
     addInt(op);
 
-    size_t offset = fWriter.size();
-    addInt(fRestoreOffsetStack.top());
-    fRestoreOffsetStack.top() = offset;
+    this->recordOffsetForRestore(op);
 
     validate();
 
@@ -164,9 +195,7 @@
     addRegion(region);
     addInt(op);
 
-    size_t offset = fWriter.size();
-    addInt(fRestoreOffsetStack.top());
-    fRestoreOffsetStack.top() = offset;
+    this->recordOffsetForRestore(op);
 
     validate();
     return this->INHERITED::clipRegion(region, op);