SkRecordPartialDraw with less code duplication

BUG=skia:
R=robertphillips@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/527423002
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 0117ade..f7f0299 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -35,15 +35,29 @@
         }
     } else {
         // Draw all ops.
-        for (SkRecords::Draw draw(canvas); draw.index() < record.count(); draw.next()) {
+        SkRecords::Draw draw(canvas);
+        for (unsigned i = 0; i < record.count(); i++) {
             if (NULL != callback && callback->abortDrawing()) {
                 return;
             }
-            record.visit<void>(draw.index(), draw);
+            record.visit<void>(i, draw);
         }
     }
 }
 
+void SkRecordPartialDraw(const SkRecord& record,
+                         SkCanvas* canvas,
+                         const SkRect& clearRect,
+                         unsigned start, unsigned stop) {
+    SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
+
+    stop = SkTMin(stop, record.count());
+    SkRecords::PartialDraw draw(canvas, clearRect);
+    for (unsigned i = start; i < stop; i++) {
+        record.visit<void>(i, draw);
+    }
+}
+
 namespace SkRecords {
 
 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads.
diff --git a/src/core/SkRecordDraw.h b/src/core/SkRecordDraw.h
index 8da7fb5..033b76d 100644
--- a/src/core/SkRecordDraw.h
+++ b/src/core/SkRecordDraw.h
@@ -19,16 +19,16 @@
 // Draw an SkRecord into an SkCanvas.  A convenience wrapper around SkRecords::Draw.
 void SkRecordDraw(const SkRecord&, SkCanvas*, const SkBBoxHierarchy*, SkDrawPictureCallback*);
 
+// Draw a portion of an SkRecord into an SkCanvas while replacing clears with drawRects.
+void SkRecordPartialDraw(const SkRecord&, SkCanvas*, const SkRect&, unsigned start, unsigned stop);
+
 namespace SkRecords {
 
 // This is an SkRecord visitor that will draw that SkRecord to an SkCanvas.
 class Draw : SkNoncopyable {
 public:
     explicit Draw(SkCanvas* canvas)
-        : fInitialCTM(canvas->getTotalMatrix()), fCanvas(canvas), fIndex(0) {}
-
-    unsigned index() const { return fIndex; }
-    void next() { ++fIndex; }
+        : fInitialCTM(canvas->getTotalMatrix()), fCanvas(canvas) {}
 
     template <typename T> void operator()(const T& r) {
         this->draw(r);
@@ -40,7 +40,28 @@
 
     const SkMatrix fInitialCTM;
     SkCanvas* fCanvas;
-    unsigned fIndex;
+};
+
+// Used by SkRecordPartialDraw.
+class PartialDraw : public Draw {
+public:
+    PartialDraw(SkCanvas* canvas, const SkRect& clearRect)
+        : INHERITED(canvas), fClearRect(clearRect) {}
+
+    // Same as Draw for all ops except Clear.
+    template <typename T> void operator()(const T& r) {
+        this->INHERITED::operator()(r);
+    }
+    void operator()(const Clear& c) {
+        SkPaint p;
+        p.setColor(c.color);
+        DrawRect drawRect(p, fClearRect);
+        this->INHERITED::operator()(drawRect);
+    }
+
+private:
+    const SkRect fClearRect;
+    typedef Draw INHERITED;
 };
 
 }  // namespace SkRecords