1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#ifndef SkLayerDrawLooper_DEFINED 9#define SkLayerDrawLooper_DEFINED 10 11#include "SkDrawLooper.h" 12#include "SkXfermode.h" 13 14struct SkPoint; 15 16class SK_API SkLayerDrawLooper : public SkDrawLooper { 17public: 18 SkLayerDrawLooper(); 19 virtual ~SkLayerDrawLooper(); 20 21 /** 22 * Bits specifies which aspects of the layer's paint should replace the 23 * corresponding aspects on the draw's paint. 24 * kEntirePaint_Bits means use the layer's paint completely. 25 * 0 means ignore the layer's paint... except that LayerInfo's fFlagsMask 26 * and fColorMode are always applied. 27 */ 28 enum Bits { 29 kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings 30 kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx 31 kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect 32 kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter 33 kShader_Bit = 1 << 4, //!< use this layer's shader 34 kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter 35 kXfermode_Bit = 1 << 6, //!< use this layer's xfermode 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 * - Flags and Color are always computed using the LayerInfo's 42 * fFlagsMask and 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 * fFlagsMask selects which flags in the layer's paint should be applied. 53 * result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask) 54 * In the extreme: 55 * If fFlagsMask is 0, we ignore all of the layer's flags 56 * If fFlagsMask is -1, we use all of the layer's flags 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 SkXfermode::Mode will work. Two common choices are: 63 * kSrc_Mode: to use the layer's color, ignoring the draw's 64 * kDst_Mode: to just keep the draw's color, ignoring the layer's 65 */ 66 struct SK_API LayerInfo { 67 uint32_t fFlagsMask; // SkPaint::Flags 68 BitFlags fPaintBits; 69 SkXfermode::Mode fColorMode; 70 SkVector fOffset; 71 bool fPostTranslate; //!< applies to fOffset 72 73 /** 74 * Initial the LayerInfo. Defaults to settings that will draw the 75 * layer with no changes: e.g. 76 * fPaintBits == 0 77 * fColorMode == kDst_Mode 78 * fOffset == (0, 0) 79 */ 80 LayerInfo(); 81 }; 82 83 /** 84 * Call for each layer you want to add (from top to bottom). 85 * This returns a paint you can modify, but that ptr is only valid until 86 * the next call made to addLayer(). 87 */ 88 SkPaint* addLayer(const LayerInfo&); 89 90 /** 91 * This layer will draw with the original paint, ad the specified offset 92 */ 93 void addLayer(SkScalar dx, SkScalar dy); 94 95 /** 96 * This layer will with the original paint and no offset. 97 */ 98 void addLayer() { this->addLayer(0, 0); } 99 100 // overrides from SkDrawLooper 101 virtual void init(SkCanvas*); 102 virtual bool next(SkCanvas*, SkPaint* paint); 103 104 // must be public for Registrar :( 105 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 106 return SkNEW_ARGS(SkLayerDrawLooper, (buffer)); 107 } 108 109 SK_DECLARE_FLATTENABLE_REGISTRAR() 110 111protected: 112 SkLayerDrawLooper(SkFlattenableReadBuffer&); 113 114 // overrides from SkFlattenable 115 virtual void flatten(SkFlattenableWriteBuffer& ); 116 virtual Factory getFactory() { return CreateProc; } 117 118private: 119 struct Rec { 120 Rec* fNext; 121 SkPaint fPaint; 122 LayerInfo fInfo; 123 124 static Rec* Reverse(Rec*); 125 }; 126 Rec* fRecs; 127 int fCount; 128 129 // state-machine during the init/next cycle 130 Rec* fCurrRec; 131 132 static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); 133 134 class MyRegistrar : public SkFlattenable::Registrar { 135 public: 136 MyRegistrar(); 137 }; 138 139 typedef SkDrawLooper INHERITED; 140}; 141 142 143#endif 144