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