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 #include "include/core/SkColorFilter.h"
8
9 #include "include/core/SkAlphaType.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkFlattenable.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/private/SkColorData.h"
15 #include "include/private/base/SkTPin.h"
16 #include "modules/skcms/skcms.h"
17 #include "src/core/SkColorFilterPriv.h"
18 #include "src/core/SkColorSpaceXformSteps.h"
19 #include "src/effects/colorfilters/SkColorFilterBase.h"
20
21 #include <cstddef>
22
23 enum class SkBlendMode;
24 struct SkDeserialProcs;
25
asAColorMode(SkColor * color,SkBlendMode * mode) const26 bool SkColorFilter::asAColorMode(SkColor* color, SkBlendMode* mode) const {
27 return as_CFB(this)->onAsAColorMode(color, mode);
28 }
29
asAColorMatrix(float matrix[20]) const30 bool SkColorFilter::asAColorMatrix(float matrix[20]) const {
31 return as_CFB(this)->onAsAColorMatrix(matrix);
32 }
33
isAlphaUnchanged() const34 bool SkColorFilter::isAlphaUnchanged() const {
35 return as_CFB(this)->onIsAlphaUnchanged();
36 }
37
Deserialize(const void * data,size_t size,const SkDeserialProcs * procs)38 sk_sp<SkColorFilter> SkColorFilter::Deserialize(const void* data, size_t size,
39 const SkDeserialProcs* procs) {
40 return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>(
41 SkFlattenable::Deserialize(
42 kSkColorFilter_Type, data, size, procs).release()));
43 }
44
filterColor4f(const SkColor4f & origSrcColor,SkColorSpace * srcCS,SkColorSpace * dstCS) const45 SkColor4f SkColorFilter::filterColor4f(const SkColor4f& origSrcColor, SkColorSpace* srcCS,
46 SkColorSpace* dstCS) const {
47 SkPMColor4f color = { origSrcColor.fR, origSrcColor.fG, origSrcColor.fB, origSrcColor.fA };
48 SkColorSpaceXformSteps(srcCS, kUnpremul_SkAlphaType,
49 dstCS, kPremul_SkAlphaType).apply(color.vec());
50
51 SkPMColor4f filteredColor = as_CFB(this)->onFilterColor4f(color, dstCS);
52 // SkColor4f will assert if we allow alpha outside [0,1]. (SkSL color filters might do this).
53 filteredColor.fA = SkTPin(filteredColor.fA, 0.0f, 1.0f);
54 return filteredColor.unpremul();
55 }
56
makeWithWorkingColorSpace(sk_sp<SkColorSpace> workingSpace) const57 sk_sp<SkColorFilter> SkColorFilter::makeWithWorkingColorSpace(
58 sk_sp<SkColorSpace> workingSpace) const {
59 SkColorFilter* base = const_cast<SkColorFilter*>(this);
60 if (!workingSpace) {
61 return sk_ref_sp(base);
62 }
63
64 skcms_TransferFunction tf;
65 skcms_Matrix3x3 toXYZ;
66 workingSpace->transferFn(&tf);
67 workingSpace->toXYZD50(&toXYZ);
68 const SkAlphaType* kOriginalAlphaType = nullptr;
69 return SkColorFilterPriv::WithWorkingFormat(sk_ref_sp(base), &tf, &toXYZ, kOriginalAlphaType);
70 }
71