[SkSVGDevice] Initial clipping support

Implement SVG clips based on clip stack flattening -
which is now exposed in SkClipStack::asPath() and shared
with SkCanvas's simplify-clip code.

R=reed@google.com,mtklein@google.com

Review URL: https://codereview.chromium.org/876923003
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 515596a..2d8c94f 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -8,6 +8,7 @@
 #include "SkCanvas.h"
 #include "SkClipStack.h"
 #include "SkPath.h"
+#include "SkPathOps.h"
 #include "SkThread.h"
 
 #include <new>
@@ -665,6 +666,35 @@
     return true;
 }
 
+bool SkClipStack::asPath(SkPath *path) const {
+    bool isAA = false;
+
+    path->reset();
+    path->setFillType(SkPath::kInverseEvenOdd_FillType);
+
+    SkClipStack::Iter iter(*this, SkClipStack::Iter::kBottom_IterStart);
+    while (const SkClipStack::Element* element = iter.next()) {
+        SkPath operand;
+        if (element->getType() != SkClipStack::Element::kEmpty_Type) {
+            element->asPath(&operand);
+        }
+
+        SkRegion::Op elementOp = element->getOp();
+        if (elementOp == SkRegion::kReplace_Op) {
+            *path = operand;
+        } else {
+            Op(*path, operand, (SkPathOp)elementOp, path);
+        }
+
+        // if the prev and curr clips disagree about aa -vs- not, favor the aa request.
+        // perhaps we need an API change to avoid this sort of mixed-signals about
+        // clipping.
+        isAA = (isAA || element->isAA());
+    }
+
+    return isAA;
+}
+
 void SkClipStack::pushElement(const Element& element) {
     // Use reverse iterator instead of back because Rect path may need previous
     SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart);