pdfviewer: All NulCanvas (does not draw operations), TrackDevice (trackes what pixels have been changed)

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

git-svn-id: http://skia.googlecode.com/svn/trunk@10236 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/PdfViewer/SkTracker.h b/experimental/PdfViewer/SkTracker.h
new file mode 100644
index 0000000..3b02964
--- /dev/null
+++ b/experimental/PdfViewer/SkTracker.h
@@ -0,0 +1,174 @@
+#ifndef EXPERIMENTAL_PDFVIEWER_SKTRACKER_H_
+#define EXPERIMENTAL_PDFVIEWER_SKTRACKER_H_
+
+#include "SkBitmap.h"
+#include "SkPoint.h"
+
+#define MAX_TRACKING_POINTS 100
+
+class SkTracker {
+public:
+    SkTracker() : fEnabled(false)
+                , fBreakOnAny(false)
+                , fCntExpectedTouched(0)
+                , fCntExpectedUntouched(0)
+                , fHits(0) {}
+
+    virtual ~SkTracker() {}
+
+    void clearPoints() {
+        fCntExpectedTouched = 0;
+        fCntExpectedUntouched = 0;
+    }
+
+    void enableTracking(bool b) {
+        fEnabled = b;
+    }
+
+    bool trackingEnabled() {
+        return fEnabled;
+    }
+
+    void any() {
+        fBreakOnAny = true;
+    }
+
+    void all() {
+        fBreakOnAny = false;
+    }
+
+    bool requireAllExpectedTouched() {
+        return !fBreakOnAny;
+    }
+
+    int cntExpectedTouched() {
+        return fCntExpectedTouched;
+    }
+
+    const SkIPoint* expectedTouched() {
+        return fExpectedTouched;
+    }
+
+    int cntExpectedUntouched() {
+        return fCntExpectedUntouched;
+    }
+
+    const SkIPoint* expectedUntouched() {
+        return fExpectedUntouched;
+    }
+
+    bool addExpectTouch(int x, int y) {
+        if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
+            return false;
+        }
+        if (found(x, y)) {
+            return false;
+        }
+        fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
+        fCntExpectedTouched++;
+        return true;
+    }
+
+    bool addExpectUntouch(int x, int y) {
+        if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
+            return false;
+        }
+        if (found(x, y)) {
+            return false;
+        }
+        fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
+        fCntExpectedUntouched++;
+        return true;
+    }
+
+    void newFrame() {
+        fHits = 0;
+    }
+
+    int hits() {
+        return fHits;
+    }
+
+    void before(const SkBitmap& bitmap) {
+        if (fCntExpectedTouched == 0) {
+            return;
+        }
+
+        for (int i = 0 ; i < fCntExpectedTouched; i++) {
+            fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
+        }
+        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
+            fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(), fExpectedUntouched[i].y());
+        }
+    }
+
+    // any/all of the expected touched has to be changed, and all expected untouched must be intact
+    void after(const SkBitmap& bitmap) {
+        if (fCntExpectedTouched == 0) {
+            return;
+        }
+
+        bool doBreak;
+        if (fBreakOnAny) {
+            doBreak = false;
+            for (int i = 0 ; i < fCntExpectedTouched; i++) {
+                doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
+            }
+        } else {
+            doBreak = true;
+            for (int i = 0 ; i < fCntExpectedTouched; i++) {
+                doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
+            }
+        }
+
+        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
+            doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(), fExpectedUntouched[i].y());
+        }
+
+        if (doBreak) {
+            fHits++;
+            if (fEnabled) {
+                breakExecution();
+            }
+        }
+    }
+
+private:
+    inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
+        return bitmap.getColor(x, y);
+    }
+
+    void breakExecution() {
+        printf("break;\n");
+    }
+
+    inline bool found(int x, int y) {
+        for (int i = 0 ; i < fCntExpectedTouched; i++) {
+            if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
+                return true;
+            }
+        }
+        for (int i = 0 ; i < fCntExpectedUntouched; i++) {
+            if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    bool fEnabled;
+    // break on any change on expected touched or all.
+    bool fBreakOnAny;
+    SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
+    SkColor fBeforeTouched[MAX_TRACKING_POINTS];
+    int fCntExpectedTouched;
+
+    SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
+    SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
+    int fCntExpectedUntouched;
+
+    int fHits;
+};
+
+#endif  // EXPERIMENTAL_PDFVIEWER_SKTRACKER_H_