Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkDrawLooper_DEFINED
     11 #define SkDrawLooper_DEFINED
     12 
     13 #include "SkFlattenable.h"
     14 
     15 class SkCanvas;
     16 class SkPaint;
     17 struct SkRect;
     18 class SkString;
     19 
     20 /** \class SkDrawLooper
     21     Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
     22     and something is drawn to a canvas with that paint, the looper subclass will
     23     be called, allowing it to modify the canvas and/or paint for that draw call.
     24     More than that, via the next() method, the looper can modify the draw to be
     25     invoked multiple times (hence the name loop-er), allow it to perform effects
     26     like shadows or frame/fills, that require more than one pass.
     27 */
     28 class SK_API SkDrawLooper : public SkFlattenable {
     29 public:
     30     SK_DECLARE_INST_COUNT(SkDrawLooper)
     31 
     32     /**
     33      *  Called right before something is being drawn. This will be followed by
     34      *  calls to next() until next() returns false.
     35      */
     36     virtual void init(SkCanvas*) = 0;
     37 
     38     /**
     39      *  Called in a loop (after init()). Each time true is returned, the object
     40      *  is drawn (possibly with a modified canvas and/or paint). When false is
     41      *  finally returned, drawing for the object stops.
     42      *
     43      *  On each call, the paint will be in its original state, but the canvas
     44      *  will be as it was following the previous call to next() or init().
     45      *
     46      *  The implementation must ensure that, when next() finally returns false,
     47      *  that the canvas has been restored to the state it was initially, before
     48      *  init() was first called.
     49      */
     50     virtual bool next(SkCanvas*, SkPaint* paint) = 0;
     51 
     52     /**
     53      * The fast bounds functions are used to enable the paint to be culled early
     54      * in the drawing pipeline. If a subclass can support this feature it must
     55      * return true for the canComputeFastBounds() function.  If that function
     56      * returns false then computeFastBounds behavior is undefined otherwise it
     57      * is expected to have the following behavior. Given the parent paint and
     58      * the parent's bounding rect the subclass must fill in and return the
     59      * storage rect, where the storage rect is with the union of the src rect
     60      * and the looper's bounding rect.
     61      */
     62     virtual bool canComputeFastBounds(const SkPaint& paint);
     63     virtual void computeFastBounds(const SkPaint& paint,
     64                                    const SkRect& src, SkRect* dst);
     65 
     66     SkDEVCODE(virtual void toString(SkString* str) const = 0;)
     67 
     68 protected:
     69     SkDrawLooper() {}
     70     SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
     71 
     72 private:
     73     typedef SkFlattenable INHERITED;
     74 };
     75 
     76 #endif
     77