SkColorFilter.cpp revision 7191840eec5ac3b5f5814e4df3cf18264b0b0a4d
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
126b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com#include "SkUnPreMultiply.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.combool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) {
1543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    return false;
1643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
1743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
18e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.orgbool SkColorFilter::asColorMatrix(SkScalar matrix[20]) {
19e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org    return false;
20e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org}
21e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org
227191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.combool SkColorFilter::asComponentTable(SkBitmap*) {
237191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com    return false;
247191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com}
257191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com
26feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) {
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
280c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com    SkDEBUGFAIL("missing implementation of SkColorFilter::filterSpan16");
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
30feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    if (d != s) {
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(d, s, count * sizeof(uint16_t));
32feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    }
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
356b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.comSkColor SkColorFilter::filterColor(SkColor c) {
366b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com    SkPMColor dst, src = SkPreMultiplyColor(c);
376b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com    this->filterSpan(&src, 1, &dst);
386b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com    return SkUnPreMultiply::PMColorToColor(dst);
396b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com}
406b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com
416b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com///////////////////////////////////////////////////////////////////////////////
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader = shader;   shader->ref();
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFilter = filter;   filter->ref();
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFilterShader::SkFilterShader(SkFlattenableReadBuffer& buffer) :
49feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com        INHERITED(buffer) {
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader = static_cast<SkShader*>(buffer.readFlattenable());
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFilter = static_cast<SkColorFilter*>(buffer.readFlattenable());
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
54feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkFilterShader::~SkFilterShader() {
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFilter->unref();
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader->unref();
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
59feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkFilterShader::beginSession() {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::beginSession();
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader->beginSession();
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
64feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkFilterShader::endSession() {
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader->endSession();
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::endSession();
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
69feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkFilterShader::flatten(SkFlattenableWriteBuffer& buffer) {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::flatten(buffer);
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeFlattenable(fShader);
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    buffer.writeFlattenable(fFilter);
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
75feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comuint32_t SkFilterShader::getFlags() {
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t shaderF = fShader->getFlags();
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t filterF = fFilter->getFlags();
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // if the filter doesn't support 16bit, clear the matching bit in the shader
80feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    if (!(filterF & SkColorFilter::kHasFilter16_Flag)) {
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        shaderF &= ~SkShader::kHasSpan16_Flag;
82feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    }
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // if the filter might change alpha, clear the opaque flag in the shader
84feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag);
86feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com    }
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return shaderF;
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkFilterShader::setContext(const SkBitmap& device,
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                const SkPaint& paint,
92feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com                                const SkMatrix& matrix) {
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return  this->INHERITED::setContext(device, paint, matrix) &&
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fShader->setContext(device, paint, matrix);
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
97feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkFilterShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader->shadeSpan(x, y, result, count);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFilter->filterSpan(result, count, result);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
102feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comvoid SkFilterShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fShader->getFlags() & SkShader::kHasSpan16_Flag);
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fShader->shadeSpan16(x, y, result, count);
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFilter->filterSpan16(result, count, result);
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
110