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 "SkBlurTypes.h"
     14 #include "SkFlattenable.h"
     15 #include "SkPoint.h"
     16 #include "SkColor.h"
     17 
     18 class SkCanvas;
     19 class SkPaint;
     20 struct SkRect;
     21 class SkString;
     22 
     23 /** \class SkDrawLooper
     24     Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
     25     and something is drawn to a canvas with that paint, the looper subclass will
     26     be called, allowing it to modify the canvas and/or paint for that draw call.
     27     More than that, via the next() method, the looper can modify the draw to be
     28     invoked multiple times (hence the name loop-er), allow it to perform effects
     29     like shadows or frame/fills, that require more than one pass.
     30 */
     31 class SK_API SkDrawLooper : public SkFlattenable {
     32 public:
     33     /**
     34      *  Holds state during a draw. Users call next() until it returns false.
     35      *
     36      *  Subclasses of SkDrawLooper should create a subclass of this object to
     37      *  hold state specific to their subclass.
     38      */
     39     class SK_API Context : ::SkNoncopyable {
     40     public:
     41         Context() {}
     42         virtual ~Context() {}
     43 
     44         /**
     45          *  Called in a loop on objects returned by SkDrawLooper::createContext().
     46          *  Each time true is returned, the object is drawn (possibly with a modified
     47          *  canvas and/or paint). When false is finally returned, drawing for the object
     48          *  stops.
     49          *
     50          *  On each call, the paint will be in its original state, but the
     51          *  canvas will be as it was following the previous call to next() or
     52          *  createContext().
     53          *
     54          *  The implementation must ensure that, when next() finally returns
     55          *  false, the canvas has been restored to the state it was
     56          *  initially, before createContext() was first called.
     57          */
     58         virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
     59     };
     60 
     61     /**
     62      *  Called right before something is being drawn. Returns a Context
     63      *  whose next() method should be called until it returns false.
     64      *  The caller has to ensure that the storage pointer provides enough
     65      *  memory for the Context. The required size can be queried by calling
     66      *  contextSize(). It is also the caller's responsibility to destroy the
     67      *  object after use.
     68      */
     69     virtual Context* createContext(SkCanvas*, void* storage) const = 0;
     70 
     71     /**
     72       *  Returns the number of bytes needed to store subclasses of Context (belonging to the
     73       *  corresponding SkDrawLooper subclass).
     74       */
     75     virtual size_t contextSize() const = 0;
     76 
     77 
     78     /**
     79      * The fast bounds functions are used to enable the paint to be culled early
     80      * in the drawing pipeline. If a subclass can support this feature it must
     81      * return true for the canComputeFastBounds() function.  If that function
     82      * returns false then computeFastBounds behavior is undefined otherwise it
     83      * is expected to have the following behavior. Given the parent paint and
     84      * the parent's bounding rect the subclass must fill in and return the
     85      * storage rect, where the storage rect is with the union of the src rect
     86      * and the looper's bounding rect.
     87      */
     88     bool canComputeFastBounds(const SkPaint& paint) const;
     89     void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;
     90 
     91     struct BlurShadowRec {
     92         SkScalar        fSigma;
     93         SkVector        fOffset;
     94         SkColor         fColor;
     95         SkBlurStyle     fStyle;
     96         SkBlurQuality   fQuality;
     97     };
     98     /**
     99      *  If this looper can be interpreted as having two layers, such that
    100      *      1. The first layer (bottom most) just has a blur and translate
    101      *      2. The second layer has no modifications to either paint or canvas
    102      *      3. No other layers.
    103      *  then return true, and if not null, fill out the BlurShadowRec).
    104      *
    105      *  If any of the above are not met, return false and ignore the BlurShadowRec parameter.
    106      */
    107     virtual bool asABlurShadow(BlurShadowRec*) const;
    108 
    109     SK_TO_STRING_PUREVIRT()
    110     SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
    111 
    112 protected:
    113     SkDrawLooper() {}
    114 
    115 private:
    116     typedef SkFlattenable INHERITED;
    117 };
    118 
    119 #endif
    120