SkLayerDrawLooper.h revision 0716c63332a64c3cc77a9afb87ae2fd9614f0c4f
1#ifndef SkLayerDrawLooper_DEFINED
2#define SkLayerDrawLooper_DEFINED
3
4#include "SkDrawLooper.h"
5#include "SkXfermode.h"
6
7struct SkPoint;
8
9class SkLayerDrawLooper : public SkDrawLooper {
10public:
11            SkLayerDrawLooper();
12    virtual ~SkLayerDrawLooper();
13
14    /**
15     *  Bits specifies which aspects of the layer's paint should replace the
16     *  corresponding aspects on the draw's paint.
17     *  kEntirePaint_Bits means use the layer's paint completely.
18     *  0 means ignore the layer's paint.
19     */
20    enum Bits {
21        kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
22        kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
23        kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
24        kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
25        kShader_Bit     = 1 << 4,   //!< use this layer's shader
26        kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
27        kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode
28
29        kEntirePaint_Bits = -1,      //!< use this layer's paint entirely
30    };
31    typedef int32_t BitFlags;
32
33    /**
34     *  Info for how to apply the layer's paint and offset.
35     *
36     *  fColorMode controls how we compute the final color for the layer:
37     *      The layer's paint's color is treated as the SRC
38     *      The draw's paint's color is treated as the DST
39     *      final-color = Mode(layers-color, draws-color);
40     *  Any SkXfermode::Mode will work. Two common choices are:
41     *      kSrc_Mode: to use the layer's color, ignoring the draw's
42     *      kDst_Mode: to just keep the draw's color, ignoring the layer's
43     */
44    struct LayerInfo {
45        BitFlags            fPaintBits;
46        SkXfermode::Mode    fColorMode;
47        SkVector            fOffset;
48        bool                fPostTranslate; //!< applies to fOffset
49
50        /**
51         *  Initial the LayerInfo. Defaults to settings that will draw the
52         *  layer with no changes: e.g.
53         *      fPaintBits == 0
54         *      fColorMode == kDst_Mode
55         *      fOffset == (0, 0)
56         */
57        LayerInfo();
58    };
59
60    /**
61     *  Call for each layer you want to add (from top to bottom).
62     *  This returns a paint you can modify, but that ptr is only valid until
63     *  the next call made to this object.
64     */
65    SkPaint* addLayer(const LayerInfo&);
66
67    /**
68     *  Call for each layer you want to add (from top to bottom).
69     *  This returns a paint you can modify, but that ptr is only valid until
70     *  the next call made to this object.
71     *  The returned paint will be ignored, and only the offset will be applied
72     *
73     *  DEPRECATED: call addLayer(const LayerInfo&)
74     */
75    SkPaint* addLayer(SkScalar dx, SkScalar dy);
76
77    /**
78     *  Helper for addLayer() which passes (0, 0) for the offset parameters.
79     *  This layer will not affect the drawing in any way.
80     *
81     *  DEPRECATED: call addLayer(const LayerInfo&)
82     */
83    SkPaint* addLayer() {
84        return this->addLayer(0, 0);
85    }
86
87    // overrides from SkDrawLooper
88    virtual void init(SkCanvas*);
89    virtual bool next(SkCanvas*, SkPaint* paint);
90
91    // must be public for Registrar :(
92    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
93        return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
94    }
95
96protected:
97    SkLayerDrawLooper(SkFlattenableReadBuffer&);
98
99    // overrides from SkFlattenable
100    virtual void flatten(SkFlattenableWriteBuffer& );
101    virtual Factory getFactory() { return CreateProc; }
102
103private:
104    struct Rec {
105        Rec*    fNext;
106        SkPaint fPaint;
107        LayerInfo fInfo;
108
109        static Rec* Reverse(Rec*);
110    };
111    Rec*    fRecs;
112    int     fCount;
113
114    // state-machine during the init/next cycle
115    Rec* fCurrRec;
116
117    static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags,
118                          SkXfermode::Mode);
119
120    class MyRegistrar : public SkFlattenable::Registrar {
121    public:
122        MyRegistrar();
123    };
124
125    typedef SkDrawLooper INHERITED;
126};
127
128
129#endif
130