SkXfermode.h revision 30da745bbf67a0ee0f305ca7bbdb685cc8a9e686
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 SkXfermode 17 18 SkXfermode is the base class for objects that are called to implement custom 19 "transfer-modes" in the drawing pipeline. The static function Create(Modes) 20 can be called to return an instance of any of the predefined subclasses as 21 specified in the Modes enum. When an SkXfermode is assigned to an SkPaint, 22 then objects drawn with that paint have the xfermode applied. 23*/ 24class SK_API SkXfermode : public SkFlattenable { 25public: 26 SK_DECLARE_INST_COUNT(SkXfermode) 27 28 SkXfermode() {} 29 30 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, 31 const SkAlpha aa[]) const; 32 virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, 33 const SkAlpha aa[]) const; 34 virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count, 35 const SkAlpha aa[]) const; 36 virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, 37 const SkAlpha aa[]) const; 38 39 /** Enum of possible coefficients to describe some xfermodes 40 */ 41 enum Coeff { 42 kZero_Coeff, /** 0 */ 43 kOne_Coeff, /** 1 */ 44 kSC_Coeff, /** src color */ 45 kISC_Coeff, /** inverse src color (i.e. 1 - sc) */ 46 kDC_Coeff, /** dst color */ 47 kIDC_Coeff, /** inverse dst color (i.e. 1 - dc) */ 48 kSA_Coeff, /** src alpha */ 49 kISA_Coeff, /** inverse src alpha (i.e. 1 - sa) */ 50 kDA_Coeff, /** dst alpha */ 51 kIDA_Coeff, /** inverse dst alpha (i.e. 1 - da) */ 52 53 kCoeffCount 54 }; 55 56 /** If the xfermode can be expressed as an equation using the coefficients 57 in Coeff, then asCoeff() returns true, and sets (if not null) src and 58 dst accordingly. 59 60 result = src_coeff * src_color + dst_coeff * dst_color; 61 62 As examples, here are some of the porterduff coefficients 63 64 MODE SRC_COEFF DST_COEFF 65 clear zero zero 66 src one zero 67 dst zero one 68 srcover one isa 69 dstover ida one 70 */ 71 virtual bool asCoeff(Coeff* src, Coeff* dst) const; 72 73 /** 74 * The same as calling xfermode->asCoeff(..), except that this also checks 75 * if the xfermode is NULL, and if so, treats its as kSrcOver_Mode. 76 */ 77 static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst); 78 79 /** List of predefined xfermodes. 80 The algebra for the modes uses the following symbols: 81 Sa, Sc - source alpha and color 82 Da, Dc - destination alpha and color (before compositing) 83 [a, c] - Resulting (alpha, color) values 84 For these equations, the colors are in premultiplied state. 85 If no xfermode is specified, kSrcOver is assumed. 86 */ 87 enum Mode { 88 kClear_Mode, //!< [0, 0] 89 kSrc_Mode, //!< [Sa, Sc] 90 kDst_Mode, //!< [Da, Dc] 91 kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc] 92 kDstOver_Mode, //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc] 93 kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 94 kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 95 kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 96 kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 97 kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 98 kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 99 kXor_Mode, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 100 101 // all remaining modes are defined in the SVG Compositing standard 102 // http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/ 103 kPlus_Mode, 104 kMultiply_Mode, 105 106 // all above modes can be expressed as pair of src/dst Coeffs 107 kCoeffModesCnt, 108 109 kScreen_Mode = kCoeffModesCnt, 110 kOverlay_Mode, 111 kDarken_Mode, 112 kLighten_Mode, 113 kColorDodge_Mode, 114 kColorBurn_Mode, 115 kHardLight_Mode, 116 kSoftLight_Mode, 117 kDifference_Mode, 118 kExclusion_Mode, 119 120 kLastMode = kExclusion_Mode 121 }; 122 123 /** 124 * If the xfermode is one of the modes in the Mode enum, then asMode() 125 * returns true and sets (if not null) mode accordingly. Otherwise it 126 * returns false and ignores the mode parameter. 127 */ 128 virtual bool asMode(Mode* mode) const; 129 130 /** 131 * The same as calling xfermode->asMode(mode), except that this also checks 132 * if the xfermode is NULL, and if so, treats its as kSrcOver_Mode. 133 */ 134 static bool AsMode(const SkXfermode*, Mode* mode); 135 136 /** 137 * Returns true if the xfermode claims to be the specified Mode. This works 138 * correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus 139 * you can say this without checking for a null... 140 * 141 * If (SkXfermode::IsMode(paint.getXfermode(), 142 * SkXfermode::kDstOver_Mode)) { 143 * ... 144 * } 145 */ 146 static bool IsMode(const SkXfermode* xfer, Mode mode); 147 148 /** Return an SkXfermode object for the specified mode. 149 */ 150 static SkXfermode* Create(Mode mode); 151 152 /** Return a function pointer to a routine that applies the specified 153 porter-duff transfer mode. 154 */ 155 static SkXfermodeProc GetProc(Mode mode); 156 157 /** Return a function pointer to a routine that applies the specified 158 porter-duff transfer mode and srcColor to a 16bit device color. Note, 159 if the mode+srcColor might return a non-opaque color, then there is not 160 16bit proc, and this will return NULL. 161 */ 162 static SkXfermodeProc16 GetProc16(Mode mode, SkColor srcColor); 163 164 /** 165 * If the specified mode can be represented by a pair of Coeff, then return 166 * true and set (if not NULL) the corresponding coeffs. If the mode is 167 * not representable as a pair of Coeffs, return false and ignore the 168 * src and dst parameters. 169 */ 170 static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst); 171 172 // DEPRECATED: call AsMode(...) 173 static bool IsMode(const SkXfermode* xfer, Mode* mode) { 174 return AsMode(xfer, mode); 175 } 176 177 SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() 178protected: 179 SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {} 180 181 /** The default implementation of xfer32/xfer16/xferA8 in turn call this 182 method, 1 color at a time (upscaled to a SkPMColor). The default 183 implmentation of this method just returns dst. If performance is 184 important, your subclass should override xfer32/xfer16/xferA8 directly. 185 186 This method will not be called directly by the client, so it need not 187 be implemented if your subclass has overridden xfer32/xfer16/xferA8 188 */ 189 virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const; 190 191private: 192 enum { 193 kModeCount = kLastMode + 1 194 }; 195 typedef SkFlattenable INHERITED; 196}; 197 198/////////////////////////////////////////////////////////////////////////////// 199 200/** \class SkProcXfermode 201 202 SkProcXfermode is a xfermode that applies the specified proc to its colors. 203 This class is not exported to java. 204*/ 205class SkProcXfermode : public SkXfermode { 206public: 207 SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {} 208 209 // overrides from SkXfermode 210 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, 211 const SkAlpha aa[]) const SK_OVERRIDE; 212 virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, 213 const SkAlpha aa[]) const SK_OVERRIDE; 214 virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count, 215 const SkAlpha aa[]) const SK_OVERRIDE; 216 virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, 217 const SkAlpha aa[]) const SK_OVERRIDE; 218 219 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode) 220 221protected: 222 SkProcXfermode(SkFlattenableReadBuffer&); 223 virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 224 225 // allow subclasses to update this after we unflatten 226 void setProc(SkXfermodeProc proc) { 227 fProc = proc; 228 } 229 230private: 231 SkXfermodeProc fProc; 232 233 typedef SkXfermode INHERITED; 234}; 235 236#endif 237