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