/* * Copyright 2013 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkFilterShader.h" #include "SkColorFilter.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkShader.h" #include "SkString.h" SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) { fShader = shader; shader->ref(); fFilter = filter; filter->ref(); } SkFilterShader::~SkFilterShader() { fFilter->unref(); fShader->unref(); } SkFlattenable* SkFilterShader::CreateProc(SkReadBuffer& buffer) { SkAutoTUnref shader(buffer.readShader()); SkAutoTUnref filter(buffer.readColorFilter()); if (!shader.get() || !filter.get()) { return nullptr; } return new SkFilterShader(shader, filter); } void SkFilterShader::flatten(SkWriteBuffer& buffer) const { buffer.writeFlattenable(fShader); buffer.writeFlattenable(fFilter); } uint32_t SkFilterShader::FilterShaderContext::getFlags() const { const SkFilterShader& filterShader = static_cast(fShader); uint32_t shaderF = fShaderContext->getFlags(); uint32_t filterF = filterShader.fFilter->getFlags(); // filters don't support 16bit, so clear the matching bit in the shader shaderF &= ~SkShader::kHasSpan16_Flag; // if the filter might change alpha, clear the opaque flag in the shader if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { shaderF &= ~SkShader::kOpaqueAlpha_Flag; } return shaderF; } SkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const { char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); if (nullptr == shaderContext) { return nullptr; } return new (storage) FilterShaderContext(*this, shaderContext, rec); } size_t SkFilterShader::contextSize() const { return sizeof(FilterShaderContext) + fShader->contextSize(); } SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader, SkShader::Context* shaderContext, const ContextRec& rec) : INHERITED(filterShader, rec) , fShaderContext(shaderContext) {} SkFilterShader::FilterShaderContext::~FilterShaderContext() { fShaderContext->~Context(); } void SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { const SkFilterShader& filterShader = static_cast(fShader); fShaderContext->shadeSpan(x, y, result, count); filterShader.fFilter->filterSpan(result, count, result); } #ifndef SK_IGNORE_TO_STRING void SkFilterShader::toString(SkString* str) const { str->append("SkFilterShader: ("); str->append("Shader: "); fShader->toString(str); str->append(" Filter: "); // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added this->INHERITED::toString(str); str->append(")"); } #endif