xref: /aosp_15_r20/external/skia/src/core/SkColorFilter.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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