blob: cec78b7466cb2df12f784bccd2c9b5c02bef92ec [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
tfarina@chromium.org6806fe82012-10-12 14:41:39 +00007
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#ifndef SkLayerDrawLooper_DEFINED
9#define SkLayerDrawLooper_DEFINED
10
11#include "SkDrawLooper.h"
reed@google.com0716c632011-04-12 18:32:06 +000012#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013
14struct SkPoint;
15
bsalomon@google.com8c3ff172011-04-15 15:42:24 +000016class SK_API SkLayerDrawLooper : public SkDrawLooper {
reed@android.com8a1c16f2008-12-17 15:59:43 +000017public:
robertphillips@google.com0456e0b2012-06-27 14:03:26 +000018 SK_DECLARE_INST_COUNT(SkLayerDrawLooper)
19
reed@android.com8a1c16f2008-12-17 15:59:43 +000020 SkLayerDrawLooper();
21 virtual ~SkLayerDrawLooper();
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000022
reed@google.com0716c632011-04-12 18:32:06 +000023 /**
24 * Bits specifies which aspects of the layer's paint should replace the
25 * corresponding aspects on the draw's paint.
26 * kEntirePaint_Bits means use the layer's paint completely.
reed@google.com84260582011-11-21 16:42:10 +000027 * 0 means ignore the layer's paint... except that LayerInfo's fFlagsMask
28 * and fColorMode are always applied.
reed@google.com0716c632011-04-12 18:32:06 +000029 */
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000030 enum Bits {
reed@google.com0716c632011-04-12 18:32:06 +000031 kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings
32 kTextSkewX_Bit = 1 << 1, //!< use this layer's textskewx
33 kPathEffect_Bit = 1 << 2, //!< use this layer's patheffect
34 kMaskFilter_Bit = 1 << 3, //!< use this layer's maskfilter
35 kShader_Bit = 1 << 4, //!< use this layer's shader
36 kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter
37 kXfermode_Bit = 1 << 6, //!< use this layer's xfermode
rmistry@google.comfbfcd562012-08-23 18:09:54 +000038
reed@google.com84260582011-11-21 16:42:10 +000039 /**
40 * Use the layer's paint entirely, with these exceptions:
41 * - We never override the draw's paint's text_encoding, since that is
42 * used to interpret the text/len parameters in draw[Pos]Text.
43 * - Flags and Color are always computed using the LayerInfo's
44 * fFlagsMask and fColorMode.
45 */
tomhudson@google.com1f902872012-06-01 13:15:47 +000046 kEntirePaint_Bits = -1
rmistry@google.comfbfcd562012-08-23 18:09:54 +000047
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000048 };
49 typedef int32_t BitFlags;
reed@google.com0716c632011-04-12 18:32:06 +000050
51 /**
52 * Info for how to apply the layer's paint and offset.
53 *
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +000054 * fFlagsMask selects which flags in the layer's paint should be applied.
55 * result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
56 * In the extreme:
57 * If fFlagsMask is 0, we ignore all of the layer's flags
58 * If fFlagsMask is -1, we use all of the layer's flags
59 *
reed@google.com0716c632011-04-12 18:32:06 +000060 * fColorMode controls how we compute the final color for the layer:
61 * The layer's paint's color is treated as the SRC
62 * The draw's paint's color is treated as the DST
63 * final-color = Mode(layers-color, draws-color);
64 * Any SkXfermode::Mode will work. Two common choices are:
65 * kSrc_Mode: to use the layer's color, ignoring the draw's
66 * kDst_Mode: to just keep the draw's color, ignoring the layer's
67 */
bsalomon@google.com8c3ff172011-04-15 15:42:24 +000068 struct SK_API LayerInfo {
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +000069 uint32_t fFlagsMask; // SkPaint::Flags
reed@google.com0716c632011-04-12 18:32:06 +000070 BitFlags fPaintBits;
71 SkXfermode::Mode fColorMode;
72 SkVector fOffset;
73 bool fPostTranslate; //!< applies to fOffset
74
75 /**
76 * Initial the LayerInfo. Defaults to settings that will draw the
77 * layer with no changes: e.g.
78 * fPaintBits == 0
79 * fColorMode == kDst_Mode
80 * fOffset == (0, 0)
81 */
82 LayerInfo();
83 };
84
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000085 /**
86 * Call for each layer you want to add (from top to bottom).
87 * This returns a paint you can modify, but that ptr is only valid until
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +000088 * the next call made to addLayer().
reed@android.com8a1c16f2008-12-17 15:59:43 +000089 */
reed@google.com0716c632011-04-12 18:32:06 +000090 SkPaint* addLayer(const LayerInfo&);
91
92 /**
robertphillips@google.com4991b8f2013-01-28 20:21:59 +000093 * This layer will draw with the original paint, at the specified offset
reed@google.com0716c632011-04-12 18:32:06 +000094 */
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +000095 void addLayer(SkScalar dx, SkScalar dy);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000096
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +000097 /**
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +000098 * This layer will with the original paint and no offset.
reed@android.com8a1c16f2008-12-17 15:59:43 +000099 */
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +0000100 void addLayer() { this->addLayer(0, 0); }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000101
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102 // overrides from SkDrawLooper
reed@google.com4e2b3d32011-04-07 14:18:59 +0000103 virtual void init(SkCanvas*);
104 virtual bool next(SkCanvas*, SkPaint* paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105
robertphillips@google.com4991b8f2013-01-28 20:21:59 +0000106 SK_DEVELOPER_TO_STRING()
djsollen@google.comba28d032012-03-26 17:57:35 +0000107 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerDrawLooper)
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000108
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109protected:
110 SkLayerDrawLooper(SkFlattenableReadBuffer&);
djsollen@google.com54924242012-03-29 15:18:04 +0000111 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000112
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113private:
114 struct Rec {
115 Rec* fNext;
116 SkPaint fPaint;
reed@google.com0716c632011-04-12 18:32:06 +0000117 LayerInfo fInfo;
118
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 static Rec* Reverse(Rec*);
120 };
121 Rec* fRecs;
122 int fCount;
reed@google.com4e2b3d32011-04-07 14:18:59 +0000123
124 // state-machine during the init/next cycle
125 Rec* fCurrRec;
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000126
mike@reedtribe.orga8282ef2011-04-14 01:22:45 +0000127 static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
mike@reedtribe.org0e2810b2011-04-08 02:41:54 +0000128
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 class MyRegistrar : public SkFlattenable::Registrar {
130 public:
131 MyRegistrar();
132 };
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000133
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 typedef SkDrawLooper INHERITED;
135};
136
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137#endif