1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkLayerDrawLooper_DEFINED 9 #define SkLayerDrawLooper_DEFINED 10 11 #include "include/core/SkBlendMode.h" 12 #include "include/core/SkDrawLooper.h" 13 #include "include/core/SkPaint.h" 14 #include "include/core/SkPoint.h" 15 16 #ifndef SK_SUPPORT_LEGACY_DRAWLOOPER 17 #error "SkDrawLooper is unsupported" 18 #endif 19 20 /** 21 * DEPRECATED: No longer supported by Skia. 22 */ 23 class SK_API SkLayerDrawLooper : public SkDrawLooper { 24 public: 25 ~SkLayerDrawLooper() override; 26 27 /** 28 * Bits specifies which aspects of the layer's paint should replace the 29 * corresponding aspects on the draw's paint. 30 * kEntirePaint_Bits means use the layer's paint completely. 31 * 0 means ignore the layer's paint... except for fColorMode, which is 32 * always applied. 33 */ 34 enum Bits { 35 kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings 36 kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect 37 kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter 38 kShader_Bit = 1 << 4, //!< use this layer's shader 39 kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter 40 kXfermode_Bit = 1 << 6, //!< use this layer's xfermode 41 42 // unsupported kTextSkewX_Bit = 1 << 1, 43 44 /** 45 * Use the layer's paint entirely, with these exceptions: 46 * - We never override the draw's paint's text_encoding, since that is 47 * used to interpret the text/len parameters in draw[Pos]Text. 48 * - Color is always computed using the LayerInfo's fColorMode. 49 */ 50 kEntirePaint_Bits = -1 51 52 }; 53 typedef int32_t BitFlags; 54 55 /** 56 * Info for how to apply the layer's paint and offset. 57 * 58 * fColorMode controls how we compute the final color for the layer: 59 * The layer's paint's color is treated as the SRC 60 * The draw's paint's color is treated as the DST 61 * final-color = Mode(layers-color, draws-color); 62 * Any SkBlendMode will work. Two common choices are: 63 * kSrc: to use the layer's color, ignoring the draw's 64 * kDst: to just keep the draw's color, ignoring the layer's 65 */ 66 struct SK_API LayerInfo { 67 BitFlags fPaintBits; 68 SkBlendMode fColorMode; 69 SkVector fOffset; 70 bool fPostTranslate; //!< applies to fOffset 71 72 /** 73 * Initial the LayerInfo. Defaults to settings that will draw the 74 * layer with no changes: e.g. 75 * fPaintBits == 0 76 * fColorMode == kDst_Mode 77 * fOffset == (0, 0) 78 */ 79 LayerInfo(); 80 }; 81 82 SkDrawLooper::Context* makeContext(SkArenaAlloc*) const override; 83 84 bool asABlurShadow(BlurShadowRec* rec) const override; 85 86 protected: 87 SkLayerDrawLooper(); 88 89 void flatten(SkWriteBuffer&) const override; 90 91 private: 92 SK_FLATTENABLE_HOOKS(SkLayerDrawLooper) 93 94 struct Rec { 95 Rec* fNext; 96 SkPaint fPaint; 97 LayerInfo fInfo; 98 }; 99 Rec* fRecs; 100 int fCount; 101 102 // state-machine during the init/next cycle 103 class LayerDrawLooperContext : public SkDrawLooper::Context { 104 public: 105 explicit LayerDrawLooperContext(const SkLayerDrawLooper* looper); 106 107 protected: 108 bool next(Info*, SkPaint* paint) override; 109 110 private: 111 Rec* fCurrRec; 112 113 static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); 114 }; 115 116 using INHERITED = SkDrawLooper; 117 118 public: 119 class SK_API Builder { 120 public: 121 Builder(); 122 123 ~Builder(); 124 125 /** 126 * Call for each layer you want to add (from top to bottom). 127 * This returns a paint you can modify, but that ptr is only valid until 128 * the next call made to addLayer(). 129 */ 130 SkPaint* addLayer(const LayerInfo&); 131 132 /** 133 * This layer will draw with the original paint, at the specified offset 134 */ 135 void addLayer(SkScalar dx, SkScalar dy); 136 137 /** 138 * This layer will with the original paint and no offset. 139 */ addLayer()140 void addLayer() { this->addLayer(0, 0); } 141 142 /// Similar to addLayer, but adds a layer to the top. 143 SkPaint* addLayerOnTop(const LayerInfo&); 144 145 /** 146 * Pass list of layers on to newly built looper and return it. This will 147 * also reset the builder, so it can be used to build another looper. 148 */ 149 sk_sp<SkDrawLooper> detach(); 150 151 private: 152 Builder(const Builder&) = delete; 153 Builder& operator=(const Builder&) = delete; 154 155 Rec* fRecs; 156 Rec* fTopRec; 157 int fCount; 158 }; 159 }; 160 161 #endif 162