blob: 3651d7e61823266c0296b0e2724a5bcb68813307 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkColorFilter.h"
reed@google.com02f65f22012-08-06 21:20:05 +00009#include "SkFilterShader.h"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000010#include "SkFlattenableBuffers.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000011#include "SkShader.h"
reed@google.com6b7aee32011-04-19 18:36:09 +000012#include "SkUnPreMultiply.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013
robertphillips@google.com0456e0b2012-06-27 14:03:26 +000014SK_DEFINE_INST_COUNT(SkColorFilter)
15
reed@google.com43c50c82011-04-14 15:50:52 +000016bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) {
17 return false;
18}
19
senorblanco@chromium.orge5ff3ce2011-12-20 20:58:18 +000020bool SkColorFilter::asColorMatrix(SkScalar matrix[20]) {
21 return false;
22}
23
reed@google.com71918402012-01-05 17:24:35 +000024bool SkColorFilter::asComponentTable(SkBitmap*) {
25 return false;
26}
27
reed@google.comfeb8cc82011-04-19 20:11:25 +000028void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000029 SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
tomhudson@google.com0c00f212011-12-28 14:59:50 +000030 SkDEBUGFAIL("missing implementation of SkColorFilter::filterSpan16");
reed@android.com8a1c16f2008-12-17 15:59:43 +000031
reed@google.comfeb8cc82011-04-19 20:11:25 +000032 if (d != s) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000033 memcpy(d, s, count * sizeof(uint16_t));
reed@google.comfeb8cc82011-04-19 20:11:25 +000034 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000035}
36
reed@google.com6b7aee32011-04-19 18:36:09 +000037SkColor SkColorFilter::filterColor(SkColor c) {
38 SkPMColor dst, src = SkPreMultiplyColor(c);
39 this->filterSpan(&src, 1, &dst);
40 return SkUnPreMultiply::PMColorToColor(dst);
41}
42
bsalomon@google.com67e78c92012-10-17 13:36:14 +000043GrCustomStage* SkColorFilter::asNewCustomStage(GrContext*) const {
44 return NULL;
45}
46
reed@google.com6b7aee32011-04-19 18:36:09 +000047///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000048
reed@google.comfeb8cc82011-04-19 20:11:25 +000049SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000050 fShader = shader; shader->ref();
51 fFilter = filter; filter->ref();
52}
53
54SkFilterShader::SkFilterShader(SkFlattenableReadBuffer& buffer) :
reed@google.comfeb8cc82011-04-19 20:11:25 +000055 INHERITED(buffer) {
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000056 fShader = buffer.readFlattenableT<SkShader>();
57 fFilter = buffer.readFlattenableT<SkColorFilter>();
reed@android.com8a1c16f2008-12-17 15:59:43 +000058}
59
reed@google.comfeb8cc82011-04-19 20:11:25 +000060SkFilterShader::~SkFilterShader() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000061 fFilter->unref();
62 fShader->unref();
63}
64
reed@google.comfeb8cc82011-04-19 20:11:25 +000065void SkFilterShader::beginSession() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000066 this->INHERITED::beginSession();
67 fShader->beginSession();
68}
69
reed@google.comfeb8cc82011-04-19 20:11:25 +000070void SkFilterShader::endSession() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 fShader->endSession();
72 this->INHERITED::endSession();
73}
74
djsollen@google.com54924242012-03-29 15:18:04 +000075void SkFilterShader::flatten(SkFlattenableWriteBuffer& buffer) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000076 this->INHERITED::flatten(buffer);
77 buffer.writeFlattenable(fShader);
78 buffer.writeFlattenable(fFilter);
79}
80
reed@google.comfeb8cc82011-04-19 20:11:25 +000081uint32_t SkFilterShader::getFlags() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000082 uint32_t shaderF = fShader->getFlags();
83 uint32_t filterF = fFilter->getFlags();
rmistry@google.comfbfcd562012-08-23 18:09:54 +000084
reed@android.com8a1c16f2008-12-17 15:59:43 +000085 // if the filter doesn't support 16bit, clear the matching bit in the shader
reed@google.comfeb8cc82011-04-19 20:11:25 +000086 if (!(filterF & SkColorFilter::kHasFilter16_Flag)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000087 shaderF &= ~SkShader::kHasSpan16_Flag;
reed@google.comfeb8cc82011-04-19 20:11:25 +000088 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000089 // if the filter might change alpha, clear the opaque flag in the shader
reed@google.comfeb8cc82011-04-19 20:11:25 +000090 if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000091 shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag);
reed@google.comfeb8cc82011-04-19 20:11:25 +000092 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000093 return shaderF;
94}
95
96bool SkFilterShader::setContext(const SkBitmap& device,
97 const SkPaint& paint,
reed@google.comfeb8cc82011-04-19 20:11:25 +000098 const SkMatrix& matrix) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000099 return this->INHERITED::setContext(device, paint, matrix) &&
100 fShader->setContext(device, paint, matrix);
101}
102
reed@google.comfeb8cc82011-04-19 20:11:25 +0000103void SkFilterShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104 fShader->shadeSpan(x, y, result, count);
105 fFilter->filterSpan(result, count, result);
106}
107
reed@google.comfeb8cc82011-04-19 20:11:25 +0000108void SkFilterShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109 SkASSERT(fShader->getFlags() & SkShader::kHasSpan16_Flag);
110 SkASSERT(fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
111
112 fShader->shadeSpan16(x, y, result, count);
113 fFilter->filterSpan16(result, count, result);
114}
115