|
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 * Holds state during a draw. Users call next() until it returns false. |
|
34 * |
|
35 * Subclasses of SkDrawLooper should create a subclass of this object to |
|
36 * hold state specific to their subclass. |
|
37 */ |
|
38 class SK_API Context : public SkNoncopyable { |
|
39 public: |
|
40 Context() {} |
|
41 virtual ~Context() {} |
|
42 |
|
43 /** |
|
44 * Called in a loop on objects returned by SkDrawLooper::createContext(). |
|
45 * Each time true is returned, the object is drawn (possibly with a modified |
|
46 * canvas and/or paint). When false is finally returned, drawing for the object |
|
47 * stops. |
|
48 * |
|
49 * On each call, the paint will be in its original state, but the |
|
50 * canvas will be as it was following the previous call to next() or |
|
51 * createContext(). |
|
52 * |
|
53 * The implementation must ensure that, when next() finally returns |
|
54 * false, the canvas has been restored to the state it was |
|
55 * initially, before createContext() was first called. |
|
56 */ |
|
57 virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0; |
|
58 }; |
|
59 |
|
60 /** |
|
61 * Called right before something is being drawn. Returns a Context |
|
62 * whose next() method should be called until it returns false. |
|
63 * The caller has to ensure that the storage pointer provides enough |
|
64 * memory for the Context. The required size can be queried by calling |
|
65 * contextSize(). It is also the caller's responsibility to destroy the |
|
66 * object after use. |
|
67 */ |
|
68 virtual Context* createContext(SkCanvas*, void* storage) const = 0; |
|
69 |
|
70 /** |
|
71 * Returns the number of bytes needed to store subclasses of Context (belonging to the |
|
72 * corresponding SkDrawLooper subclass). |
|
73 */ |
|
74 virtual size_t contextSize() const = 0; |
|
75 |
|
76 |
|
77 /** |
|
78 * The fast bounds functions are used to enable the paint to be culled early |
|
79 * in the drawing pipeline. If a subclass can support this feature it must |
|
80 * return true for the canComputeFastBounds() function. If that function |
|
81 * returns false then computeFastBounds behavior is undefined otherwise it |
|
82 * is expected to have the following behavior. Given the parent paint and |
|
83 * the parent's bounding rect the subclass must fill in and return the |
|
84 * storage rect, where the storage rect is with the union of the src rect |
|
85 * and the looper's bounding rect. |
|
86 */ |
|
87 virtual bool canComputeFastBounds(const SkPaint& paint) const; |
|
88 virtual void computeFastBounds(const SkPaint& paint, |
|
89 const SkRect& src, SkRect* dst) const; |
|
90 |
|
91 SK_TO_STRING_PUREVIRT() |
|
92 SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper) |
|
93 |
|
94 protected: |
|
95 SkDrawLooper() {} |
|
96 SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {} |
|
97 |
|
98 private: |
|
99 typedef SkFlattenable INHERITED; |
|
100 }; |
|
101 |
|
102 #endif |