xref: /aosp_15_r20/external/skia/src/shaders/SkColorShader.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2016 Google Inc.
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 #include "src/shaders/SkColorShader.h"
9 
10 #include "include/core/SkAlphaType.h"
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkFlattenable.h"
14 #include "include/core/SkShader.h"
15 #include "include/private/base/SkFloatingPoint.h"
16 #include "include/private/base/SkTPin.h"
17 #include "src/core/SkColorSpacePriv.h"
18 #include "src/core/SkColorSpaceXformSteps.h"
19 #include "src/core/SkEffectPriv.h"
20 #include "src/core/SkRasterPipeline.h"
21 #include "src/core/SkReadBuffer.h"
22 #include "src/core/SkWriteBuffer.h"
23 #include "src/shaders/SkShaderBase.h"
24 
25 #include <utility>
26 
SkColorShader(SkColor c)27 SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
28 
isOpaque() const29 bool SkColorShader::isOpaque() const {
30     return SkColorGetA(fColor) == 255;
31 }
32 
CreateProc(SkReadBuffer & buffer)33 sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
34     return sk_make_sp<SkColorShader>(buffer.readColor());
35 }
36 
flatten(SkWriteBuffer & buffer) const37 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
38     buffer.writeColor(fColor);
39 }
40 
SkColor4Shader(const SkColor4f & color,sk_sp<SkColorSpace> space)41 SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
42     : fColorSpace(std::move(space))
43     , fColor({color.fR, color.fG, color.fB, SkTPin(color.fA, 0.0f, 1.0f)})
44 {}
45 
CreateProc(SkReadBuffer & buffer)46 sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
47     SkColor4f color;
48     sk_sp<SkColorSpace> colorSpace;
49     buffer.readColor4f(&color);
50     if (buffer.readBool()) {
51         sk_sp<SkData> data = buffer.readByteArrayAsData();
52         colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
53     }
54     return SkShaders::Color(color, std::move(colorSpace));
55 }
56 
flatten(SkWriteBuffer & buffer) const57 void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
58     buffer.writeColor4f(fColor);
59     sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr;
60     if (colorSpaceData) {
61         buffer.writeBool(true);
62         buffer.writeDataAsByteArray(colorSpaceData.get());
63     } else {
64         buffer.writeBool(false);
65     }
66 }
67 
appendStages(const SkStageRec & rec,const SkShaders::MatrixRec &) const68 bool SkColorShader::appendStages(const SkStageRec& rec, const SkShaders::MatrixRec&) const {
69     SkColor4f color = SkColor4f::FromColor(fColor);
70     SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
71                            rec.fDstCS,          kUnpremul_SkAlphaType).apply(color.vec());
72     rec.fPipeline->appendConstantColor(rec.fAlloc, color.premul().vec());
73     return true;
74 }
75 
appendStages(const SkStageRec & rec,const SkShaders::MatrixRec &) const76 bool SkColor4Shader::appendStages(const SkStageRec& rec, const SkShaders::MatrixRec&) const {
77     SkColor4f color = fColor;
78     SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
79                            rec.fDstCS,        kUnpremul_SkAlphaType).apply(color.vec());
80     rec.fPipeline->appendConstantColor(rec.fAlloc, color.premul().vec());
81     return true;
82 }
83 
onAsLuminanceColor(SkColor4f * lum) const84 bool SkColor4Shader::onAsLuminanceColor(SkColor4f* lum) const {
85     SkColor4f color = fColor;
86     SkColorSpaceXformSteps(fColorSpace.get(),   kUnpremul_SkAlphaType,
87                            sk_srgb_singleton(), kUnpremul_SkAlphaType).apply(color.vec());
88     *lum = color;
89     return true;
90 }
91 
92 /////////////////////////////////////////////////////////////////////////////////////////////////
93 
SkRegisterColor4ShaderFlattenable()94 void SkRegisterColor4ShaderFlattenable() {
95     SK_REGISTER_FLATTENABLE(SkColor4Shader);
96 }
97 
SkRegisterColorShaderFlattenable()98 void SkRegisterColorShaderFlattenable() {
99     SK_REGISTER_FLATTENABLE(SkColorShader);
100 }
101 
102 namespace SkShaders {
Color(SkColor color)103 sk_sp<SkShader> Color(SkColor color) { return sk_make_sp<SkColorShader>(color); }
104 
Color(const SkColor4f & color,sk_sp<SkColorSpace> space)105 sk_sp<SkShader> Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
106     if (!SkIsFinite(color.vec(), 4)) {
107         return nullptr;
108     }
109     return sk_make_sp<SkColor4Shader>(color, std::move(space));
110 }
111 }  // namespace SkShaders
112