SkLayerDrawLooper.h revision 842292f10fc08bc8701114f7eec00944b6ea26d2
19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Copyright 2011 Google Inc.
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Use of this source code is governed by a BSD-style license that can be
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * found in the LICENSE file.
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifndef SkLayerDrawLooper_DEFINED
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SkLayerDrawLooper_DEFINED
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkDrawLooper.h"
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkPaint.h"
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkPoint.h"
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SkXfermode.h"
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallclass SK_API SkLayerDrawLooper : public SkDrawLooper {
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic:
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SK_DECLARE_INST_COUNT(SkLayerDrawLooper)
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            SkLayerDrawLooper();
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    virtual ~SkLayerDrawLooper();
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /**
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  Bits specifies which aspects of the layer's paint should replace the
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  corresponding aspects on the draw's paint.
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  kEntirePaint_Bits means use the layer's paint completely.
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  0 means ignore the layer's paint... except for fColorMode, which is
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  always applied.
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    enum Bits {
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kShader_Bit     = 1 << 4,   //!< use this layer's shader
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  Use the layer's paint entirely, with these exceptions:
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  - We never override the draw's paint's text_encoding, since that is
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *    used to interpret the text/len parameters in draw[Pos]Text.
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  - Color is always computed using the LayerInfo's fColorMode.
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         */
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        kEntirePaint_Bits = -1
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    };
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    typedef int32_t BitFlags;
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /**
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  Info for how to apply the layer's paint and offset.
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  fColorMode controls how we compute the final color for the layer:
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *      The layer's paint's color is treated as the SRC
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *      The draw's paint's color is treated as the DST
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *      final-color = Mode(layers-color, draws-color);
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  Any SkXfermode::Mode will work. Two common choices are:
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *      kSrc_Mode: to use the layer's color, ignoring the draw's
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *      kDst_Mode: to just keep the draw's color, ignoring the layer's
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    struct SK_API LayerInfo {
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        BitFlags            fPaintBits;
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkXfermode::Mode    fColorMode;
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkVector            fOffset;
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        bool                fPostTranslate; //!< applies to fOffset
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  Initial the LayerInfo. Defaults to settings that will draw the
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  layer with no changes: e.g.
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *      fPaintBits == 0
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *      fColorMode == kDst_Mode
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *      fOffset == (0, 0)
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         */
749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        LayerInfo();
759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    };
769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /**
789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  Call for each layer you want to add (from top to bottom).
799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  This returns a paint you can modify, but that ptr is only valid until
809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  the next call made to addLayer().
819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SkPaint* addLayer(const LayerInfo&);
839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /**
859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  This layer will draw with the original paint, at the specified offset
869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    void addLayer(SkScalar dx, SkScalar dy);
889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /**
909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     *  This layer will with the original paint and no offset.
919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    void addLayer() { this->addLayer(0, 0); }
939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /// Similar to addLayer, but adds a layer to the top.
959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SkPaint* addLayerOnTop(const LayerInfo&);
969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    // overrides from SkDrawLooper
989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    virtual void init(SkCanvas*);
999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    virtual bool next(SkCanvas*, SkPaint* paint);
1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SK_DEVELOPER_TO_STRING()
1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /// Implements Flattenable.
1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    static SkFlattenable* CreateProc(SkReadBuffer& buffer);
1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallprotected:
1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallprivate:
1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    struct Rec {
1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Rec*    fNext;
1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkPaint fPaint;
1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        LayerInfo fInfo;
1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    };
1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Rec*    fRecs;
1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Rec*    fTopRec;
1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    int     fCount;
1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    // state-machine during the init/next cycle
1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Rec* fCurrRec;
1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    class MyRegistrar : public SkFlattenable::Registrar {
1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    public:
1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        MyRegistrar();
1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    };
1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    typedef SkDrawLooper INHERITED;
1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic:
1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    class SK_API Builder {
1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    public:
1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Builder();
1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        ~Builder();
1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  Call for each layer you want to add (from top to bottom).
1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  This returns a paint you can modify, but that ptr is only valid until
1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  the next call made to addLayer().
1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         */
1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkPaint* addLayer(const LayerInfo&);
1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  This layer will draw with the original paint, at the specified offset
1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         */
1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        void addLayer(SkScalar dx, SkScalar dy);
1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         *  This layer will with the original paint and no offset.
1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall         */
1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        void addLayer() { this->addLayer(0, 0); }
1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /// Similar to addLayer, but adds a layer to the top.
1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkPaint* addLayerOnTop(const LayerInfo&);
1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        /**
1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall          * Pass list of layers on to newly built looper and return it. This will
1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall          * also reset the builder, so it can be used to build another looper.
1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall          */
1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SkLayerDrawLooper* detachLooper();
1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    private:
1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Rec* fRecs;
1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Rec* fTopRec;
1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        int  fCount;
1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    };
1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall};
1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall