gfx/skia/trunk/include/core/SkXfermode.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/core/SkXfermode.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,295 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#ifndef SkXfermode_DEFINED
    1.14 +#define SkXfermode_DEFINED
    1.15 +
    1.16 +#include "SkFlattenable.h"
    1.17 +#include "SkColor.h"
    1.18 +
    1.19 +class GrEffectRef;
    1.20 +class GrTexture;
    1.21 +class SkString;
    1.22 +
    1.23 +/** \class SkXfermode
    1.24 + *
    1.25 + *  SkXfermode is the base class for objects that are called to implement custom
    1.26 + *  "transfer-modes" in the drawing pipeline. The static function Create(Modes)
    1.27 + *  can be called to return an instance of any of the predefined subclasses as
    1.28 + *  specified in the Modes enum. When an SkXfermode is assigned to an SkPaint,
    1.29 + *  then objects drawn with that paint have the xfermode applied.
    1.30 + *
    1.31 + *  All subclasses are required to be reentrant-safe : it must be legal to share
    1.32 + *  the same instance between several threads.
    1.33 + */
    1.34 +class SK_API SkXfermode : public SkFlattenable {
    1.35 +public:
    1.36 +    SK_DECLARE_INST_COUNT(SkXfermode)
    1.37 +
    1.38 +    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
    1.39 +                        const SkAlpha aa[]) const;
    1.40 +    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
    1.41 +                        const SkAlpha aa[]) const;
    1.42 +    virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
    1.43 +                        const SkAlpha aa[]) const;
    1.44 +
    1.45 +    /** Enum of possible coefficients to describe some xfermodes
    1.46 +     */
    1.47 +    enum Coeff {
    1.48 +        kZero_Coeff,    /** 0 */
    1.49 +        kOne_Coeff,     /** 1 */
    1.50 +        kSC_Coeff,      /** src color */
    1.51 +        kISC_Coeff,     /** inverse src color (i.e. 1 - sc) */
    1.52 +        kDC_Coeff,      /** dst color */
    1.53 +        kIDC_Coeff,     /** inverse dst color (i.e. 1 - dc) */
    1.54 +        kSA_Coeff,      /** src alpha */
    1.55 +        kISA_Coeff,     /** inverse src alpha (i.e. 1 - sa) */
    1.56 +        kDA_Coeff,      /** dst alpha */
    1.57 +        kIDA_Coeff,     /** inverse dst alpha (i.e. 1 - da) */
    1.58 +
    1.59 +        kCoeffCount
    1.60 +    };
    1.61 +
    1.62 +    /** If the xfermode can be expressed as an equation using the coefficients
    1.63 +        in Coeff, then asCoeff() returns true, and sets (if not null) src and
    1.64 +        dst accordingly.
    1.65 +
    1.66 +            result = src_coeff * src_color + dst_coeff * dst_color;
    1.67 +
    1.68 +        As examples, here are some of the porterduff coefficients
    1.69 +
    1.70 +        MODE        SRC_COEFF       DST_COEFF
    1.71 +        clear       zero            zero
    1.72 +        src         one             zero
    1.73 +        dst         zero            one
    1.74 +        srcover     one             isa
    1.75 +        dstover     ida             one
    1.76 +     */
    1.77 +    virtual bool asCoeff(Coeff* src, Coeff* dst) const;
    1.78 +
    1.79 +    /**
    1.80 +     *  The same as calling xfermode->asCoeff(..), except that this also checks
    1.81 +     *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
    1.82 +     */
    1.83 +    static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst);
    1.84 +
    1.85 +    /** List of predefined xfermodes.
    1.86 +        The algebra for the modes uses the following symbols:
    1.87 +        Sa, Sc  - source alpha and color
    1.88 +        Da, Dc - destination alpha and color (before compositing)
    1.89 +        [a, c] - Resulting (alpha, color) values
    1.90 +        For these equations, the colors are in premultiplied state.
    1.91 +        If no xfermode is specified, kSrcOver is assumed.
    1.92 +        The modes are ordered by those that can be expressed as a pair of Coeffs, followed by those
    1.93 +        that aren't Coeffs but have separable r,g,b computations, and finally
    1.94 +        those that are not separable.
    1.95 +     */
    1.96 +    enum Mode {
    1.97 +        kClear_Mode,    //!< [0, 0]
    1.98 +        kSrc_Mode,      //!< [Sa, Sc]
    1.99 +        kDst_Mode,      //!< [Da, Dc]
   1.100 +        kSrcOver_Mode,  //!< [Sa + Da - Sa*Da, Rc = Sc + (1 - Sa)*Dc]
   1.101 +        kDstOver_Mode,  //!< [Sa + Da - Sa*Da, Rc = Dc + (1 - Da)*Sc]
   1.102 +        kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
   1.103 +        kDstIn_Mode,    //!< [Sa * Da, Sa * Dc]
   1.104 +        kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
   1.105 +        kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
   1.106 +        kSrcATop_Mode,  //!< [Da, Sc * Da + (1 - Sa) * Dc]
   1.107 +        kDstATop_Mode,  //!< [Sa, Sa * Dc + Sc * (1 - Da)]
   1.108 +        kXor_Mode,      //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
   1.109 +        kPlus_Mode,     //!< [Sa + Da, Sc + Dc]
   1.110 +        kModulate_Mode, // multiplies all components (= alpha and color)
   1.111 +
   1.112 +        // Following blend modes are defined in the CSS Compositing standard:
   1.113 +        // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
   1.114 +        kScreen_Mode,
   1.115 +        kLastCoeffMode = kScreen_Mode,
   1.116 +
   1.117 +        kOverlay_Mode,
   1.118 +        kDarken_Mode,
   1.119 +        kLighten_Mode,
   1.120 +        kColorDodge_Mode,
   1.121 +        kColorBurn_Mode,
   1.122 +        kHardLight_Mode,
   1.123 +        kSoftLight_Mode,
   1.124 +        kDifference_Mode,
   1.125 +        kExclusion_Mode,
   1.126 +        kMultiply_Mode,
   1.127 +        kLastSeparableMode = kMultiply_Mode,
   1.128 +
   1.129 +        kHue_Mode,
   1.130 +        kSaturation_Mode,
   1.131 +        kColor_Mode,
   1.132 +        kLuminosity_Mode,
   1.133 +        kLastMode = kLuminosity_Mode
   1.134 +    };
   1.135 +
   1.136 +    /**
   1.137 +     * Gets the name of the Mode as a string.
   1.138 +     */
   1.139 +    static const char* ModeName(Mode);
   1.140 +
   1.141 +    /**
   1.142 +     *  If the xfermode is one of the modes in the Mode enum, then asMode()
   1.143 +     *  returns true and sets (if not null) mode accordingly. Otherwise it
   1.144 +     *  returns false and ignores the mode parameter.
   1.145 +     */
   1.146 +    virtual bool asMode(Mode* mode) const;
   1.147 +
   1.148 +    /**
   1.149 +     *  The same as calling xfermode->asMode(mode), except that this also checks
   1.150 +     *  if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
   1.151 +     */
   1.152 +    static bool AsMode(const SkXfermode*, Mode* mode);
   1.153 +
   1.154 +    /**
   1.155 +     *  Returns true if the xfermode claims to be the specified Mode. This works
   1.156 +     *  correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
   1.157 +     *  you can say this without checking for a null...
   1.158 +     *
   1.159 +     *  If (SkXfermode::IsMode(paint.getXfermode(),
   1.160 +     *                         SkXfermode::kDstOver_Mode)) {
   1.161 +     *      ...
   1.162 +     *  }
   1.163 +     */
   1.164 +    static bool IsMode(const SkXfermode* xfer, Mode mode);
   1.165 +
   1.166 +    /** Return an SkXfermode object for the specified mode.
   1.167 +     */
   1.168 +    static SkXfermode* Create(Mode mode);
   1.169 +
   1.170 +    /** Return a function pointer to a routine that applies the specified
   1.171 +        porter-duff transfer mode.
   1.172 +     */
   1.173 +    static SkXfermodeProc GetProc(Mode mode);
   1.174 +
   1.175 +    /** Return a function pointer to a routine that applies the specified
   1.176 +        porter-duff transfer mode and srcColor to a 16bit device color. Note,
   1.177 +        if the mode+srcColor might return a non-opaque color, then there is not
   1.178 +        16bit proc, and this will return NULL.
   1.179 +      */
   1.180 +    static SkXfermodeProc16 GetProc16(Mode mode, SkColor srcColor);
   1.181 +
   1.182 +    /**
   1.183 +     *  If the specified mode can be represented by a pair of Coeff, then return
   1.184 +     *  true and set (if not NULL) the corresponding coeffs. If the mode is
   1.185 +     *  not representable as a pair of Coeffs, return false and ignore the
   1.186 +     *  src and dst parameters.
   1.187 +     */
   1.188 +    static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
   1.189 +
   1.190 +    SK_ATTR_DEPRECATED("use AsMode(...)")
   1.191 +    static bool IsMode(const SkXfermode* xfer, Mode* mode) {
   1.192 +        return AsMode(xfer, mode);
   1.193 +    }
   1.194 +
   1.195 +    /** A subclass may implement this factory function to work with the GPU backend. It is legal
   1.196 +        to call this with all params NULL to simply test the return value. If effect is non-NULL
   1.197 +        then the xfermode may optionally allocate an effect to return and the caller as *effect.
   1.198 +        The caller will install it and own a ref to it. Since the xfermode may or may not assign
   1.199 +        *effect, the caller should set *effect to NULL beforehand. background specifies the
   1.200 +        texture to use as the background for compositing, and should be accessed in the effect's
   1.201 +        fragment shader. If NULL, the effect should request access to destination color
   1.202 +        (setWillReadDstColor()), and use that in the fragment shader (builder->dstColor()).
   1.203 +     */
   1.204 +    virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background = NULL) const;
   1.205 +
   1.206 +    /** Returns true if the xfermode can be expressed as coeffs (src, dst), or as an effect
   1.207 +        (effect). This helper calls the asCoeff() and asNewEffect() virtuals. If the xfermode is
   1.208 +        NULL, it is treated as kSrcOver_Mode. It is legal to call this with all params NULL to
   1.209 +        simply test the return value.  effect, src, and dst must all be NULL or all non-NULL.
   1.210 +     */
   1.211 +    static bool AsNewEffectOrCoeff(SkXfermode*,
   1.212 +                                   GrEffectRef** effect,
   1.213 +                                   Coeff* src,
   1.214 +                                   Coeff* dst,
   1.215 +                                   GrTexture* background = NULL);
   1.216 +
   1.217 +    SK_TO_STRING_PUREVIRT()
   1.218 +    SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
   1.219 +    SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
   1.220 +
   1.221 +protected:
   1.222 +    SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
   1.223 +
   1.224 +    /** The default implementation of xfer32/xfer16/xferA8 in turn call this
   1.225 +        method, 1 color at a time (upscaled to a SkPMColor). The default
   1.226 +        implmentation of this method just returns dst. If performance is
   1.227 +        important, your subclass should override xfer32/xfer16/xferA8 directly.
   1.228 +
   1.229 +        This method will not be called directly by the client, so it need not
   1.230 +        be implemented if your subclass has overridden xfer32/xfer16/xferA8
   1.231 +    */
   1.232 +    virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
   1.233 +
   1.234 +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
   1.235 +public:
   1.236 +#endif
   1.237 +    SkXfermode() {}
   1.238 +
   1.239 +private:
   1.240 +    enum {
   1.241 +        kModeCount = kLastMode + 1
   1.242 +    };
   1.243 +
   1.244 +    friend class SkGraphics;
   1.245 +    static void Term();
   1.246 +
   1.247 +    typedef SkFlattenable INHERITED;
   1.248 +};
   1.249 +
   1.250 +///////////////////////////////////////////////////////////////////////////////
   1.251 +
   1.252 +/** \class SkProcXfermode
   1.253 +
   1.254 +    SkProcXfermode is a xfermode that applies the specified proc to its colors.
   1.255 +    This class is not exported to java.
   1.256 +*/
   1.257 +class SkProcXfermode : public SkXfermode {
   1.258 +public:
   1.259 +    static SkProcXfermode* Create(SkXfermodeProc proc) {
   1.260 +        return SkNEW_ARGS(SkProcXfermode, (proc));
   1.261 +    }
   1.262 +
   1.263 +    // overrides from SkXfermode
   1.264 +    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
   1.265 +                        const SkAlpha aa[]) const SK_OVERRIDE;
   1.266 +    virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
   1.267 +                        const SkAlpha aa[]) const SK_OVERRIDE;
   1.268 +    virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
   1.269 +                        const SkAlpha aa[]) const SK_OVERRIDE;
   1.270 +
   1.271 +    SK_TO_STRING_OVERRIDE()
   1.272 +    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode)
   1.273 +
   1.274 +protected:
   1.275 +    SkProcXfermode(SkReadBuffer&);
   1.276 +    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
   1.277 +
   1.278 +    // allow subclasses to update this after we unflatten
   1.279 +    void setProc(SkXfermodeProc proc) {
   1.280 +        fProc = proc;
   1.281 +    }
   1.282 +
   1.283 +    SkXfermodeProc getProc() const {
   1.284 +        return fProc;
   1.285 +    }
   1.286 +
   1.287 +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
   1.288 +public:
   1.289 +#endif
   1.290 +    SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {}
   1.291 +
   1.292 +private:
   1.293 +    SkXfermodeProc  fProc;
   1.294 +
   1.295 +    typedef SkXfermode INHERITED;
   1.296 +};
   1.297 +
   1.298 +#endif

mercurial