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