SkColorFilter.cpp revision 7fbcfe97543b964fdc43156f9fa5d91220f2e4f7
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
8#include "SkColorFilter.h"
9#include "SkFilterShader.h"
10#include "SkFlattenableBuffers.h"
11#include "SkShader.h"
12#include "SkUnPreMultiply.h"
13#include "SkString.h"
14
15SK_DEFINE_INST_COUNT(SkColorFilter)
16
17bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
18    return false;
19}
20
21bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const {
22    return false;
23}
24
25bool SkColorFilter::asComponentTable(SkBitmap*) const {
26    return false;
27}
28
29void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) const {
30    SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
31    SkDEBUGFAIL("missing implementation of SkColorFilter::filterSpan16");
32
33    if (d != s) {
34        memcpy(d, s, count * sizeof(uint16_t));
35    }
36}
37
38SkColor SkColorFilter::filterColor(SkColor c) const {
39    SkPMColor dst, src = SkPreMultiplyColor(c);
40    this->filterSpan(&src, 1, &dst);
41    return SkUnPreMultiply::PMColorToColor(dst);
42}
43
44GrEffect* SkColorFilter::asNewEffect(GrContext*) const {
45    return NULL;
46}
47
48///////////////////////////////////////////////////////////////////////////////
49
50SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
51    fShader = shader;   shader->ref();
52    fFilter = filter;   filter->ref();
53}
54
55SkFilterShader::SkFilterShader(SkFlattenableReadBuffer& buffer) :
56        INHERITED(buffer) {
57    fShader = buffer.readFlattenableT<SkShader>();
58    fFilter = buffer.readFlattenableT<SkColorFilter>();
59}
60
61SkFilterShader::~SkFilterShader() {
62    fFilter->unref();
63    fShader->unref();
64}
65
66void SkFilterShader::flatten(SkFlattenableWriteBuffer& buffer) const {
67    this->INHERITED::flatten(buffer);
68    buffer.writeFlattenable(fShader);
69    buffer.writeFlattenable(fFilter);
70}
71
72uint32_t SkFilterShader::getFlags() {
73    uint32_t shaderF = fShader->getFlags();
74    uint32_t filterF = fFilter->getFlags();
75
76    // if the filter doesn't support 16bit, clear the matching bit in the shader
77    if (!(filterF & SkColorFilter::kHasFilter16_Flag)) {
78        shaderF &= ~SkShader::kHasSpan16_Flag;
79    }
80    // if the filter might change alpha, clear the opaque flag in the shader
81    if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
82        shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag);
83    }
84    return shaderF;
85}
86
87bool SkFilterShader::setContext(const SkBitmap& device,
88                                const SkPaint& paint,
89                                const SkMatrix& matrix) {
90    // we need to keep the setContext/endContext calls balanced. If we return
91    // false, our endContext() will not be called.
92
93    if (!this->INHERITED::setContext(device, paint, matrix)) {
94        return false;
95    }
96    if (!fShader->setContext(device, paint, matrix)) {
97        this->INHERITED::endContext();
98        return false;
99    }
100    return true;
101}
102
103void SkFilterShader::endContext() {
104    fShader->endContext();
105    this->INHERITED::endContext();
106}
107
108void SkFilterShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
109    fShader->shadeSpan(x, y, result, count);
110    fFilter->filterSpan(result, count, result);
111}
112
113void SkFilterShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
114    SkASSERT(fShader->getFlags() & SkShader::kHasSpan16_Flag);
115    SkASSERT(fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
116
117    fShader->shadeSpan16(x, y, result, count);
118    fFilter->filterSpan16(result, count, result);
119}
120
121#ifdef SK_DEVELOPER
122void SkFilterShader::toString(SkString* str) const {
123    str->append("SkFilterShader: (");
124
125    str->append("Shader: ");
126    fShader->toString(str);
127    str->append(" Filter: ");
128    // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
129
130    this->INHERITED::toString(str);
131
132    str->append(")");
133}
134#endif
135