SkColorFilterImageFilter.cpp revision 8a8d841d485ff36b64d838575eb3735c1ddcf929
144888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org/*
244888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org * Copyright 2012 The Android Open Source Project
344888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org *
444888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
544888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org * found in the LICENSE file.
644888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org */
744888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
844888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org#include "SkColorFilterImageFilter.h"
944888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org#include "SkBitmap.h"
1044888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org#include "SkCanvas.h"
118d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org#include "SkColorMatrixFilter.h"
1244888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org#include "SkDevice.h"
1344888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org#include "SkColorFilter.h"
148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
15c12b74dc413ef024b13e0ed478491c4b1bafe6b1cwallez#include "SkTableColorFilter.h"
168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
1744888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
18cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.orgSkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
195e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
209bde31e95ddd82a4a923275bb01265740407dab1sugoi    if (NULL == cf) {
219bde31e95ddd82a4a923275bb01265740407dab1sugoi        return NULL;
229bde31e95ddd82a4a923275bb01265740407dab1sugoi    }
23c12b74dc413ef024b13e0ed478491c4b1bafe6b1cwallez
24cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.org    SkColorFilter* inputColorFilter;
258a8d841d485ff36b64d838575eb3735c1ddcf929reed    if (input && input->asColorFilter(&inputColorFilter)) {
26a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com        SkAutoUnref autoUnref(inputColorFilter);
278a8d841d485ff36b64d838575eb3735c1ddcf929reed        SkAutoTUnref<SkColorFilter> newCF(cf->newComposed(inputColorFilter));
288a8d841d485ff36b64d838575eb3735c1ddcf929reed        if (newCF) {
29c12b74dc413ef024b13e0ed478491c4b1bafe6b1cwallez            return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
30c12b74dc413ef024b13e0ed478491c4b1bafe6b1cwallez        }
31cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.org    }
32c12b74dc413ef024b13e0ed478491c4b1bafe6b1cwallez
335e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco    return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID));
34cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.org}
35cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.org
36194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.orgSkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf,
375e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
389bde31e95ddd82a4a923275bb01265740407dab1sugoi    : INHERITED(1, &input, cropRect, uniqueID), fColorFilter(SkRef(cf)) {
3944888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org}
4044888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
43f0f6c405fe9646be224128fc1dd24c7fc15246efreed    SkAutoTUnref<SkColorFilter> cf(buffer.readColorFilter());
445e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco    return Create(cf, common.getInput(0), &common.cropRect(), common.uniqueID());
459fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed}
4644888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
478b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
4844888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    this->INHERITED::flatten(buffer);
4944888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    buffer.writeFlattenable(fColorFilter);
5044888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org}
5144888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
5244888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.orgSkColorFilterImageFilter::~SkColorFilterImageFilter() {
539bde31e95ddd82a4a923275bb01265740407dab1sugoi    fColorFilter->unref();
5444888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org}
5544888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
5644888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.orgbool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
574cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                                             const Context& ctx,
5844888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org                                             SkBitmap* result,
59ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                                             SkIPoint* offset) const {
6068400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org    SkBitmap src = source;
616776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    SkIPoint srcOffset = SkIPoint::Make(0, 0);
624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) {
6368400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org        return false;
6468400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org    }
6568400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org
66194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org    SkIRect bounds;
67118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org    if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
68194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org        return false;
69194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org    }
70194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org
711f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
72cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org    if (NULL == device.get()) {
73cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org        return false;
74cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org    }
7544888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    SkCanvas canvas(device.get());
7644888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    SkPaint paint;
7744888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
7844888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
79cd9f55989e680b7f52fa21766dde0ac67ac9911fsenorblanco@chromium.org    paint.setColorFilter(fColorFilter);
806776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    canvas.drawSprite(src, srcOffset.fX - bounds.fLeft, srcOffset.fY - bounds.fTop, &paint);
8144888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org
8244888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    *result = device.get()->accessBitmap(false);
836776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    offset->fX = bounds.fLeft;
846776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    offset->fY = bounds.fTop;
8544888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org    return true;
8644888c66d4bf03da58eb9fbd3db92eb477141aabsenorblanco@chromium.org}
878d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org
88a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.combool SkColorFilterImageFilter::asColorFilter(SkColorFilter** filter) const {
89b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    if (!cropRectIsSet()) {
90194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org        if (filter) {
91194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org            *filter = fColorFilter;
92194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org            fColorFilter->ref();
93194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org        }
94194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org        return true;
95a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com    }
96194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org    return false;
978d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org}
98f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
99f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING
100f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkColorFilterImageFilter::toString(SkString* str) const {
101f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->appendf("SkColorFilterImageFilter: (");
102f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
10333cca886b757ed575136a628b30e845096ef94a3robertphillips    str->appendf("input: (");
10433cca886b757ed575136a628b30e845096ef94a3robertphillips
10533cca886b757ed575136a628b30e845096ef94a3robertphillips    if (this->getInput(0)) {
10633cca886b757ed575136a628b30e845096ef94a3robertphillips        this->getInput(0)->toString(str);
10733cca886b757ed575136a628b30e845096ef94a3robertphillips    }
10833cca886b757ed575136a628b30e845096ef94a3robertphillips
10933cca886b757ed575136a628b30e845096ef94a3robertphillips    str->appendf(") color filter: ");
110f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    fColorFilter->toString(str);
111f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
112f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->append(")");
113f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips}
114f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif
115