11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkLayerDrawLooper_DEFINED
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkLayerDrawLooper_DEFINED
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDrawLooper.h"
1287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#include "SkXfermode.h"
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstruct SkPoint;
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerclass SK_API SkLayerDrawLooper : public SkDrawLooper {
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkLayerDrawLooper();
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual ~SkLayerDrawLooper();
2087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
2187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    /**
2287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  Bits specifies which aspects of the layer's paint should replace the
2387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  corresponding aspects on the draw's paint.
2487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  kEntirePaint_Bits means use the layer's paint completely.
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  0 means ignore the layer's paint... except that LayerInfo's fFlagsMask
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  and fColorMode are always applied.
2787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     */
2887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    enum Bits {
2987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
3087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
3187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
3287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
3387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kShader_Bit     = 1 << 4,   //!< use this layer's shader
3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode
3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        /**
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         *  Use the layer's paint entirely, with these exceptions:
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         *  - We never override the draw's paint's text_encoding, since that is
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         *    used to interpret the text/len parameters in draw[Pos]Text.
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         *  - Flags and Color are always computed using the LayerInfo's
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         *    fFlagsMask and fColorMode.
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         */
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kEntirePaint_Bits = -1,
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    };
4787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    typedef int32_t BitFlags;
4887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
4987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    /**
5087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  Info for how to apply the layer's paint and offset.
5187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *
5235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  fFlagsMask selects which flags in the layer's paint should be applied.
5335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *      result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
5435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  In the extreme:
5535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *      If fFlagsMask is 0, we ignore all of the layer's flags
5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *      If fFlagsMask is -1, we use all of the layer's flags
5735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *
5887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  fColorMode controls how we compute the final color for the layer:
5987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *      The layer's paint's color is treated as the SRC
6087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *      The draw's paint's color is treated as the DST
6187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *      final-color = Mode(layers-color, draws-color);
6287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  Any SkXfermode::Mode will work. Two common choices are:
6387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *      kSrc_Mode: to use the layer's color, ignoring the draw's
6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *      kDst_Mode: to just keep the draw's color, ignoring the layer's
6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     */
6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    struct SK_API LayerInfo {
6735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        uint32_t            fFlagsMask; // SkPaint::Flags
6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        BitFlags            fPaintBits;
6987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        SkXfermode::Mode    fColorMode;
7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        SkVector            fOffset;
7187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        bool                fPostTranslate; //!< applies to fOffset
7287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        /**
7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         *  Initial the LayerInfo. Defaults to settings that will draw the
7587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         *  layer with no changes: e.g.
7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         *      fPaintBits == 0
7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         *      fColorMode == kDst_Mode
7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         *      fOffset == (0, 0)
7987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger         */
8087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        LayerInfo();
8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    };
8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    /**
8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  Call for each layer you want to add (from top to bottom).
8587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     *  This returns a paint you can modify, but that ptr is only valid until
8635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  the next call made to addLayer().
8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger     */
8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    SkPaint* addLayer(const LayerInfo&);
8987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
9087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    /**
9135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  This layer will draw with the original paint, ad the specified offset
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project     */
9335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    void addLayer(SkScalar dx, SkScalar dy);
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    /**
9635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     *  This layer will with the original paint and no offset.
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project     */
9835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    void addLayer() { this->addLayer(0, 0); }
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // overrides from SkDrawLooper
10187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    virtual void init(SkCanvas*);
10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    virtual bool next(SkCanvas*, SkPaint* paint);
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // must be public for Registrar :(
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_DECLARE_FLATTENABLE_REGISTRAR()
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkLayerDrawLooper(SkFlattenableReadBuffer&);
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // overrides from SkFlattenable
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void flatten(SkFlattenableWriteBuffer& );
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual Factory getFactory() { return CreateProc; }
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    struct Rec {
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Rec*    fNext;
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkPaint fPaint;
12287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        LayerInfo fInfo;
12387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        static Rec* Reverse(Rec*);
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Rec*    fRecs;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int     fCount;
12887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
12987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    // state-machine during the init/next cycle
13087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    Rec* fCurrRec;
13187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
13235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
13387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class MyRegistrar : public SkFlattenable::Registrar {
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MyRegistrar();
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkDrawLooper INHERITED;
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
144