/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkArenaAlloc.h" #include "SkColorShader.h" #include "SkColorSpace.h" #include "SkColorSpacePriv.h" #include "SkColorSpaceXformSteps.h" #include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkUtils.h" SkColorShader::SkColorShader(SkColor c) : fColor(c) {} bool SkColorShader::isOpaque() const { return SkColorGetA(fColor) == 255; } sk_sp SkColorShader::CreateProc(SkReadBuffer& buffer) { return sk_make_sp(buffer.readColor()); } void SkColorShader::flatten(SkWriteBuffer& buffer) const { buffer.writeColor(fColor); } SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { if (info) { if (info->fColors && info->fColorCount >= 1) { info->fColors[0] = fColor; } info->fColorCount = 1; info->fTileMode = SkShader::kRepeat_TileMode; } return kColor_GradientType; } SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp space) : fColorSpace(std::move(space)) , fColor(color) {} sk_sp SkColor4Shader::CreateProc(SkReadBuffer& buffer) { SkColor4f color; sk_sp colorSpace; buffer.readColor4f(&color); if (buffer.readBool()) { sk_sp data = buffer.readByteArrayAsData(); colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr; } return SkShader::MakeColorShader(color, std::move(colorSpace)); } void SkColor4Shader::flatten(SkWriteBuffer& buffer) const { buffer.writeColor4f(fColor); sk_sp colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr; if (colorSpaceData) { buffer.writeBool(true); buffer.writeDataAsByteArray(colorSpaceData.get()); } else { buffer.writeBool(false); } } sk_sp SkColor4Shader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { SkColor4f color = fColor; SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, xformer->dst().get(), kUnpremul_SkAlphaType).apply(color.vec()); return SkShader::MakeColorShader(color.toSkColor()); } sk_sp SkShader::MakeColorShader(const SkColor4f& color, sk_sp space) { if (!SkScalarsAreFinite(color.vec(), 4)) { return nullptr; } return sk_make_sp(color, std::move(space)); } bool SkColorShader::onAppendStages(const StageRec& rec) const { SkColor4f color = SkColor4f::FromColor(fColor); SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType, rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); return true; } bool SkColor4Shader::onAppendStages(const StageRec& rec) const { SkColor4f color = fColor; SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); return true; } #if SK_SUPPORT_GPU #include "GrColorSpaceInfo.h" #include "GrColorSpaceXform.h" #include "SkGr.h" #include "effects/GrConstColorProcessor.h" std::unique_ptr SkColorShader::asFragmentProcessor( const GrFPArgs& args) const { SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorSpaceInfo); return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA); } std::unique_ptr SkColor4Shader::asFragmentProcessor( const GrFPArgs& args) const { SkColorSpaceXformSteps steps{ fColorSpace.get(), kUnpremul_SkAlphaType, args.fDstColorSpaceInfo->colorSpace(), kUnpremul_SkAlphaType }; SkColor4f color = fColor; steps.apply(color.vec()); return GrConstColorProcessor::Make(color.premul(), GrConstColorProcessor::InputMode::kModulateA); } #endif