Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkLocalMatrixImageFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
13
16 if (!input) {
17 return nullptr;
18 }
19 if (localMatrix.isIdentity()) {
20 return input;
21 }
22
23 MatrixCapability inputCapability = as_IFB(input)->getCTMCapability();
24 if ((inputCapability == MatrixCapability::kTranslate && !localMatrix.isTranslate()) ||
25 (inputCapability == MatrixCapability::kScaleTranslate && !localMatrix.isScaleTranslate())) {
26 // Nothing we can do at this point
27 return nullptr;
28 }
29
30 SkMatrix invLocal;
31 if (!localMatrix.invert(&invLocal)) {
32 return nullptr;
33 }
34
35 return sk_sp<SkImageFilter>(new SkLocalMatrixImageFilter(localMatrix, invLocal, &input));
36}
37
38sk_sp<SkFlattenable> SkLocalMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
40 SkMatrix lm;
41 buffer.readMatrix(&lm);
42 return SkLocalMatrixImageFilter::Make(lm, common.getInput(0));
43}
44
46 this->SkImageFilter_Base::flatten(buffer);
47 buffer.writeMatrix(fLocalMatrix);
48 // fInvLocalMatrix will be reconstructed
49}
50
51///////////////////////////////////////////////////////////////////////////////
52
53skif::Mapping SkLocalMatrixImageFilter::localMapping(const skif::Mapping& mapping) const {
54 skif::Mapping localMapping = mapping;
55 localMapping.concatLocal(fLocalMatrix);
56 return localMapping;
57}
58
60 skif::Mapping localMapping = this->localMapping(ctx.mapping());
61 return this->getChildOutput(0, ctx.withNewMapping(localMapping));
62}
63
65 const skif::Mapping& mapping,
66 const skif::LayerSpace<SkIRect>& desiredOutput,
67 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const {
68 // The local matrix changes 'mapping' by adjusting the parameter space of the image filter, but
69 // both 'desiredOutput' and 'contentBounds' have already been transformed to the consistent
70 // layer space. They remain unchanged with the new mapping.
71 return this->getChildInputLayerBounds(0, this->localMapping(mapping),
72 desiredOutput, contentBounds);
73}
74
75std::optional<skif::LayerSpace<SkIRect>> SkLocalMatrixImageFilter::onGetOutputLayerBounds(
76 const skif::Mapping& mapping,
77 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const {
78 return this->getChildOutputLayerBounds(0, this->localMapping(mapping), contentBounds);
79}
80
82 // In onGet[Input|Output]LayerBounds, there is a Mapping that can be adjusted by the
83 // local matrix, so their layer-space parameters do not need to be modified. Since
84 // computeFastBounds() takes no matrix, it always operates as if it has the identity mapping.
85 //
86 // In order to match the behavior of onGetInputLayerBounds, we map 'bounds' by the inverse of
87 // the local matrix, pass that to the child, and then map the result by the local matrix.
88 // TODO: Implementing computeFastBounds in terms of onGetOutputLayerBounds() trivially removes
89 // this complexity.
90 SkRect localBounds = fInvLocalMatrix.mapRect(bounds);
91 return fLocalMatrix.mapRect(this->getInput(0)->computeFastBounds(localBounds));
92}
static SkImageFilter_Base * as_IFB(SkImageFilter *filter)
#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)
skif::LayerSpace< SkIRect > getChildInputLayerBounds(int index, const skif::Mapping &mapping, const skif::LayerSpace< SkIRect > &desiredOutput, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const
void flatten(SkWriteBuffer &) const override
skif::FilterResult getChildOutput(int index, const skif::Context &ctx) const
std::optional< skif::LayerSpace< SkIRect > > getChildOutputLayerBounds(int index, const skif::Mapping &mapping, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const
MatrixCapability getCTMCapability() const
const SkImageFilter * getInput(int i) const
skif::LayerSpace< SkIRect > onGetInputLayerBounds(const skif::Mapping &, const skif::LayerSpace< SkIRect > &desiredOutput, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const override
std::optional< skif::LayerSpace< SkIRect > > onGetOutputLayerBounds(const skif::Mapping &, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const override
skif::FilterResult onFilterImage(const skif::Context &ctx) const override
void flatten(SkWriteBuffer &) const override
static sk_sp< SkImageFilter > Make(const SkMatrix &localMatrix, sk_sp< SkImageFilter > input)
SkRect computeFastBounds(const SkRect &) const override
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
bool isTranslate() const
Definition SkMatrix.h:248
bool isScaleTranslate() const
Definition SkMatrix.h:236
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
bool isIdentity() const
Definition SkMatrix.h:223
const Mapping & mapping() const
Context withNewMapping(const Mapping &mapping) const
void concatLocal(const SkMatrix &local)
static const uint8_t buffer[]