Line data Source code
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 SkArenaAlloc;
19 : class SkCanvas;
20 : class SkColorSpaceXformer;
21 : class SkPaint;
22 : struct SkRect;
23 : class SkString;
24 :
25 : /** \class SkDrawLooper
26 : Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
27 : and something is drawn to a canvas with that paint, the looper subclass will
28 : be called, allowing it to modify the canvas and/or paint for that draw call.
29 : More than that, via the next() method, the looper can modify the draw to be
30 : invoked multiple times (hence the name loop-er), allow it to perform effects
31 : like shadows or frame/fills, that require more than one pass.
32 : */
33 : class SK_API SkDrawLooper : public SkFlattenable {
34 : public:
35 : /**
36 : * Holds state during a draw. Users call next() until it returns false.
37 : *
38 : * Subclasses of SkDrawLooper should create a subclass of this object to
39 : * hold state specific to their subclass.
40 : */
41 : class SK_API Context : ::SkNoncopyable {
42 : public:
43 : Context() {}
44 : virtual ~Context() {}
45 :
46 : /**
47 : * Called in a loop on objects returned by SkDrawLooper::createContext().
48 : * Each time true is returned, the object is drawn (possibly with a modified
49 : * canvas and/or paint). When false is finally returned, drawing for the object
50 : * stops.
51 : *
52 : * On each call, the paint will be in its original state, but the
53 : * canvas will be as it was following the previous call to next() or
54 : * createContext().
55 : *
56 : * The implementation must ensure that, when next() finally returns
57 : * false, the canvas has been restored to the state it was
58 : * initially, before createContext() was first called.
59 : */
60 : virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
61 : };
62 :
63 : /**
64 : * Called right before something is being drawn. Returns a Context
65 : * whose next() method should be called until it returns false.
66 : */
67 : virtual Context* makeContext(SkCanvas*, SkArenaAlloc*) const = 0;
68 :
69 : /**
70 : * The fast bounds functions are used to enable the paint to be culled early
71 : * in the drawing pipeline. If a subclass can support this feature it must
72 : * return true for the canComputeFastBounds() function. If that function
73 : * returns false then computeFastBounds behavior is undefined otherwise it
74 : * is expected to have the following behavior. Given the parent paint and
75 : * the parent's bounding rect the subclass must fill in and return the
76 : * storage rect, where the storage rect is with the union of the src rect
77 : * and the looper's bounding rect.
78 : */
79 : bool canComputeFastBounds(const SkPaint& paint) const;
80 : void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;
81 :
82 : struct BlurShadowRec {
83 : SkScalar fSigma;
84 : SkVector fOffset;
85 : SkColor fColor;
86 : SkBlurStyle fStyle;
87 : SkBlurQuality fQuality;
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 :
100 : SK_TO_STRING_PUREVIRT()
101 0 : SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
102 :
103 : protected:
104 0 : sk_sp<SkDrawLooper> makeColorSpace(SkColorSpaceXformer* xformer) const {
105 0 : return this->onMakeColorSpace(xformer);
106 : }
107 : virtual sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
108 :
109 : SkDrawLooper() {}
110 :
111 : private:
112 : friend class SkColorSpaceXformer;
113 :
114 : typedef SkFlattenable INHERITED;
115 : };
116 :
117 : #endif
|