Home | History | Annotate | Download | only in core
      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 SkColorFilter_DEFINED
     11 #define SkColorFilter_DEFINED
     12 
     13 #include "SkColor.h"
     14 #include "SkFlattenable.h"
     15 #include "SkXfermode.h"
     16 
     17 class SkBitmap;
     18 class GrEffectRef;
     19 class GrContext;
     20 
     21 /**
     22  *  ColorFilters are optional objects in the drawing pipeline. When present in
     23  *  a paint, they are called with the "src" colors, and return new colors, which
     24  *  are then passed onto the next stage (either ImageFilter or Xfermode).
     25  *
     26  *  All subclasses are required to be reentrant-safe : it must be legal to share
     27  *  the same instance between several threads.
     28  */
     29 class SK_API SkColorFilter : public SkFlattenable {
     30 public:
     31     SK_DECLARE_INST_COUNT(SkColorFilter)
     32 
     33     /**
     34      *  If the filter can be represented by a source color plus Mode, this
     35      *  returns true, and sets (if not NULL) the color and mode appropriately.
     36      *  If not, this returns false and ignores the parameters.
     37      */
     38     virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const;
     39 
     40     /**
     41      *  If the filter can be represented by a 5x4 matrix, this
     42      *  returns true, and sets the matrix appropriately.
     43      *  If not, this returns false and ignores the parameter.
     44      */
     45     virtual bool asColorMatrix(SkScalar matrix[20]) const;
     46 
     47     /**
     48      *  If the filter can be represented by per-component table, return true,
     49      *  and if table is not null, copy the bitmap containing the table into it.
     50      *
     51      *  The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
     52      *  to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
     53      *  etc. To transform a color, you (logically) perform the following:
     54      *
     55      *      a' = *table.getAddr8(a, 0);
     56      *      r' = *table.getAddr8(r, 1);
     57      *      g' = *table.getAddr8(g, 2);
     58      *      b' = *table.getAddr8(b, 3);
     59      *
     60      *  The original component value is the horizontal index for a given row,
     61      *  and the stored value at that index is the new value for that component.
     62      */
     63     virtual bool asComponentTable(SkBitmap* table) const;
     64 
     65     /** Called with a scanline of colors, as if there was a shader installed.
     66         The implementation writes out its filtered version into result[].
     67         Note: shader and result may be the same buffer.
     68         @param src      array of colors, possibly generated by a shader
     69         @param count    the number of entries in the src[] and result[] arrays
     70         @param result   written by the filter
     71     */
     72     virtual void filterSpan(const SkPMColor src[], int count,
     73                             SkPMColor result[]) const = 0;
     74     /** Called with a scanline of colors, as if there was a shader installed.
     75         The implementation writes out its filtered version into result[].
     76         Note: shader and result may be the same buffer.
     77         @param src      array of colors, possibly generated by a shader
     78         @param count    the number of entries in the src[] and result[] arrays
     79         @param result   written by the filter
     80     */
     81     virtual void filterSpan16(const uint16_t shader[], int count,
     82                               uint16_t result[]) const;
     83 
     84     enum Flags {
     85         /** If set the filter methods will not change the alpha channel of the
     86             colors.
     87         */
     88         kAlphaUnchanged_Flag = 0x01,
     89         /** If set, this subclass implements filterSpan16(). If this flag is
     90             set, then kAlphaUnchanged_Flag must also be set.
     91         */
     92         kHasFilter16_Flag    = 0x02
     93     };
     94 
     95     /** Returns the flags for this filter. Override in subclasses to return
     96         custom flags.
     97     */
     98     virtual uint32_t getFlags() const { return 0; }
     99 
    100     /**
    101      *  Apply this colorfilter to the specified SkColor. This routine handles
    102      *  converting to SkPMColor, calling the filter, and then converting back
    103      *  to SkColor. This method is not virtual, but will call filterSpan()
    104      *   which is virtual.
    105      */
    106     SkColor filterColor(SkColor) const;
    107 
    108     /** Create a colorfilter that uses the specified color and mode.
    109         If the Mode is DST, this function will return NULL (since that
    110         mode will have no effect on the result).
    111         @param c    The source color used with the specified mode
    112         @param mode The xfermode mode that is applied to each color in
    113                         the colorfilter's filterSpan[16,32] methods
    114         @return colorfilter object that applies the src color and mode,
    115                     or NULL if the mode will have no effect.
    116     */
    117     static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
    118 
    119     /** Create a colorfilter that multiplies the RGB channels by one color, and
    120         then adds a second color, pinning the result for each component to
    121         [0..255]. The alpha components of the mul and add arguments
    122         are ignored.
    123     */
    124     static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
    125 
    126     /** A subclass may implement this factory function to work with the GPU backend. If the return
    127         is non-NULL then the caller owns a ref on the returned object.
    128      */
    129     virtual GrEffectRef* asNewEffect(GrContext*) const;
    130 
    131     SK_TO_STRING_PUREVIRT()
    132 
    133     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
    134     SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter)
    135 
    136 protected:
    137     SkColorFilter() {}
    138     SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
    139 
    140 private:
    141     typedef SkFlattenable INHERITED;
    142 };
    143 
    144 #endif
    145