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