add SkDrawPictureCallback optional parameter to drawPicture(), which can abort the...
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 20 May 2013 17:02:41 +0000 (17:02 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 20 May 2013 17:02:41 +0000 (17:02 +0000)
R=bsalomon@google.com

Review URL: https://codereview.chromium.org/14598023

git-svn-id: http://skia.googlecode.com/svn/trunk@9197 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkPicture.h
src/core/SkPicture.cpp
src/core/SkPicturePlayback.cpp
src/core/SkPicturePlayback.h

index b2c2b62edec4ee3684dc4ef4ef3129a1e29f2ad8..83aee4b2be4aea4e3d19fe1165bbe89fe664cd47 100644 (file)
@@ -15,6 +15,7 @@
 
 class SkBBoxHierarchy;
 class SkCanvas;
+class SkDrawPictureCallback;
 class SkPicturePlayback;
 class SkPictureRecord;
 class SkStream;
@@ -150,9 +151,9 @@ public:
 
     /** Replays the drawing commands on the specified canvas. This internally
         calls endRecording() if that has not already been called.
-        @param surface the canvas receiving the drawing commands.
+        @param canvas the canvas receiving the drawing commands.
     */
-    void draw(SkCanvas* surface);
+    void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL);
 
     /** Return the width of the picture's recording canvas. This
         value reflects what was passed to setSize(), and does not necessarily
@@ -246,5 +247,22 @@ private:
     SkCanvas*   fCanvas;
 };
 
+/**
+ *  Subclasses of this can be passed to canvas.drawPicture. During the drawing
+ *  of the picture, this callback will periodically be invoked. If its
+ *  abortDrawing() returns true, then picture playback will be interrupted.
+ *
+ *  The resulting drawing is undefined, as there is no guarantee how often the
+ *  callback will be invoked. If the abort happens inside some level of nested
+ *  calls to save(), restore will automatically be called to return the state
+ *  to the same level it was before the drawPicture call was made.
+ */
+class SkDrawPictureCallback {
+public:
+    SkDrawPictureCallback() {}
+    virtual ~SkDrawPictureCallback() {}
+    
+    virtual bool abortDrawing() = 0;
+};
 
 #endif
index 1ff58656512681ed5ac056d1399f9558c33f0c91..ab2faea6b6b4eb38b6e0a9a9ac4ae5338cb46c8b 100644 (file)
@@ -253,10 +253,10 @@ void SkPicture::endRecording() {
     SkASSERT(NULL == fRecord);
 }
 
-void SkPicture::draw(SkCanvas* surface) {
+void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
     this->endRecording();
     if (fPlayback) {
-        fPlayback->draw(*surface);
+        fPlayback->draw(*surface, callback);
     }
 }
 
index d54a6c5f3b3384d99499e6966dd139b4fce280e5..e1c9a3a65f98c78df4caeae806a01ca716ee782d 100644 (file)
@@ -656,7 +656,7 @@ static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) {
     return (DrawType) op;
 }
 
-void SkPicturePlayback::draw(SkCanvas& canvas) {
+void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
 #ifdef ENABLE_TIME_DRAW
     SkAutoTime  at("SkPicture::draw", 50);
 #endif
@@ -706,12 +706,17 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
 
     // Record this, so we can concat w/ it if we encounter a setMatrix()
     SkMatrix initialMatrix = canvas.getTotalMatrix();
+    int originalSaveCount = canvas.getSaveCount();
 
 #ifdef SK_BUILD_FOR_ANDROID
     fAbortCurrentPlayback = false;
 #endif
 
     while (!reader.eof()) {
+        if (callback && callback->abortDrawing()) {
+            canvas.restoreToCount(originalSaveCount);
+            return;
+        }
 #ifdef SK_BUILD_FOR_ANDROID
         if (fAbortCurrentPlayback) {
             return;
index b0af6942bcb1eb49fa00c398b024a92e07019df6..801900124af5227c26b36d88bc589789c055139f 100644 (file)
@@ -66,7 +66,7 @@ public:
 
     virtual ~SkPicturePlayback();
 
-    void draw(SkCanvas& canvas);
+    void draw(SkCanvas& canvas, SkDrawPictureCallback*);
 
     void serialize(SkWStream*, SkPicture::EncodeBitmap) const;