| Index: src/core/SkLocalMatrixImageFilter.cpp
|
| diff --git a/src/core/SkLocalMatrixImageFilter.cpp b/src/core/SkLocalMatrixImageFilter.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ff84f9d497620a07041d0116fd4ccc61176c5aca
|
| --- /dev/null
|
| +++ b/src/core/SkLocalMatrixImageFilter.cpp
|
| @@ -0,0 +1,256 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkImageFilter.h"
|
| +#include "SkReadBuffer.h"
|
| +#include "SkString.h"
|
| +
|
| +/**
|
| + * Wraps another imagefilter + matrix, such that using this filter will give the same result
|
| + * as using the wrapped filter with the matrix applied to its context.
|
| + */
|
| +class SkLocalMatrixImageFilter : public SkImageFilter {
|
| +public:
|
| + static SkImageFilter* Create(SkImageFilter* base, const SkMatrix& localM) {
|
| + if (localM.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
|
| + return nullptr;
|
| + }
|
| + if (localM.isIdentity()) {
|
| + // return SkRef(base);
|
| + }
|
| + return new SkLocalMatrixImageFilter(base, localM);
|
| + }
|
| +
|
| + void computeFastBounds(const SkRect&, SkRect*) const override;
|
| +
|
| + SK_TO_STRING_OVERRIDE()
|
| + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixImageFilter)
|
| +
|
| +protected:
|
| + bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const override;
|
| + bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
|
| + const SkIRect& bounds) const override;
|
| + bool affectsTransparentBlack() const override;
|
| + bool canComputeFastBounds() const override;
|
| +
|
| + void flatten(SkWriteBuffer&) const override;
|
| + bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
|
| + SkBitmap* result, SkIPoint* offset) const override;
|
| + bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const override;
|
| + bool canFilterImageGPU() const override;
|
| + bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
| + SkBitmap* result, SkIPoint* offset) const override;
|
| + bool usesSrcInput() const override;
|
| +
|
| + bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset,
|
| + SkIRect* bounds) const override;
|
| + bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src,
|
| + SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* result) const override;
|
| +
|
| +private:
|
| + SkLocalMatrixImageFilter(SkImageFilter* base, const SkMatrix& localM)
|
| + : INHERITED(0, nullptr), fBase(SkRef(base)), fLocalM(localM)
|
| + {}
|
| +
|
| + SkAutoTUnref<SkImageFilter> fBase;
|
| + SkMatrix fLocalM;
|
| +
|
| + typedef SkImageFilter INHERITED;
|
| +};
|
| +
|
| +static SkMatrix concat(const SkMatrix& a, const SkMatrix& b) {
|
| + SkMatrix c;
|
| + c.setConcat(a, b);
|
| + return c;
|
| +}
|
| +
|
| +SkFlattenable* SkLocalMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
|
| + SkMatrix lm;
|
| + buffer.readMatrix(&lm);
|
| + SkAutoTUnref<SkImageFilter> filter(buffer.readImageFilter());
|
| + if (!filter) {
|
| + return nullptr;
|
| + }
|
| + return SkLocalMatrixImageFilter::Create(filter, lm);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::onIsColorFilterNode(SkColorFilter** filterPtr) const {
|
| + return fBase->onIsColorFilterNode(filterPtr);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::asFragmentProcessor(GrFragmentProcessor** procs, GrTexture* tex,
|
| + const SkMatrix& matrix,
|
| + const SkIRect& bounds) const {
|
| + return fBase->asFragmentProcessor(procs, tex, concat(matrix, fLocalM), bounds);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::affectsTransparentBlack() const {
|
| + return fBase->affectsTransparentBlack();
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::canComputeFastBounds() const {
|
| + return fBase->canComputeFastBounds();
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::usesSrcInput() const {
|
| + return fBase->usesSrcInput();
|
| +}
|
| +
|
| +void SkLocalMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
|
| + buffer.writeMatrix(fLocalM);
|
| + buffer.writeFlattenable(fBase);
|
| +}
|
| +
|
| +void SkLocalMatrixImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
|
| + fBase->computeFastBounds(src, dst);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
| + SkBitmap* result, SkIPoint* offset) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return fBase->onFilterImage(proxy, src, localCtx, result, offset);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& matrix,
|
| + SkIRect* dst) const {
|
| + return fBase->onFilterBounds(src, concat(matrix, fLocalM), dst);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::canFilterImageGPU() const {
|
| + return fBase->canFilterImageGPU();
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
| + SkBitmap* result, SkIPoint* offset) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return fBase->filterImageGPU(proxy, src, localCtx, result, offset);
|
| +}
|
| +
|
| +#ifndef SK_IGNORE_TO_STRING
|
| +void SkLocalMatrixImageFilter::toString(SkString* str) const {
|
| + str->append("SkLocalMatrixImageFilter: (");
|
| + fBase->toString(str);
|
| + str->append(")");
|
| +}
|
| +#endif
|
| +
|
| +bool SkLocalMatrixImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
|
| + const SkIPoint& srcOffset, SkIRect* bounds) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return fBase->applyCropRect(localCtx, src, srcOffset, bounds);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
|
| + SkIPoint* srcOffset, SkIRect* bounds,
|
| + SkBitmap* result) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return fBase->applyCropRect(localCtx, proxy, src, srcOffset, bounds, result);
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +class SkLocalMatrixImageFilterAsInput : public SkImageFilter {
|
| +public:
|
| + static SkImageFilter* Create(SkImageFilter* base, const SkMatrix& localM) {
|
| + if (localM.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) {
|
| + return nullptr;
|
| + }
|
| + if (localM.isIdentity()) {
|
| + // return SkRef(base);
|
| + }
|
| + return new SkLocalMatrixImageFilterAsInput(base, localM);
|
| + }
|
| +
|
| + SK_TO_STRING_OVERRIDE()
|
| + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixImageFilterAsInput)
|
| +
|
| +protected:
|
| + bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
|
| + const SkIRect& bounds) const override;
|
| +
|
| + void flatten(SkWriteBuffer&) const override;
|
| + bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
|
| + SkBitmap* result, SkIPoint* offset) const override;
|
| + bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const override;
|
| +
|
| + bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset,
|
| + SkIRect* bounds) const override;
|
| + bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src,
|
| + SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* result) const override;
|
| +
|
| +private:
|
| + SkLocalMatrixImageFilterAsInput(SkImageFilter* base, const SkMatrix& localM)
|
| + : INHERITED(1, &base, nullptr), fLocalM(localM)
|
| + {}
|
| +
|
| + SkMatrix fLocalM;
|
| +
|
| + typedef SkImageFilter INHERITED;
|
| +};
|
| +
|
| +SkFlattenable* SkLocalMatrixImageFilterAsInput::CreateProc(SkReadBuffer& buffer) {
|
| + SkMatrix lm;
|
| + buffer.readMatrix(&lm);
|
| + SkAutoTUnref<SkImageFilter> filter(buffer.readImageFilter());
|
| + if (!filter) {
|
| + return nullptr;
|
| + }
|
| + return SkLocalMatrixImageFilter::Create(filter, lm);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilterAsInput::asFragmentProcessor(GrFragmentProcessor** procs,
|
| + GrTexture* tex, const SkMatrix& matrix,
|
| + const SkIRect& bounds) const {
|
| + return this->INHERITED::asFragmentProcessor(procs, tex, concat(matrix, fLocalM), bounds);
|
| +}
|
| +
|
| +void SkLocalMatrixImageFilterAsInput::flatten(SkWriteBuffer& buffer) const {
|
| + buffer.writeMatrix(fLocalM);
|
| + this->INHERITED::flatten(buffer);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilterAsInput::onFilterImage(Proxy* proxy, const SkBitmap& src,
|
| + const Context& ctx, SkBitmap* result,
|
| + SkIPoint* offset) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return this->INHERITED::onFilterImage(proxy, src, localCtx, result, offset);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilterAsInput::onFilterBounds(const SkIRect& src, const SkMatrix& matrix,
|
| + SkIRect* dst) const {
|
| + return this->INHERITED::onFilterBounds(src, concat(matrix, fLocalM), dst);
|
| +}
|
| +
|
| +#ifndef SK_IGNORE_TO_STRING
|
| +void SkLocalMatrixImageFilterAsInput::toString(SkString* str) const {
|
| + str->append("SkLocalMatrixImageFilterAsInput: (");
|
| + this->getInput(0)->toString(str);
|
| + str->append(")");
|
| +}
|
| +#endif
|
| +
|
| +bool SkLocalMatrixImageFilterAsInput::applyCropRect(const Context& ctx, const SkBitmap& src,
|
| + const SkIPoint& srcOffset,
|
| + SkIRect* bounds) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return this->INHERITED::applyCropRect(localCtx, src, srcOffset, bounds);
|
| +}
|
| +
|
| +bool SkLocalMatrixImageFilterAsInput::applyCropRect(const Context& ctx, Proxy* proxy,
|
| + const SkBitmap& src,
|
| + SkIPoint* srcOffset, SkIRect* bounds,
|
| + SkBitmap* result) const {
|
| + Context localCtx(concat(ctx.ctm(), fLocalM), ctx.clipBounds(), ctx.cache());
|
| + return this->INHERITED::applyCropRect(localCtx, proxy, src, srcOffset, bounds, result);
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& localMatrix) const {
|
| +// return SkLocalMatrixImageFilterAsInput::Create(const_cast<SkImageFilter*>(this), localMatrix);
|
| + return SkLocalMatrixImageFilter::Create(const_cast<SkImageFilter*>(this), localMatrix);
|
| +}
|
|
|