1 /* 2 * Copyright 2006 The Android Open Source Project 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 SkColorFilter_DEFINED 9 #define SkColorFilter_DEFINED 10 11 #include "include/core/SkBlendMode.h" 12 #include "include/core/SkColor.h" 13 #include "include/core/SkFlattenable.h" 14 #include "include/core/SkRefCnt.h" 15 16 class GrColorInfo; 17 class GrFragmentProcessor; 18 class GrRecordingContext; 19 class SkBitmap; 20 class SkColorMatrix; 21 class SkColorSpace; 22 struct SkStageRec; 23 class SkString; 24 25 /** 26 * ColorFilters are optional objects in the drawing pipeline. When present in 27 * a paint, they are called with the "src" colors, and return new colors, which 28 * are then passed onto the next stage (either ImageFilter or Xfermode). 29 * 30 * All subclasses are required to be reentrant-safe : it must be legal to share 31 * the same instance between several threads. 32 */ 33 class SK_API SkColorFilter : public SkFlattenable { 34 public: 35 // DEPRECATED. skbug.com/8941 36 asColorMode(SkColor * color,SkBlendMode * mode)37 bool asColorMode(SkColor* color, SkBlendMode* mode) const { 38 return this->onAsAColorMode(color, mode); 39 } 40 41 /** If the filter can be represented by a source color plus Mode, this 42 * returns true, and sets (if not NULL) the color and mode appropriately. 43 * If not, this returns false and ignores the parameters. 44 */ asAColorMode(SkColor * color,SkBlendMode * mode)45 bool asAColorMode(SkColor* color, SkBlendMode* mode) const { 46 return this->onAsAColorMode(color, mode); 47 } 48 49 /** If the filter can be represented by a 5x4 matrix, this 50 * returns true, and sets the matrix appropriately. 51 * If not, this returns false and ignores the parameter. 52 */ asAColorMatrix(float matrix[20])53 bool asAColorMatrix(float matrix[20]) const { 54 return this->onAsAColorMatrix(matrix); 55 } 56 57 bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const; 58 59 enum Flags { 60 /** If set the filter methods will not change the alpha channel of the colors. 61 */ 62 kAlphaUnchanged_Flag = 1 << 0, 63 }; 64 65 /** Returns the flags for this filter. Override in subclasses to return custom flags. 66 */ getFlags()67 virtual uint32_t getFlags() const { return 0; } 68 69 SkColor filterColor(SkColor) const; 70 71 /** 72 * Converts the src color (in src colorspace), into the dst colorspace, 73 * then applies this filter to it, returning the filtered color in the dst colorspace. 74 */ 75 SkColor4f filterColor4f(const SkColor4f& srcColor, SkColorSpace* srcCS, 76 SkColorSpace* dstCS) const; 77 78 /** Construct a colorfilter whose effect is to first apply the inner filter and then apply 79 * this filter, applied to the output of the inner filter. 80 * 81 * result = this(inner(...)) 82 * 83 * Due to internal limits, it is possible that this will return NULL, so the caller must 84 * always check. 85 */ 86 sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const; 87 88 #if SK_SUPPORT_GPU 89 /** 90 * A subclass may implement this factory function to work with the GPU backend. It returns 91 * a GrFragmentProcessor that implemets the color filter in GPU shader code. 92 * 93 * The fragment processor receives a premultiplied input color and produces a premultiplied 94 * output color. 95 * 96 * A null return indicates that the color filter isn't implemented for the GPU backend. 97 */ 98 virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor( 99 GrRecordingContext*, const GrColorInfo& dstColorInfo) const; 100 #endif 101 affectsTransparentBlack()102 bool affectsTransparentBlack() const { 103 return this->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT; 104 } 105 106 static void RegisterFlattenables(); 107 GetFlattenableType()108 static SkFlattenable::Type GetFlattenableType() { 109 return kSkColorFilter_Type; 110 } 111 getFlattenableType()112 SkFlattenable::Type getFlattenableType() const override { 113 return kSkColorFilter_Type; 114 } 115 116 static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size, 117 const SkDeserialProcs* procs = nullptr) { 118 return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>( 119 SkFlattenable::Deserialize( 120 kSkColorFilter_Type, data, size, procs).release())); 121 } 122 123 protected: SkColorFilter()124 SkColorFilter() {} 125 126 virtual bool onAsAColorMatrix(float[20]) const; 127 virtual bool onAsAColorMode(SkColor* color, SkBlendMode* bmode) const; 128 129 private: 130 /* 131 * Returns 1 if this is a single filter (not a composition of other filters), otherwise it 132 * reutrns the number of leaf-node filters in a composition. This should be the same value 133 * as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter. 134 * 135 * e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4 136 */ privateComposedFilterCount()137 virtual int privateComposedFilterCount() const { return 1; } 138 139 virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0; 140 141 friend class SkComposeColorFilter; 142 143 typedef SkFlattenable INHERITED; 144 }; 145 146 class SK_API SkColorFilters { 147 public: Compose(sk_sp<SkColorFilter> outer,sk_sp<SkColorFilter> inner)148 static sk_sp<SkColorFilter> Compose(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner) { 149 return outer ? outer->makeComposed(inner) : inner; 150 } 151 static sk_sp<SkColorFilter> Blend(SkColor c, SkBlendMode mode); 152 static sk_sp<SkColorFilter> Matrix(const SkColorMatrix&); 153 static sk_sp<SkColorFilter> Matrix(const float rowMajor[20]); 154 155 // A version of Matrix which operates in HSLA space instead of RGBA. 156 // I.e. HSLA-to-RGBA(Matrix(RGBA-to-HSLA(input))). 157 static sk_sp<SkColorFilter> HSLAMatrix(const float rowMajor[20]); 158 159 static sk_sp<SkColorFilter> LinearToSRGBGamma(); 160 static sk_sp<SkColorFilter> SRGBToLinearGamma(); 161 static sk_sp<SkColorFilter> Lerp(float t, sk_sp<SkColorFilter> dst, sk_sp<SkColorFilter> src); 162 163 private: 164 SkColorFilters() = delete; 165 }; 166 167 #endif 168