1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/effects/SkLayerDrawLooper.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,180 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkLayerDrawLooper_DEFINED 1.12 +#define SkLayerDrawLooper_DEFINED 1.13 + 1.14 +#include "SkDrawLooper.h" 1.15 +#include "SkPaint.h" 1.16 +#include "SkPoint.h" 1.17 +#include "SkXfermode.h" 1.18 + 1.19 +class SK_API SkLayerDrawLooper : public SkDrawLooper { 1.20 +public: 1.21 + SK_DECLARE_INST_COUNT(SkLayerDrawLooper) 1.22 + 1.23 + SkLayerDrawLooper(); 1.24 + virtual ~SkLayerDrawLooper(); 1.25 + 1.26 + /** 1.27 + * Bits specifies which aspects of the layer's paint should replace the 1.28 + * corresponding aspects on the draw's paint. 1.29 + * kEntirePaint_Bits means use the layer's paint completely. 1.30 + * 0 means ignore the layer's paint... except for fColorMode, which is 1.31 + * always applied. 1.32 + */ 1.33 + enum Bits { 1.34 + kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings 1.35 + kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx 1.36 + kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect 1.37 + kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter 1.38 + kShader_Bit = 1 << 4, //!< use this layer's shader 1.39 + kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter 1.40 + kXfermode_Bit = 1 << 6, //!< use this layer's xfermode 1.41 + 1.42 + /** 1.43 + * Use the layer's paint entirely, with these exceptions: 1.44 + * - We never override the draw's paint's text_encoding, since that is 1.45 + * used to interpret the text/len parameters in draw[Pos]Text. 1.46 + * - Color is always computed using the LayerInfo's fColorMode. 1.47 + */ 1.48 + kEntirePaint_Bits = -1 1.49 + 1.50 + }; 1.51 + typedef int32_t BitFlags; 1.52 + 1.53 + /** 1.54 + * Info for how to apply the layer's paint and offset. 1.55 + * 1.56 + * fColorMode controls how we compute the final color for the layer: 1.57 + * The layer's paint's color is treated as the SRC 1.58 + * The draw's paint's color is treated as the DST 1.59 + * final-color = Mode(layers-color, draws-color); 1.60 + * Any SkXfermode::Mode will work. Two common choices are: 1.61 + * kSrc_Mode: to use the layer's color, ignoring the draw's 1.62 + * kDst_Mode: to just keep the draw's color, ignoring the layer's 1.63 + */ 1.64 + struct SK_API LayerInfo { 1.65 + BitFlags fPaintBits; 1.66 + SkXfermode::Mode fColorMode; 1.67 + SkVector fOffset; 1.68 + bool fPostTranslate; //!< applies to fOffset 1.69 + 1.70 + /** 1.71 + * Initial the LayerInfo. Defaults to settings that will draw the 1.72 + * layer with no changes: e.g. 1.73 + * fPaintBits == 0 1.74 + * fColorMode == kDst_Mode 1.75 + * fOffset == (0, 0) 1.76 + */ 1.77 + LayerInfo(); 1.78 + }; 1.79 + 1.80 + /** 1.81 + * Call for each layer you want to add (from top to bottom). 1.82 + * This returns a paint you can modify, but that ptr is only valid until 1.83 + * the next call made to addLayer(). 1.84 + */ 1.85 + SkPaint* addLayer(const LayerInfo&); 1.86 + 1.87 + /** 1.88 + * This layer will draw with the original paint, at the specified offset 1.89 + */ 1.90 + void addLayer(SkScalar dx, SkScalar dy); 1.91 + 1.92 + /** 1.93 + * This layer will with the original paint and no offset. 1.94 + */ 1.95 + void addLayer() { this->addLayer(0, 0); } 1.96 + 1.97 + /// Similar to addLayer, but adds a layer to the top. 1.98 + SkPaint* addLayerOnTop(const LayerInfo&); 1.99 + 1.100 + virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE; 1.101 + 1.102 + virtual size_t contextSize() const SK_OVERRIDE { return sizeof(LayerDrawLooperContext); } 1.103 + 1.104 + SK_TO_STRING_OVERRIDE() 1.105 + 1.106 + /// Implements Flattenable. 1.107 + virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } 1.108 + static SkFlattenable* CreateProc(SkReadBuffer& buffer); 1.109 + 1.110 +protected: 1.111 + virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 1.112 + 1.113 +private: 1.114 + struct Rec { 1.115 + Rec* fNext; 1.116 + SkPaint fPaint; 1.117 + LayerInfo fInfo; 1.118 + }; 1.119 + Rec* fRecs; 1.120 + Rec* fTopRec; 1.121 + int fCount; 1.122 + 1.123 + // state-machine during the init/next cycle 1.124 + class LayerDrawLooperContext : public SkDrawLooper::Context { 1.125 + public: 1.126 + explicit LayerDrawLooperContext(const SkLayerDrawLooper* looper); 1.127 + 1.128 + protected: 1.129 + virtual bool next(SkCanvas*, SkPaint* paint) SK_OVERRIDE; 1.130 + 1.131 + private: 1.132 + Rec* fCurrRec; 1.133 + 1.134 + static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); 1.135 + }; 1.136 + 1.137 + class MyRegistrar : public SkFlattenable::Registrar { 1.138 + public: 1.139 + MyRegistrar(); 1.140 + }; 1.141 + 1.142 + typedef SkDrawLooper INHERITED; 1.143 + 1.144 +public: 1.145 + class SK_API Builder { 1.146 + public: 1.147 + Builder(); 1.148 + ~Builder(); 1.149 + 1.150 + /** 1.151 + * Call for each layer you want to add (from top to bottom). 1.152 + * This returns a paint you can modify, but that ptr is only valid until 1.153 + * the next call made to addLayer(). 1.154 + */ 1.155 + SkPaint* addLayer(const LayerInfo&); 1.156 + 1.157 + /** 1.158 + * This layer will draw with the original paint, at the specified offset 1.159 + */ 1.160 + void addLayer(SkScalar dx, SkScalar dy); 1.161 + 1.162 + /** 1.163 + * This layer will with the original paint and no offset. 1.164 + */ 1.165 + void addLayer() { this->addLayer(0, 0); } 1.166 + 1.167 + /// Similar to addLayer, but adds a layer to the top. 1.168 + SkPaint* addLayerOnTop(const LayerInfo&); 1.169 + 1.170 + /** 1.171 + * Pass list of layers on to newly built looper and return it. This will 1.172 + * also reset the builder, so it can be used to build another looper. 1.173 + */ 1.174 + SkLayerDrawLooper* detachLooper(); 1.175 + 1.176 + private: 1.177 + Rec* fRecs; 1.178 + Rec* fTopRec; 1.179 + int fCount; 1.180 + }; 1.181 +}; 1.182 + 1.183 +#endif