SkLayerDrawLooper.h revision a8282ef8f9e63e60c5665af0cdfc8fdd11c089f6
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     *  fFlagsMask selects which flags in the layer's paint should be applied.
37     *      result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
38     *  In the extreme:
39     *      If fFlagsMask is 0, we ignore all of the layer's flags
40     *      If fFlagsMask is -1, we use all of the layer's flags
41     *
42     *  fColorMode controls how we compute the final color for the layer:
43     *      The layer's paint's color is treated as the SRC
44     *      The draw's paint's color is treated as the DST
45     *      final-color = Mode(layers-color, draws-color);
46     *  Any SkXfermode::Mode will work. Two common choices are:
47     *      kSrc_Mode: to use the layer's color, ignoring the draw's
48     *      kDst_Mode: to just keep the draw's color, ignoring the layer's
49     */
50    struct LayerInfo {
51        uint32_t            fFlagsMask; // SkPaint::Flags
52        BitFlags            fPaintBits;
53        SkXfermode::Mode    fColorMode;
54        SkVector            fOffset;
55        bool                fPostTranslate; //!< applies to fOffset
56
57        /**
58         *  Initial the LayerInfo. Defaults to settings that will draw the
59         *  layer with no changes: e.g.
60         *      fPaintBits == 0
61         *      fColorMode == kDst_Mode
62         *      fOffset == (0, 0)
63         */
64        LayerInfo();
65    };
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 addLayer().
71     */
72    SkPaint* addLayer(const LayerInfo&);
73
74    /**
75     *  This layer will draw with the original paint, ad the specified offset
76     */
77    void addLayer(SkScalar dx, SkScalar dy);
78
79    /**
80     *  This layer will with the original paint and no offset.
81     */
82    void addLayer() { this->addLayer(0, 0); }
83
84    // overrides from SkDrawLooper
85    virtual void init(SkCanvas*);
86    virtual bool next(SkCanvas*, SkPaint* paint);
87
88    // must be public for Registrar :(
89    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
90        return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
91    }
92
93protected:
94    SkLayerDrawLooper(SkFlattenableReadBuffer&);
95
96    // overrides from SkFlattenable
97    virtual void flatten(SkFlattenableWriteBuffer& );
98    virtual Factory getFactory() { return CreateProc; }
99
100private:
101    struct Rec {
102        Rec*    fNext;
103        SkPaint fPaint;
104        LayerInfo fInfo;
105
106        static Rec* Reverse(Rec*);
107    };
108    Rec*    fRecs;
109    int     fCount;
110
111    // state-machine during the init/next cycle
112    Rec* fCurrRec;
113
114    static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
115
116    class MyRegistrar : public SkFlattenable::Registrar {
117    public:
118        MyRegistrar();
119    };
120
121    typedef SkDrawLooper INHERITED;
122};
123
124
125#endif
126