11c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org/*
21c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org * Copyright 2013 Google Inc.
31c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org *
41c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
51c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org * found in the LICENSE file.
61c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org */
71c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org
81c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org#include "SkComposeImageFilter.h"
940736abf74908dfed82567ba88432103c9a7e900robertphillips
108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
1140736abf74908dfed82567ba88432103c9a7e900robertphillips#include "SkSpecialImage.h"
128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
131c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org
14225db4441e0cb887d52c906e8bb39df506304b3erobertphillipssk_sp<SkImageFilter> SkComposeImageFilter::Make(sk_sp<SkImageFilter> outer,
15225db4441e0cb887d52c906e8bb39df506304b3erobertphillips                                                sk_sp<SkImageFilter> inner) {
16225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    if (!outer) {
17225db4441e0cb887d52c906e8bb39df506304b3erobertphillips        return inner;
18225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    }
19225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    if (!inner) {
20225db4441e0cb887d52c906e8bb39df506304b3erobertphillips        return outer;
21225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    }
22225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    sk_sp<SkImageFilter> inputs[2] = { std::move(outer), std::move(inner) };
23225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    return sk_sp<SkImageFilter>(new SkComposeImageFilter(inputs));
24225db4441e0cb887d52c906e8bb39df506304b3erobertphillips}
251c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org
26e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblancoSkRect SkComposeImageFilter::computeFastBounds(const SkRect& src) const {
27491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips    SkImageFilter* outer = this->getInput(0);
28491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips    SkImageFilter* inner = this->getInput(1);
295788faaa2ac4203827c68006b669e277d441e2e4ajuma
30e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco    return outer->computeFastBounds(inner->computeFastBounds(src));
315788faaa2ac4203827c68006b669e277d441e2e4ajuma}
325788faaa2ac4203827c68006b669e277d441e2e4ajuma
332302de920e5434809bd0e85b871a6e002856dfdbrobertphillipssk_sp<SkSpecialImage> SkComposeImageFilter::onFilterImage(SkSpecialImage* source,
342302de920e5434809bd0e85b871a6e002856dfdbrobertphillips                                                          const Context& ctx,
352302de920e5434809bd0e85b871a6e002856dfdbrobertphillips                                                          SkIPoint* offset) const {
3617a652017a0243c57c954662e08a7976b9990feejbroman    // The bounds passed to the inner filter must be filtered by the outer
3717a652017a0243c57c954662e08a7976b9990feejbroman    // filter, so that the inner filter produces the pixels that the outer
3817a652017a0243c57c954662e08a7976b9990feejbroman    // filter requires as input. This matters if the outer filter moves pixels.
3917a652017a0243c57c954662e08a7976b9990feejbroman    SkIRect innerClipBounds;
40491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips    innerClipBounds = this->getInput(0)->filterBounds(ctx.clipBounds(), ctx.ctm());
412a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman    Context innerContext(ctx.ctm(), innerClipBounds, ctx.cache(), ctx.outputProperties());
425788faaa2ac4203827c68006b669e277d441e2e4ajuma    SkIPoint innerOffset = SkIPoint::Make(0, 0);
432302de920e5434809bd0e85b871a6e002856dfdbrobertphillips    sk_sp<SkSpecialImage> inner(this->filterInput(1, source, innerContext, &innerOffset));
4440736abf74908dfed82567ba88432103c9a7e900robertphillips    if (!inner) {
4540736abf74908dfed82567ba88432103c9a7e900robertphillips        return nullptr;
4640736abf74908dfed82567ba88432103c9a7e900robertphillips    }
475788faaa2ac4203827c68006b669e277d441e2e4ajuma
485788faaa2ac4203827c68006b669e277d441e2e4ajuma    SkMatrix outerMatrix(ctx.ctm());
495788faaa2ac4203827c68006b669e277d441e2e4ajuma    outerMatrix.postTranslate(SkIntToScalar(-innerOffset.x()), SkIntToScalar(-innerOffset.y()));
50db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco    SkIRect clipBounds = ctx.clipBounds();
51db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco    clipBounds.offset(-innerOffset.x(), -innerOffset.y());
522a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman    Context outerContext(outerMatrix, clipBounds, ctx.cache(), ctx.outputProperties());
5340736abf74908dfed82567ba88432103c9a7e900robertphillips
5440736abf74908dfed82567ba88432103c9a7e900robertphillips    SkIPoint outerOffset = SkIPoint::Make(0, 0);
552302de920e5434809bd0e85b871a6e002856dfdbrobertphillips    sk_sp<SkSpecialImage> outer(this->filterInput(0, inner.get(), outerContext, &outerOffset));
5640736abf74908dfed82567ba88432103c9a7e900robertphillips    if (!outer) {
5740736abf74908dfed82567ba88432103c9a7e900robertphillips        return nullptr;
585788faaa2ac4203827c68006b669e277d441e2e4ajuma    }
595788faaa2ac4203827c68006b669e277d441e2e4ajuma
605788faaa2ac4203827c68006b669e277d441e2e4ajuma    *offset = innerOffset + outerOffset;
612302de920e5434809bd0e85b871a6e002856dfdbrobertphillips    return outer;
621c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org}
631c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org
64e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblancoSkIRect SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
65e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco                                             MapDirection direction) const {
6640736abf74908dfed82567ba88432103c9a7e900robertphillips    SkImageFilter* outer = this->getInput(0);
6740736abf74908dfed82567ba88432103c9a7e900robertphillips    SkImageFilter* inner = this->getInput(1);
681c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org
69e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco    return outer->filterBounds(inner->filterBounds(src, ctm, direction), ctm, direction);
709fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed}
719fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed
7260c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkComposeImageFilter::CreateProc(SkReadBuffer& buffer) {
739fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
7460c9b58b3214b0154c931656e91e39b230e987d8reed    return SkComposeImageFilter::Make(common.getInput(0), common.getInput(1));
751c4c9ef43747b42d2c31b5f17fe5e054fb3fee64commit-bot@chromium.org}
76f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
77f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING
78f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkComposeImageFilter::toString(SkString* str) const {
79f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    SkImageFilter* outer = getInput(0);
80f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    SkImageFilter* inner = getInput(1);
81f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
82f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->appendf("SkComposeImageFilter: (");
83f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
84f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->appendf("outer: ");
85f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    outer->toString(str);
86f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
87f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->appendf("inner: ");
88f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    inner->toString(str);
89f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips
90f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips    str->appendf(")");
91f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips}
92f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif
93