120311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco/*
220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco * Copyright 2015 Google Inc.
320311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco *
420311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco * Use of this source code is governed by a BSD-style license that can be
520311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco * found in the LICENSE file.
620311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco */
720311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
820311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco#include "SkLocalMatrixImageFilter.h"
920311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco#include "SkReadBuffer.h"
102302de920e5434809bd0e85b871a6e002856dfdbrobertphillips#include "SkSpecialImage.h"
1120311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco#include "SkString.h"
1220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
13225db4441e0cb887d52c906e8bb39df506304b3erobertphillipssk_sp<SkImageFilter> SkLocalMatrixImageFilter::Make(const SkMatrix& localM,
14225db4441e0cb887d52c906e8bb39df506304b3erobertphillips                                                    sk_sp<SkImageFilter> input) {
15225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    if (!input) {
16225db4441e0cb887d52c906e8bb39df506304b3erobertphillips        return nullptr;
17225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    }
18225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    if (localM.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
19225db4441e0cb887d52c906e8bb39df506304b3erobertphillips        return nullptr;
20225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    }
21225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    if (localM.isIdentity()) {
22225db4441e0cb887d52c906e8bb39df506304b3erobertphillips        return input;
23225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    }
24225db4441e0cb887d52c906e8bb39df506304b3erobertphillips    return sk_sp<SkImageFilter>(new SkLocalMatrixImageFilter(localM, input));
25225db4441e0cb887d52c906e8bb39df506304b3erobertphillips}
26225db4441e0cb887d52c906e8bb39df506304b3erobertphillips
27372177ee115d46dfb5bfb881a408e6c37ae83678robertphillipsSkLocalMatrixImageFilter::SkLocalMatrixImageFilter(const SkMatrix& localM,
28372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips                                                   sk_sp<SkImageFilter> input)
29372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips    : INHERITED(&input, 1, nullptr)
30ae2f2de1b85e35824aab13f11e082920a33805adrobertphillips    , fLocalM(localM) {
31ae2f2de1b85e35824aab13f11e082920a33805adrobertphillips}
3220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
3360c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkLocalMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
3420311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
3520311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    SkMatrix lm;
3620311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    buffer.readMatrix(&lm);
3760c9b58b3214b0154c931656e91e39b230e987d8reed    return SkLocalMatrixImageFilter::Make(lm, common.getInput(0));
3820311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco}
3920311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
4020311d4843f25e6a3d9416456b18780ad5d9c1fasenorblancovoid SkLocalMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
4120311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    this->INHERITED::flatten(buffer);
4220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    buffer.writeMatrix(fLocalM);
4320311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco}
4420311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
452302de920e5434809bd0e85b871a6e002856dfdbrobertphillipssk_sp<SkSpecialImage> SkLocalMatrixImageFilter::onFilterImage(SkSpecialImage* source,
462302de920e5434809bd0e85b871a6e002856dfdbrobertphillips                                                              const Context& ctx,
472302de920e5434809bd0e85b871a6e002856dfdbrobertphillips                                                              SkIPoint* offset) const {
482a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman    Context localCtx(SkMatrix::Concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache(),
492a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman                     ctx.outputProperties());
50ae2f2de1b85e35824aab13f11e082920a33805adrobertphillips    return this->filterInput(0, source, localCtx, offset);
5120311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco}
5220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
53e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblancoSkIRect SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& matrix,
54e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco                                                 MapDirection direction) const {
55e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco    return this->getInput(0)->filterBounds(src, SkMatrix::Concat(matrix, fLocalM), direction);
5620311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco}
5720311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco
5820311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco#ifndef SK_IGNORE_TO_STRING
5920311d4843f25e6a3d9416456b18780ad5d9c1fasenorblancovoid SkLocalMatrixImageFilter::toString(SkString* str) const {
6020311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    str->append("SkLocalMatrixImageFilter: (");
6120311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco    str->append(")");
6220311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco}
6320311d4843f25e6a3d9416456b18780ad5d9c1fasenorblanco#endif
64