Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkLayerDrawLooper_DEFINED
      9 #define SkLayerDrawLooper_DEFINED
     10 
     11 #include "SkDrawLooper.h"
     12 #include "SkXfermode.h"
     13 
     14 struct SkPoint;
     15 
     16 class SK_API SkLayerDrawLooper : public SkDrawLooper {
     17 public:
     18     SK_DECLARE_INST_COUNT(SkLayerDrawLooper)
     19 
     20             SkLayerDrawLooper();
     21     virtual ~SkLayerDrawLooper();
     22 
     23     /**
     24      *  Bits specifies which aspects of the layer's paint should replace the
     25      *  corresponding aspects on the draw's paint.
     26      *  kEntirePaint_Bits means use the layer's paint completely.
     27      *  0 means ignore the layer's paint... except that LayerInfo's fFlagsMask
     28      *  and fColorMode are always applied.
     29      */
     30     enum Bits {
     31         kStyle_Bit      = 1 << 0,   //!< use this layer's Style/stroke settings
     32         kTextSkewX_Bit  = 1 << 1,   //!< use this layer's textskewx
     33         kPathEffect_Bit = 1 << 2,   //!< use this layer's patheffect
     34         kMaskFilter_Bit = 1 << 3,   //!< use this layer's maskfilter
     35         kShader_Bit     = 1 << 4,   //!< use this layer's shader
     36         kColorFilter_Bit = 1 << 5,  //!< use this layer's colorfilter
     37         kXfermode_Bit   = 1 << 6,   //!< use this layer's xfermode
     38 
     39         /**
     40          *  Use the layer's paint entirely, with these exceptions:
     41          *  - We never override the draw's paint's text_encoding, since that is
     42          *    used to interpret the text/len parameters in draw[Pos]Text.
     43          *  - Flags and Color are always computed using the LayerInfo's
     44          *    fFlagsMask and fColorMode.
     45          */
     46         kEntirePaint_Bits = -1
     47 
     48     };
     49     typedef int32_t BitFlags;
     50 
     51     /**
     52      *  Info for how to apply the layer's paint and offset.
     53      *
     54      *  fFlagsMask selects which flags in the layer's paint should be applied.
     55      *      result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
     56      *  In the extreme:
     57      *      If fFlagsMask is 0, we ignore all of the layer's flags
     58      *      If fFlagsMask is -1, we use all of the layer's flags
     59      *
     60      *  fColorMode controls how we compute the final color for the layer:
     61      *      The layer's paint's color is treated as the SRC
     62      *      The draw's paint's color is treated as the DST
     63      *      final-color = Mode(layers-color, draws-color);
     64      *  Any SkXfermode::Mode will work. Two common choices are:
     65      *      kSrc_Mode: to use the layer's color, ignoring the draw's
     66      *      kDst_Mode: to just keep the draw's color, ignoring the layer's
     67      */
     68     struct SK_API LayerInfo {
     69         uint32_t            fFlagsMask; // SkPaint::Flags
     70         BitFlags            fPaintBits;
     71         SkXfermode::Mode    fColorMode;
     72         SkVector            fOffset;
     73         bool                fPostTranslate; //!< applies to fOffset
     74 
     75         /**
     76          *  Initial the LayerInfo. Defaults to settings that will draw the
     77          *  layer with no changes: e.g.
     78          *      fPaintBits == 0
     79          *      fColorMode == kDst_Mode
     80          *      fOffset == (0, 0)
     81          */
     82         LayerInfo();
     83     };
     84 
     85     /**
     86      *  Call for each layer you want to add (from top to bottom).
     87      *  This returns a paint you can modify, but that ptr is only valid until
     88      *  the next call made to addLayer().
     89      */
     90     SkPaint* addLayer(const LayerInfo&);
     91 
     92     /**
     93      *  This layer will draw with the original paint, at the specified offset
     94      */
     95     void addLayer(SkScalar dx, SkScalar dy);
     96 
     97     /**
     98      *  This layer will with the original paint and no offset.
     99      */
    100     void addLayer() { this->addLayer(0, 0); }
    101 
    102     // overrides from SkDrawLooper
    103     virtual void init(SkCanvas*);
    104     virtual bool next(SkCanvas*, SkPaint* paint);
    105 
    106     SK_DEVELOPER_TO_STRING()
    107     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerDrawLooper)
    108 
    109 protected:
    110     SkLayerDrawLooper(SkFlattenableReadBuffer&);
    111     virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
    112 
    113 private:
    114     struct Rec {
    115         Rec*    fNext;
    116         SkPaint fPaint;
    117         LayerInfo fInfo;
    118 
    119         static Rec* Reverse(Rec*);
    120     };
    121     Rec*    fRecs;
    122     int     fCount;
    123 
    124     // state-machine during the init/next cycle
    125     Rec* fCurrRec;
    126 
    127     static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
    128 
    129     class MyRegistrar : public SkFlattenable::Registrar {
    130     public:
    131         MyRegistrar();
    132     };
    133 
    134     typedef SkDrawLooper INHERITED;
    135 };
    136 
    137 #endif
    138