Home | History | Annotate | Download | only in core
      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 SkDeviceLooper_DEFINED
      9 #define SkDeviceLooper_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 #include "SkMatrix.h"
     13 #include "SkRasterClip.h"
     14 
     15 /**
     16  *  Helper class to manage "tiling" a large coordinate space into managable
     17  *  chunks, where managable means areas that are <= some max critical coordinate
     18  *  size.
     19  *
     20  *  The constructor takes an antialiasing bool, which affects what this maximum
     21  *  allowable size is: If we're drawing BW, then we need coordinates to stay
     22  *  safely within fixed-point range (we use +- 16K, to give ourselves room to
     23  *  add/subtract two fixed values and still be in range. If we're drawing AA,
     24  *  then we reduce that size by the amount that the supersampler scan converter
     25  *  needs (at the moment, that is 4X, so the "safe" range is +- 4K).
     26  *
     27  *  For performance reasons, the class first checks to see if any help is needed
     28  *  at all, and if not (i.e. the specified bounds and base bitmap area already
     29  *  in the safe-zone, then the class does nothing (effectively).
     30  */
     31 class SkDeviceLooper {
     32 public:
     33     SkDeviceLooper(const SkBitmap& base, const SkRasterClip&,
     34                    const SkIRect& bounds, bool aa);
     35     ~SkDeviceLooper();
     36 
     37     const SkBitmap& getBitmap() const {
     38         SkASSERT(kDone_State != fState);
     39         SkASSERT(fCurrBitmap);
     40         return *fCurrBitmap;
     41     }
     42 
     43     const SkRasterClip& getRC() const {
     44         SkASSERT(kDone_State != fState);
     45         SkASSERT(fCurrRC);
     46         return *fCurrRC;
     47     }
     48 
     49     void mapRect(SkRect* dst, const SkRect& src) const;
     50     void mapMatrix(SkMatrix* dst, const SkMatrix& src) const;
     51 
     52     /**
     53      *  Call next to setup the looper to return a valid coordinate chunk.
     54      *  Each time this returns true, it is safe to call mapRect() and
     55      *  mapMatrix(), to convert from "global" coordinate values to ones that
     56      *  are local to this chunk.
     57      *
     58      *  When next() returns false, the list of chunks is done, and mapRect()
     59      *  and mapMatrix() should no longer be called.
     60      */
     61     bool next();
     62 
     63 private:
     64     const SkBitmap&     fBaseBitmap;
     65     const SkRasterClip& fBaseRC;
     66 
     67     enum State {
     68         kDone_State,    // iteration is complete, getters will assert
     69         kSimple_State,  // no translate/clip mods needed
     70         kComplex_State
     71     };
     72 
     73     // storage for our tiled versions. Perhaps could use SkTLazy
     74     SkBitmap            fSubsetBitmap;
     75     SkRasterClip        fSubsetRC;
     76 
     77     const SkBitmap*     fCurrBitmap;
     78     const SkRasterClip* fCurrRC;
     79     SkIRect             fClippedBounds;
     80     SkIPoint            fCurrOffset;
     81     int                 fDelta;
     82     State               fState;
     83 
     84     enum Delta {
     85         kBW_Delta = 1 << 14,        // 16K, gives room to spare for fixedpoint
     86         kAA_Delta = kBW_Delta >> 2  // supersample 4x
     87     };
     88 
     89     bool fitsInDelta(const SkIRect& r) const {
     90         return r.right() < fDelta && r.bottom() < fDelta;
     91     }
     92 
     93     bool computeCurrBitmapAndClip();
     94 };
     95 
     96 #endif
     97