Home | History | Annotate | Download | only in PdfViewer
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkTracker_DEFINED
      9 #define SkTracker_DEFINED
     10 
     11 #include <stdio.h>
     12 
     13 #include "SkBitmap.h"
     14 #include "SkPoint.h"
     15 
     16 // TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tree!
     17 // TODO(edisonn): Minimal PDF to draw some points - remove everything that it is not needed,
     18 //                save pdf uncompressed
     19 
     20 #define MAX_TRACKING_POINTS 100
     21 
     22 /** \class SkTracker
     23  *
     24  *   A Tracker can be attached to a SkTrackDevice and it will store the track pixels.
     25  *   It can be used with SampleApp to investigate bugs (CL not checked in yet).
     26  *
     27  *   The Tracker tracks 2 sets of points
     28  *     A) one which is expected to issue breackpoints if the pixels are changes
     29  *     B) one which if changes will disable the breackpoint
     30  *   For point in A) there are two modes:
     31  *     A.1) a breackpoint require that any of the points is changed
     32  *     A.2) a breackpoint require that all of the points is changed
     33  *   Points in B are allways in "any mode" - chaning the value of any pixel, will disable
     34  *     the breackpoint
     35  *
     36  *   Point in A) are used to show what are the areas of interest, while poit in B are used to
     37  *     disable breackpoints which would be issued in background change.
     38  *
     39  */
     40 class SkTracker {
     41 public:
     42     SkTracker() : fEnabled(false)
     43                 , fBreakOnAny(false)
     44                 , fCntExpectedTouched(0)
     45                 , fCntExpectedUntouched(0)
     46                 , fHits(0) {}
     47 
     48     virtual ~SkTracker() {}
     49 
     50     // Clears all the points, but preserves the break mode.
     51     void clearPoints() {
     52         fCntExpectedTouched = 0;
     53         fCntExpectedUntouched = 0;
     54     }
     55 
     56     // Enable the breackpoints.
     57     void enableTracking(bool b) {
     58         fEnabled = b;
     59     }
     60 
     61     // Returns true if breackpoints are enabled.
     62     bool trackingEnabled() {
     63         return fEnabled;
     64     }
     65 
     66     // Puts the tracker in Any mode.
     67     void any() {
     68         fBreakOnAny = true;
     69     }
     70 
     71     // Puts the tracker in Any mode.
     72     void all() {
     73         fBreakOnAny = false;
     74     }
     75 
     76     // returns true in in All mode. False for Any mode.
     77     bool requireAllExpectedTouched() {
     78         return !fBreakOnAny;
     79     }
     80 
     81     // Returns the numbers of points in which if touched, would trigger a breackpoint.
     82     int cntExpectedTouched() {
     83         return fCntExpectedTouched;
     84     }
     85 
     86     // Returns the points which if touched, would trigger a breackpoint.
     87     // the Tracker owns the array
     88     const SkIPoint* expectedTouched() {
     89         return fExpectedTouched;
     90     }
     91 
     92     // Returns the numbers of points in which if touched, would disable a breackpoint.
     93     int cntExpectedUntouched() {
     94         return fCntExpectedUntouched;
     95     }
     96 
     97     // Returns the points which if touched, would disable a breackpoint.
     98     // the Tracker owns the array
     99     const SkIPoint* expectedUntouched() {
    100         return fExpectedUntouched;
    101     }
    102 
    103     // Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
    104     bool addExpectTouch(int x, int y) {
    105         if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
    106             return false;
    107         }
    108         if (found(x, y)) {
    109             return false;
    110         }
    111         fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
    112         fCntExpectedTouched++;
    113         return true;
    114     }
    115 
    116     // Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
    117     bool addExpectUntouch(int x, int y) {
    118         if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
    119             return false;
    120         }
    121         if (found(x, y)) {
    122             return false;
    123         }
    124         fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
    125         fCntExpectedUntouched++;
    126         return true;
    127     }
    128 
    129     // Starts a new rendering session - reset the number of hits.
    130     void newFrame() {
    131         fHits = 0;
    132     }
    133 
    134     // returns the number of breackpoints issues in this rendering session.
    135     int hits() {
    136         return fHits;
    137     }
    138 
    139     // Called before drawFoo to store the state of the pixels
    140     void before(const SkBitmap& bitmap) {
    141         if (fCntExpectedTouched == 0) {
    142             return;
    143         }
    144 
    145         for (int i = 0 ; i < fCntExpectedTouched; i++) {
    146             fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
    147         }
    148         for (int i = 0 ; i < fCntExpectedUntouched; i++) {
    149             fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
    150                                             fExpectedUntouched[i].y());
    151         }
    152     }
    153 
    154     // Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
    155     // any/all of the expected touched has to be changed, and all expected untouched must be intact
    156     void after(const SkBitmap& bitmap) {
    157         if (fCntExpectedTouched == 0) {
    158             return;
    159         }
    160 
    161         bool doBreak;
    162         if (fBreakOnAny) {
    163             doBreak = false;
    164             for (int i = 0 ; i < fCntExpectedTouched; i++) {
    165                 doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
    166                                                                     fExpectedTouched[i].y());
    167             }
    168         } else {
    169             doBreak = true;
    170             for (int i = 0 ; i < fCntExpectedTouched; i++) {
    171                 doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
    172                                                                     fExpectedTouched[i].y());
    173             }
    174         }
    175 
    176         for (int i = 0 ; i < fCntExpectedUntouched; i++) {
    177             doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
    178                                                                   fExpectedUntouched[i].y());
    179         }
    180 
    181         if (doBreak) {
    182             fHits++;
    183             if (fEnabled) {
    184                 breakExecution();
    185             }
    186         }
    187     }
    188 
    189 private:
    190     inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
    191         return bitmap.getColor(x, y);
    192     }
    193 
    194     void breakExecution() {
    195         printf("break;\n");
    196     }
    197 
    198     inline bool found(int x, int y) {
    199         for (int i = 0 ; i < fCntExpectedTouched; i++) {
    200             if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
    201                 return true;
    202             }
    203         }
    204         for (int i = 0 ; i < fCntExpectedUntouched; i++) {
    205             if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
    206                 return true;
    207             }
    208         }
    209         return false;
    210     }
    211 
    212 
    213     bool fEnabled;
    214     // break on any change on expected touched or all.
    215     bool fBreakOnAny;
    216     SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
    217     SkColor fBeforeTouched[MAX_TRACKING_POINTS];
    218     int fCntExpectedTouched;
    219 
    220     SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
    221     SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
    222     int fCntExpectedUntouched;
    223 
    224     int fHits;
    225 };
    226 
    227 #endif  // SkTracker_DEFINED
    228