Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / core / SkXfermode.h
1
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9
10 #ifndef SkXfermode_DEFINED
11 #define SkXfermode_DEFINED
12
13 #include "SkFlattenable.h"
14 #include "SkColor.h"
15
16 class GrEffectRef;
17 class GrTexture;
18 class SkString;
19
20 /** \class SkXfermode
21  *
22  *  SkXfermode is the base class for objects that are called to implement custom
23  *  "transfer-modes" in the drawing pipeline. The static function Create(Modes)
24  *  can be called to return an instance of any of the predefined subclasses as
25  *  specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
26  *  then objects drawn with that paint have the xfermode applied.
27  *
28  *  All subclasses are required to be reentrant-safe : it must be legal to share
29  *  the same instance between several threads.
30  */
31 class SK_API SkXfermode : public SkFlattenable {
32 public:
33     SK_DECLARE_INST_COUNT(SkXfermode)
34
35     SkXfermode() {}
36
37     virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
38                         const SkAlpha aa[]) const;
39     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
40                         const SkAlpha aa[]) const;
41     virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
42                         const SkAlpha aa[]) const;
43
44     /** Enum of possible coefficients to describe some xfermodes
45      */
46     enum Coeff {
47         kZero_Coeff,    /** 0 */
48         kOne_Coeff,     /** 1 */
49         kSC_Coeff,      /** src color */
50         kISC_Coeff,     /** inverse src color (i.e. 1 - sc) */
51         kDC_Coeff,      /** dst color */
52         kIDC_Coeff,     /** inverse dst color (i.e. 1 - dc) */
53         kSA_Coeff,      /** src alpha */
54         kISA_Coeff,     /** inverse src alpha (i.e. 1 - sa) */
55         kDA_Coeff,      /** dst alpha */
56         kIDA_Coeff,     /** inverse dst alpha (i.e. 1 - da) */
57
58         kCoeffCount
59     };
60
61     /** If the xfermode can be expressed as an equation using the coefficients
62         in Coeff, then asCoeff() returns true, and sets (if not null) src and
63         dst accordingly.
64
65             result = src_coeff * src_color + dst_coeff * dst_color;
66
67         As examples, here are some of the porterduff coefficients
68
69         MODE        SRC_COEFF       DST_COEFF
70         clear       zero            zero
71         src         one             zero
72         dst         zero            one
73         srcover     one             isa
74         dstover     ida             one
75      */
76     virtual bool asCoeff(Coeff* src, Coeff* dst) const;
77
78     /**
79      *  The same as calling xfermode->asCoeff(..), except that this also checks
80      *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
81      */
82     static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst);
83
84     /** List of predefined xfermodes.
85         The algebra for the modes uses the following symbols:
86         Sa, Sc  - source alpha and color
87         Da, Dc - destination alpha and color (before compositing)
88         [a, c] - Resulting (alpha, color) values
89         For these equations, the colors are in premultiplied state.
90         If no xfermode is specified, kSrcOver is assumed.
91         The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
92         that aren't Coeffs but have separable r,g,b computations, and finally
93         those that are not separable.
94      */
95     enum Mode {
96         kClear_Mode,    //!< [0, 0]
97         kSrc_Mode,      //!< [Sa, Sc]
98         kDst_Mode,      //!< [Da, Dc]
99         kSrcOver_Mode,  //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc]
100         kDstOver_Mode,  //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc]
101         kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
102         kDstIn_Mode,    //!< [Sa * Da, Sa * Dc]
103         kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
104         kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
105         kSrcATop_Mode,  //!< [Da, Sc * Da + (1 - Sa) * Dc]
106         kDstATop_Mode,  //!< [Sa, Sa * Dc + Sc * (1 - Da)]
107         kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
108         kPlus_Mode,     //!< [Sa + Da, Sc + Dc]
109         kModulate_Mode, // multiplies all components (= alpha and color)
110
111         // Following blend modes are defined in the CSS Compositing standard:
112         // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
113         kScreen_Mode,
114         kLastCoeffMode = kScreen_Mode,
115
116         kOverlay_Mode,
117         kDarken_Mode,
118         kLighten_Mode,
119         kColorDodge_Mode,
120         kColorBurn_Mode,
121         kHardLight_Mode,
122         kSoftLight_Mode,
123         kDifference_Mode,
124         kExclusion_Mode,
125         kMultiply_Mode,
126         kLastSeparableMode = kMultiply_Mode,
127
128         kHue_Mode,
129         kSaturation_Mode,
130         kColor_Mode,
131         kLuminosity_Mode,
132         kLastMode = kLuminosity_Mode
133     };
134
135     /**
136      * Gets the name of the Mode as a string.
137      */
138     static const char* ModeName(Mode);
139
140     /**
141      *  If the xfermode is one of the modes in the Mode enum, then asMode()
142      *  returns true and sets (if not null) mode accordingly. Otherwise it
143      *  returns false and ignores the mode parameter.
144      */
145     virtual bool asMode(Mode* mode) const;
146
147     /**
148      *  The same as calling xfermode->asMode(mode), except that this also checks
149      *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
150      */
151     static bool AsMode(const SkXfermode*, Mode* mode);
152
153     /**
154      *  Returns true if the xfermode claims to be the specified Mode. This works
155      *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
156      *  you can say this without checking for a null...
157      *
158      *  If (SkXfermode::IsMode(paint.getXfermode(),
159      *                         SkXfermode::kDstOver_Mode)) {
160      *      ...
161      *  }
162      */
163     static bool IsMode(const SkXfermode* xfer, Mode mode);
164
165     /** Return an SkXfermode object for the specified mode.
166      */
167     static SkXfermode* Create(Mode mode);
168
169     /** Return a function pointer to a routine that applies the specified
170         porter-duff transfer mode.
171      */
172     static SkXfermodeProc GetProc(Mode mode);
173
174     /** Return a function pointer to a routine that applies the specified
175         porter-duff transfer mode and srcColor to a 16bit device color. Note,
176         if the mode+srcColor might return a non-opaque color, then there is not
177         16bit proc, and this will return NULL.
178       */
179     static SkXfermodeProc16 GetProc16(Mode mode, SkColor srcColor);
180
181     /**
182      *  If the specified mode can be represented by a pair of Coeff, then return
183      *  true and set (if not NULL) the corresponding coeffs. If the mode is
184      *  not representable as a pair of Coeffs, return false and ignore the
185      *  src and dst parameters.
186      */
187     static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
188
189     SK_ATTR_DEPRECATED("use AsMode(...)")
190     static bool IsMode(const SkXfermode* xfer, Mode* mode) {
191         return AsMode(xfer, mode);
192     }
193
194     /** A subclass may implement this factory function to work with the GPU backend. It is legal
195         to call this with all params NULL to simply test the return value. If effect is non-NULL
196         then the xfermode may optionally allocate an effect to return and the caller as *effect.
197         The caller will install it and own a ref to it. Since the xfermode may or may not assign
198         *effect, the caller should set *effect to NULL beforehand. background specifies the
199         texture to use as the background for compositing, and should be accessed in the effect's
200         fragment shader. If NULL, the effect should request access to destination color
201         (setWillReadDstColor()), and use that in the fragment shader (builder->dstColor()).
202      */
203     virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background = NULL) const;
204
205     /** Returns true if the xfermode can be expressed as coeffs (src, dst), or as an effect
206         (effect). This helper calls the asCoeff() and asNewEffect() virtuals. If the xfermode is
207         NULL, it is treated as kSrcOver_Mode. It is legal to call this with all params NULL to
208         simply test the return value.  effect, src, and dst must all be NULL or all non-NULL.
209      */
210     static bool AsNewEffectOrCoeff(SkXfermode*,
211                                    GrEffectRef** effect,
212                                    Coeff* src,
213                                    Coeff* dst,
214                                    GrTexture* background = NULL);
215
216     SkDEVCODE(virtual void toString(SkString* str) const = 0;)
217     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
218     SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
219
220 protected:
221     SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
222
223     /** The default implementation of xfer32/xfer16/xferA8 in turn call this
224         method, 1 color at a time (upscaled to a SkPMColor). The default
225         implmentation of this method just returns dst. If performance is
226         important, your subclass should override xfer32/xfer16/xferA8 directly.
227
228         This method will not be called directly by the client, so it need not
229         be implemented if your subclass has overridden xfer32/xfer16/xferA8
230     */
231     virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
232
233 private:
234     enum {
235         kModeCount = kLastMode + 1
236     };
237
238     friend class SkGraphics;
239     static void Term();
240
241     typedef SkFlattenable INHERITED;
242 };
243
244 ///////////////////////////////////////////////////////////////////////////////
245
246 /** \class SkProcXfermode
247
248     SkProcXfermode is a xfermode that applies the specified proc to its colors.
249     This class is not exported to java.
250 */
251 class SkProcXfermode : public SkXfermode {
252 public:
253     SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {}
254
255     // overrides from SkXfermode
256     virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
257                         const SkAlpha aa[]) const SK_OVERRIDE;
258     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
259                         const SkAlpha aa[]) const SK_OVERRIDE;
260     virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
261                         const SkAlpha aa[]) const SK_OVERRIDE;
262
263     SK_DEVELOPER_TO_STRING()
264     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode)
265
266 protected:
267     SkProcXfermode(SkReadBuffer&);
268     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
269
270     // allow subclasses to update this after we unflatten
271     void setProc(SkXfermodeProc proc) {
272         fProc = proc;
273     }
274
275     SkXfermodeProc getProc() const {
276         return fProc;
277     }
278
279 private:
280     SkXfermodeProc  fProc;
281
282     typedef SkXfermode INHERITED;
283 };
284
285 #endif