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