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