| /* | 
 |  * Copyright 2013 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #ifndef SkDeviceLooper_DEFINED | 
 | #define SkDeviceLooper_DEFINED | 
 |  | 
 | #include "SkBitmap.h" | 
 | #include "SkMatrix.h" | 
 | #include "SkRasterClip.h" | 
 |  | 
 | /** | 
 |  *  Helper class to manage "tiling" a large coordinate space into managable | 
 |  *  chunks, where managable means areas that are <= some max critical coordinate | 
 |  *  size. | 
 |  * | 
 |  *  The constructor takes an antialiasing bool, which affects what this maximum | 
 |  *  allowable size is: If we're drawing BW, then we need coordinates to stay | 
 |  *  safely within fixed-point range (we use +- 16K, to give ourselves room to | 
 |  *  add/subtract two fixed values and still be in range. If we're drawing AA, | 
 |  *  then we reduce that size by the amount that the supersampler scan converter | 
 |  *  needs (at the moment, that is 4X, so the "safe" range is +- 4K). | 
 |  * | 
 |  *  For performance reasons, the class first checks to see if any help is needed | 
 |  *  at all, and if not (i.e. the specified bounds and base bitmap area already | 
 |  *  in the safe-zone, then the class does nothing (effectively). | 
 |  */ | 
 | class SkDeviceLooper { | 
 | public: | 
 |     SkDeviceLooper(const SkPixmap& base, const SkRasterClip&, const SkIRect& bounds, bool aa); | 
 |     ~SkDeviceLooper(); | 
 |  | 
 |     const SkPixmap& getPixmap() const { | 
 |         SkASSERT(kDone_State != fState); | 
 |         SkASSERT(fCurrDst); | 
 |         return *fCurrDst; | 
 |     } | 
 |  | 
 |     const SkRasterClip& getRC() const { | 
 |         SkASSERT(kDone_State != fState); | 
 |         SkASSERT(fCurrRC); | 
 |         return *fCurrRC; | 
 |     } | 
 |  | 
 |     void mapRect(SkRect* dst, const SkRect& src) const; | 
 |     void mapMatrix(SkMatrix* dst, const SkMatrix& src) const; | 
 |  | 
 |     /** | 
 |      *  Call next to setup the looper to return a valid coordinate chunk. | 
 |      *  Each time this returns true, it is safe to call mapRect() and | 
 |      *  mapMatrix(), to convert from "global" coordinate values to ones that | 
 |      *  are local to this chunk. | 
 |      * | 
 |      *  When next() returns false, the list of chunks is done, and mapRect() | 
 |      *  and mapMatrix() should no longer be called. | 
 |      */ | 
 |     bool next(); | 
 |  | 
 | private: | 
 |     const SkPixmap&     fBaseDst; | 
 |     const SkRasterClip& fBaseRC; | 
 |  | 
 |     enum State { | 
 |         kDone_State,    // iteration is complete, getters will assert | 
 |         kSimple_State,  // no translate/clip mods needed | 
 |         kComplex_State | 
 |     }; | 
 |  | 
 |     // storage for our tiled versions. Perhaps could use SkTLazy | 
 |     SkPixmap            fSubsetDst; | 
 |     SkRasterClip        fSubsetRC; | 
 |  | 
 |     const SkPixmap*     fCurrDst; | 
 |     const SkRasterClip* fCurrRC; | 
 |     SkIRect             fClippedBounds; | 
 |     SkIPoint            fCurrOffset; | 
 |     int                 fDelta; | 
 |     State               fState; | 
 |  | 
 |     enum Delta { | 
 |         kBW_Delta = 1 << 14,        // 16K, gives room to spare for fixedpoint | 
 |         kAA_Delta = kBW_Delta >> 2  // supersample 4x | 
 |     }; | 
 |  | 
 |     bool fitsInDelta(const SkIRect& r) const { | 
 |         return r.right() < fDelta && r.bottom() < fDelta; | 
 |     } | 
 |  | 
 |     bool computeCurrBitmapAndClip(); | 
 | }; | 
 |  | 
 | #endif |