Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkImageImageFilter.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
14#include "include/core/SkRect.h"
24
25#include <optional>
26#include <utility>
27
28namespace {
29
30class SkImageImageFilter final : public SkImageFilter_Base {
31public:
32 SkImageImageFilter(sk_sp<SkImage> image,
33 const SkRect& srcRect,
34 const SkRect& dstRect,
35 const SkSamplingOptions& sampling)
36 : SkImageFilter_Base(nullptr, 0)
37 , fImage(std::move(image))
38 , fSrcRect(srcRect)
39 , fDstRect(dstRect)
40 , fSampling(sampling) {
41 // The dst rect should be non-empty
42 SkASSERT(fImage && !dstRect.isEmpty());
43 }
44
45 SkRect computeFastBounds(const SkRect&) const override { return SkRect(fDstRect); }
46
47protected:
48 void flatten(SkWriteBuffer&) const override;
49
50private:
51 friend void ::SkRegisterImageImageFilterFlattenable();
52 SK_FLATTENABLE_HOOKS(SkImageImageFilter)
53
54 MatrixCapability onGetCTMCapability() const override { return MatrixCapability::kComplex; }
55
56 skif::FilterResult onFilterImage(const skif::Context&) const override;
57
59 const skif::Mapping& mapping,
60 const skif::LayerSpace<SkIRect>& desiredOutput,
61 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
62
63 std::optional<skif::LayerSpace<SkIRect>> onGetOutputLayerBounds(
64 const skif::Mapping& mapping,
65 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
66
67 sk_sp<SkImage> fImage;
68 // The src rect is relative to the image's contents, so is not technically in the parameter
69 // coordinate space that responds to the layer matrix (unlike fDstRect).
70 SkRect fSrcRect;
72 SkSamplingOptions fSampling;
73};
74
75} // end namespace
76
78 const SkRect& srcRect,
79 const SkRect& dstRect,
80 const SkSamplingOptions& sampling) {
81 if (srcRect.isEmpty() || dstRect.isEmpty() || !image) {
82 // There is no content to draw, so the filter should produce transparent black
83 return SkImageFilters::Empty();
84 } else {
85 SkRect imageBounds = SkRect::Make(image->dimensions());
86 if (imageBounds.contains(srcRect)) {
87 // No change to srcRect and dstRect needed
88 return sk_sp<SkImageFilter>(new SkImageImageFilter(
89 std::move(image), srcRect, dstRect, sampling));
90 } else {
91 SkMatrix srcToDst = SkMatrix::RectToRect(srcRect, dstRect);
92 if (!imageBounds.intersect(srcRect)) {
93 // No overlap, so draw empty
94 return SkImageFilters::Empty();
95 }
96
97 // Adjust dstRect to match the updated src (which is stored in imageBounds)
98 SkRect mappedBounds = srcToDst.mapRect(imageBounds);
99 if (mappedBounds.isEmpty()) {
100 return SkImageFilters::Empty();
101 }
102 return sk_sp<SkImageFilter>(new SkImageImageFilter(
103 std::move(image), imageBounds, mappedBounds, sampling));
104 }
105 }
106}
107
109 SK_REGISTER_FLATTENABLE(SkImageImageFilter);
110 // TODO (michaelludwig) - Remove after grace period for SKPs to stop using old name
111 SkFlattenable::Register("SkImageSourceImpl", SkImageImageFilter::CreateProc);
112}
113
114sk_sp<SkFlattenable> SkImageImageFilter::CreateProc(SkReadBuffer& buffer) {
118 } else {
119 sampling = buffer.readSampling();
120 }
121
122 SkRect src, dst;
123 buffer.readRect(&src);
124 buffer.readRect(&dst);
125
126 sk_sp<SkImage> image(buffer.readImage());
127 if (!image) {
128 return nullptr;
129 }
130
131 return SkImageFilters::Image(std::move(image), src, dst, sampling);
132}
133
134void SkImageImageFilter::flatten(SkWriteBuffer& buffer) const {
135 buffer.writeSampling(fSampling);
136 buffer.writeRect(fSrcRect);
137 buffer.writeRect(SkRect(fDstRect));
138 buffer.writeImage(fImage.get());
139}
140
141///////////////////////////////////////////////////////////////////////////////////////////////////
142
143skif::FilterResult SkImageImageFilter::onFilterImage(const skif::Context& ctx) const {
144 return skif::FilterResult::MakeFromImage(ctx, fImage, fSrcRect, fDstRect, fSampling);
145}
146
147skif::LayerSpace<SkIRect> SkImageImageFilter::onGetInputLayerBounds(
148 const skif::Mapping&,
150 std::optional<skif::LayerSpace<SkIRect>>) const {
151 // This is a leaf filter, it requires no input and no further recursion
153}
154
155std::optional<skif::LayerSpace<SkIRect>> SkImageImageFilter::onGetOutputLayerBounds(
156 const skif::Mapping& mapping,
157 std::optional<skif::LayerSpace<SkIRect>>) const {
158 // The output is the transformed bounds of the image.
159 return mapping.paramToLayer(fDstRect).roundOut();
160}
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SK_FLATTENABLE_HOOKS(type)
#define SK_REGISTER_FLATTENABLE(type)
void SkRegisterImageImageFilterFlattenable()
@ kLinear_SkMediumAs
static void Register(const char name[], Factory)
virtual skif::LayerSpace< SkIRect > onGetInputLayerBounds(const skif::Mapping &mapping, const skif::LayerSpace< SkIRect > &desiredOutput, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
void flatten(SkWriteBuffer &) const override
virtual std::optional< skif::LayerSpace< SkIRect > > onGetOutputLayerBounds(const skif::Mapping &mapping, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
virtual skif::FilterResult onFilterImage(const skif::Context &context) const =0
virtual MatrixCapability onGetCTMCapability() const
virtual SkRect computeFastBounds(const SkRect &bounds) const
static sk_sp< SkImageFilter > Empty()
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkRect &srcRect, const SkRect &dstRect, const SkSamplingOptions &sampling)
SkISize dimensions() const
Definition SkImage.h:297
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition SkMatrix.h:157
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ kImageFilterImageSampling_Version
static SkSamplingOptions FromFQ(SkLegacyFQ fq, SkMediumAs behavior=kNearest_SkMediumAs)
static FilterResult MakeFromImage(const Context &ctx, sk_sp< SkImage > image, SkRect srcRect, ParameterSpace< SkRect > dstRect, const SkSamplingOptions &sampling)
LayerSpace< T > paramToLayer(const ParameterSpace< T > &paramGeometry) const
sk_sp< SkImage > image
Definition examples.cpp:29
static const uint8_t buffer[]
SkSamplingOptions sampling
Definition SkRecords.h:337
dst
Definition cp.py:12
Definition ref_ptr.h:256
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
bool intersect(const SkRect &r)
Definition SkRect.cpp:114
bool contains(SkScalar x, SkScalar y) const
Definition extension.cpp:19
bool isEmpty() const
Definition SkRect.h:693