blob: b487a88eebb9f521c2bba9385de80b43cdd4ccba [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#ifndef SkLayerDrawLooper_DEFINED
2#define SkLayerDrawLooper_DEFINED
3
4#include "SkDrawLooper.h"
reed@google.com0716c632011-04-12 18:32:06 +00005#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00006
7struct SkPoint;
8
9class SkLayerDrawLooper : public SkDrawLooper {
10public:
11 SkLayerDrawLooper();
12 virtual ~SkLayerDrawLooper();
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000013
reed@google.com0716c632011-04-12 18:32:06 +000014 /**
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 */
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000020 enum Bits {
reed@google.com0716c632011-04-12 18:32:06 +000021 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
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000028
29 kEntirePaint_Bits = -1, //!< use this layer's paint entirely
30 };
31 typedef int32_t BitFlags;
reed@google.com0716c632011-04-12 18:32:06 +000032
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
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000060 /**
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.
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 */
reed@google.com0716c632011-04-12 18:32:06 +000065 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);
reed@android.com8a1c16f2008-12-17 15:59:43 +000076
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000077 /**
reed@google.com0716c632011-04-12 18:32:06 +000078 * 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&)
reed@android.com8a1c16f2008-12-17 15:59:43 +000082 */
reed@google.com0716c632011-04-12 18:32:06 +000083 SkPaint* addLayer() {
84 return this->addLayer(0, 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +000085 }
86
87 // overrides from SkDrawLooper
reed@google.com4e2b3d32011-04-07 14:18:59 +000088 virtual void init(SkCanvas*);
89 virtual bool next(SkCanvas*, SkPaint* paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +000090
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;
reed@google.com0716c632011-04-12 18:32:06 +0000107 LayerInfo fInfo;
108
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109 static Rec* Reverse(Rec*);
110 };
111 Rec* fRecs;
112 int fCount;
reed@google.com4e2b3d32011-04-07 14:18:59 +0000113
114 // state-machine during the init/next cycle
115 Rec* fCurrRec;
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000116
reed@google.com0716c632011-04-12 18:32:06 +0000117 static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags,
118 SkXfermode::Mode);
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000119
reed@android.com8a1c16f2008-12-17 15:59:43 +0000120 class MyRegistrar : public SkFlattenable::Registrar {
121 public:
122 MyRegistrar();
123 };
124
125 typedef SkDrawLooper INHERITED;
126};
127
128
129#endif