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 17class SK_API SkColorFilter : public SkFlattenable { 18public: 19 /** 20 * If the filter can be represented by a source color plus Mode, this 21 * returns true, and sets (if not NULL) the color and mode appropriately. 22 * If not, this returns false and ignores the parameters. 23 */ 24 virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode); 25 26 /** 27 * If the filter can be represented by a 5x4 matrix, this 28 * returns true, and sets the matrix appropriately. 29 * If not, this returns false and ignores the parameter. 30 */ 31 virtual bool asColorMatrix(SkScalar matrix[20]); 32 33 /** 34 * If the filter can be represented by per-component table, return true, 35 * and if table is not null, copy the bitmap containing the table into it. 36 * 37 * The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding 38 * to each component in ARGB order. e.g. row[0] == alpha, row[1] == red, 39 * etc. To transform a color, you (logically) perform the following: 40 * 41 * a' = *table.getAddr8(a, 0); 42 * r' = *table.getAddr8(r, 1); 43 * g' = *table.getAddr8(g, 2); 44 * b' = *table.getAddr8(b, 3); 45 * 46 * The original component value is the horizontal index for a given row, 47 * and the stored value at that index is the new value for that component. 48 */ 49 virtual bool asComponentTable(SkBitmap* table); 50 51 /** Called with a scanline of colors, as if there was a shader installed. 52 The implementation writes out its filtered version into result[]. 53 Note: shader and result may be the same buffer. 54 @param src array of colors, possibly generated by a shader 55 @param count the number of entries in the src[] and result[] arrays 56 @param result written by the filter 57 */ 58 virtual void filterSpan(const SkPMColor src[], int count, 59 SkPMColor result[]) = 0; 60 /** Called with a scanline of colors, as if there was a shader installed. 61 The implementation writes out its filtered version into result[]. 62 Note: shader and result may be the same buffer. 63 @param src array of colors, possibly generated by a shader 64 @param count the number of entries in the src[] and result[] arrays 65 @param result written by the filter 66 */ 67 virtual void filterSpan16(const uint16_t shader[], int count, 68 uint16_t result[]); 69 70 enum Flags { 71 /** If set the filter methods will not change the alpha channel of the 72 colors. 73 */ 74 kAlphaUnchanged_Flag = 0x01, 75 /** If set, this subclass implements filterSpan16(). If this flag is 76 set, then kAlphaUnchanged_Flag must also be set. 77 */ 78 kHasFilter16_Flag = 0x02 79 }; 80 81 /** Returns the flags for this filter. Override in subclasses to return 82 custom flags. 83 */ 84 virtual uint32_t getFlags() { return 0; } 85 86 /** 87 * Apply this colorfilter to the specified SkColor. This routine handles 88 * converting to SkPMColor, calling the filter, and then converting back 89 * to SkColor. This method is not virtual, but will call filterSpan() 90 * which is virtual. 91 */ 92 SkColor filterColor(SkColor); 93 94 95 /** Create a colorfilter that uses the specified color and mode. 96 If the Mode is DST, this function will return NULL (since that 97 mode will have no effect on the result). 98 @param c The source color used with the specified mode 99 @param mode The xfermode mode that is applied to each color in 100 the colorfilter's filterSpan[16,32] methods 101 @return colorfilter object that applies the src color and mode, 102 or NULL if the mode will have no effect. 103 */ 104 static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode); 105 106 /** Create a colorfilter that calls through to the specified procs to 107 filter the colors. The SkXfermodeProc parameter must be non-null, but 108 the SkXfermodeProc16 is optional, and may be null. 109 */ 110 static SkColorFilter* CreateProcFilter(SkColor srcColor, 111 SkXfermodeProc proc, 112 SkXfermodeProc16 proc16 = NULL); 113 114 /** Create a colorfilter that multiplies the RGB channels by one color, and 115 then adds a second color, pinning the result for each component to 116 [0..255]. The alpha components of the mul and add arguments 117 are ignored. 118 */ 119 static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add); 120 121 SK_DECLARE_FLATTENABLE_REGISTRAR() 122protected: 123 SkColorFilter() {} 124 SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {} 125 126private: 127 typedef SkFlattenable INHERITED; 128}; 129 130#include "SkShader.h" 131 132class SkFilterShader : public SkShader { 133public: 134 SkFilterShader(SkShader* shader, SkColorFilter* filter); 135 virtual ~SkFilterShader(); 136 137 // override 138 virtual uint32_t getFlags(); 139 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 140 const SkMatrix& matrix); 141 virtual void shadeSpan(int x, int y, SkPMColor result[], int count); 142 virtual void shadeSpan16(int x, int y, uint16_t result[], int count); 143 virtual void beginSession(); 144 virtual void endSession(); 145 146protected: 147 SkFilterShader(SkFlattenableReadBuffer& ); 148 virtual void flatten(SkFlattenableWriteBuffer& ) SK_OVERRIDE; 149 virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 150private: 151 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 152 return SkNEW_ARGS(SkFilterShader, (buffer)); } 153 SkShader* fShader; 154 SkColorFilter* fFilter; 155 156 typedef SkShader INHERITED; 157}; 158 159#endif 160