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