1 /*
2 * Copyright 2019 Google LLC
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
8 #include "include/effects/SkImageFilters.h"
9
10 // TODO (michaelludwig) - Right now there is a bit of a weird dependency where the implementations
11 // of the new, preferred filter factories depends on the per-filter headers in include/effects,
12 // which have themselves been marked as deprecated. But, once clients are updated to use the
13 // new factories implemented in this file, the per-filter headers can go into
14 // src/effects/imagefilters and will no longer be "deprecated" since they've been made fully
15 // internal at that point.
16 #include "include/effects/SkAlphaThresholdFilter.h"
17 #include "include/effects/SkArithmeticImageFilter.h"
18 #include "include/effects/SkBlurImageFilter.h"
19 #include "include/effects/SkColorFilterImageFilter.h"
20 #include "include/effects/SkComposeImageFilter.h"
21 #include "include/effects/SkDisplacementMapEffect.h"
22 #include "include/effects/SkDropShadowImageFilter.h"
23 #include "include/effects/SkImageSource.h"
24 #include "include/effects/SkLightingImageFilter.h"
25 #include "include/effects/SkMagnifierImageFilter.h"
26 #include "include/effects/SkMatrixConvolutionImageFilter.h"
27 #include "include/effects/SkMergeImageFilter.h"
28 #include "include/effects/SkMorphologyImageFilter.h"
29 #include "include/effects/SkOffsetImageFilter.h"
30 #include "include/effects/SkPaintImageFilter.h"
31 #include "include/effects/SkPictureImageFilter.h"
32 #include "include/effects/SkTileImageFilter.h"
33 #include "include/effects/SkXfermodeImageFilter.h"
34
35 // TODO (michaelludwig) - Once SkCanvas can draw the results of a filter with any transform, this
36 // filter can be moved out of core
37 #include "src/core/SkMatrixImageFilter.h"
38
39 // TODO (michaelludwig) - We are phasing out the use of SkImageFilter::CropRect since it does not
40 // appear as though edge flags are actually used and will move towards an explicit cropping filter.
41 // To assist with this, the new factory functions just take the basic SkIRect* even though the
42 // implementations have not been updated yet.
make_crop_rect(const SkIRect * cropRect)43 static SkImageFilter::CropRect make_crop_rect(const SkIRect* cropRect) {
44 return cropRect ? SkImageFilter::CropRect(SkRect::Make(*cropRect))
45 : SkImageFilter::CropRect(SkRect::MakeEmpty(), 0x0);
46 }
47
RegisterFlattenables()48 void SkImageFilters::RegisterFlattenables() {
49 SkAlphaThresholdFilter::RegisterFlattenables();
50 SkArithmeticImageFilter::RegisterFlattenables();
51 SkBlurImageFilter::RegisterFlattenables();
52 SkColorFilterImageFilter::RegisterFlattenables();
53 SkComposeImageFilter::RegisterFlattenables();
54 SkDilateImageFilter::RegisterFlattenables();
55 SkDisplacementMapEffect::RegisterFlattenables();
56 SkDropShadowImageFilter::RegisterFlattenables();
57 SkImageSource::RegisterFlattenables();
58 SkLightingImageFilter::RegisterFlattenables();
59 SkMagnifierImageFilter::RegisterFlattenables();
60 SkMatrixConvolutionImageFilter::RegisterFlattenables();
61 SkMergeImageFilter::RegisterFlattenables();
62 SkOffsetImageFilter::RegisterFlattenables();
63 SkPaintImageFilter::RegisterFlattenables();
64 SkPictureImageFilter::RegisterFlattenables();
65 SkTileImageFilter::RegisterFlattenables();
66 SkXfermodeImageFilter::RegisterFlattenables();
67 }
68
69 ///////////////////////////////////////////////////////////////////////////////////////////////////
70
AlphaThreshold(const SkRegion & region,SkScalar innerMin,SkScalar outerMax,sk_sp<SkImageFilter> input,const SkIRect * cropRect)71 sk_sp<SkImageFilter> SkImageFilters::AlphaThreshold(
72 const SkRegion& region, SkScalar innerMin, SkScalar outerMax, sk_sp<SkImageFilter> input,
73 const SkIRect* cropRect) {
74 SkImageFilter::CropRect r = make_crop_rect(cropRect);
75 return SkAlphaThresholdFilter::Make(region, innerMin, outerMax, std::move(input), &r);
76 }
77
Arithmetic(SkScalar k1,SkScalar k2,SkScalar k3,SkScalar k4,bool enforcePMColor,sk_sp<SkImageFilter> background,sk_sp<SkImageFilter> foreground,const SkIRect * cropRect)78 sk_sp<SkImageFilter> SkImageFilters::Arithmetic(
79 SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor,
80 sk_sp<SkImageFilter> background, sk_sp<SkImageFilter> foreground, const SkIRect* cropRect) {
81 SkImageFilter::CropRect r = make_crop_rect(cropRect);
82 return SkArithmeticImageFilter::Make(k1, k2, k3, k4, enforcePMColor, std::move(background),
83 std::move(foreground), &r);
84 }
85
Blur(SkScalar sigmaX,SkScalar sigmaY,SkTileMode tileMode,sk_sp<SkImageFilter> input,const SkIRect * cropRect)86 sk_sp<SkImageFilter> SkImageFilters::Blur(
87 SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp<SkImageFilter> input,
88 const SkIRect* cropRect) {
89 SkImageFilter::CropRect r = make_crop_rect(cropRect);
90 return SkBlurImageFilter::Make(sigmaX, sigmaY, tileMode, std::move(input), &r);
91 }
92
ColorFilter(sk_sp<SkColorFilter> cf,sk_sp<SkImageFilter> input,const SkIRect * cropRect)93 sk_sp<SkImageFilter> SkImageFilters::ColorFilter(
94 sk_sp<SkColorFilter> cf, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
95 SkImageFilter::CropRect r = make_crop_rect(cropRect);
96 return SkColorFilterImageFilter::Make(std::move(cf), std::move(input), &r);
97 }
98
Compose(sk_sp<SkImageFilter> outer,sk_sp<SkImageFilter> inner)99 sk_sp<SkImageFilter> SkImageFilters::Compose(
100 sk_sp<SkImageFilter> outer, sk_sp<SkImageFilter> inner) {
101 return SkComposeImageFilter::Make(std::move(outer), std::move(inner));
102 }
103
DisplacementMap(SkColorChannel xChannelSelector,SkColorChannel yChannelSelector,SkScalar scale,sk_sp<SkImageFilter> displacement,sk_sp<SkImageFilter> color,const SkIRect * cropRect)104 sk_sp<SkImageFilter> SkImageFilters::DisplacementMap(
105 SkColorChannel xChannelSelector, SkColorChannel yChannelSelector, SkScalar scale,
106 sk_sp<SkImageFilter> displacement, sk_sp<SkImageFilter> color, const SkIRect* cropRect) {
107 SkImageFilter::CropRect r = make_crop_rect(cropRect);
108 return SkDisplacementMapEffect::Make(xChannelSelector, yChannelSelector, scale,
109 std::move(displacement), std::move(color), &r);
110 }
111
DropShadow(SkScalar dx,SkScalar dy,SkScalar sigmaX,SkScalar sigmaY,SkColor color,sk_sp<SkImageFilter> input,const SkIRect * cropRect)112 sk_sp<SkImageFilter> SkImageFilters::DropShadow(
113 SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color,
114 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
115 SkImageFilter::CropRect r = make_crop_rect(cropRect);
116 // TODO (michaelludwig) - Once SkDropShadowImageFilter is fully hidden, this can be updated to
117 // pass a constant bool into the internal factory.
118 return SkDropShadowImageFilter::Make(
119 dx, dy, sigmaX, sigmaY, color,
120 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
121 std::move(input), &r);
122 }
123
DropShadowOnly(SkScalar dx,SkScalar dy,SkScalar sigmaX,SkScalar sigmaY,SkColor color,sk_sp<SkImageFilter> input,const SkIRect * cropRect)124 sk_sp<SkImageFilter> SkImageFilters::DropShadowOnly(
125 SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color,
126 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
127 SkImageFilter::CropRect r = make_crop_rect(cropRect);
128 // TODO (michaelludwig) - Once SkDropShadowImageFilter is fully hidden, this can be updated to
129 // pass a constant bool into the internal factory.
130 return SkDropShadowImageFilter::Make(dx, dy, sigmaX, sigmaY, color,
131 SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode,
132 std::move(input), &r);
133 }
134
Image(sk_sp<SkImage> image,const SkRect & srcRect,const SkRect & dstRect,SkFilterQuality filterQuality)135 sk_sp<SkImageFilter> SkImageFilters::Image(
136 sk_sp<SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
137 SkFilterQuality filterQuality) {
138 return SkImageSource::Make(std::move(image), srcRect, dstRect, filterQuality);
139 }
140
Magnifier(const SkRect & srcRect,SkScalar inset,sk_sp<SkImageFilter> input,const SkIRect * cropRect)141 sk_sp<SkImageFilter> SkImageFilters::Magnifier(
142 const SkRect& srcRect, SkScalar inset, sk_sp<SkImageFilter> input,const SkIRect* cropRect) {
143 SkImageFilter::CropRect r = make_crop_rect(cropRect);
144 return SkMagnifierImageFilter::Make(srcRect, inset, std::move(input), &r);
145 }
146
MatrixConvolution(const SkISize & kernelSize,const SkScalar kernel[],SkScalar gain,SkScalar bias,const SkIPoint & kernelOffset,SkTileMode tileMode,bool convolveAlpha,sk_sp<SkImageFilter> input,const SkIRect * cropRect)147 sk_sp<SkImageFilter> SkImageFilters::MatrixConvolution(
148 const SkISize& kernelSize, const SkScalar kernel[], SkScalar gain, SkScalar bias,
149 const SkIPoint& kernelOffset, SkTileMode tileMode, bool convolveAlpha,
150 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
151 SkImageFilter::CropRect r = make_crop_rect(cropRect);
152 return SkMatrixConvolutionImageFilter::Make(kernelSize, kernel, gain, bias, kernelOffset,
153 tileMode, convolveAlpha, std::move(input), &r);
154 }
155
MatrixTransform(const SkMatrix & transform,SkFilterQuality filterQuality,sk_sp<SkImageFilter> input)156 sk_sp<SkImageFilter> SkImageFilters::MatrixTransform(
157 const SkMatrix& transform, SkFilterQuality filterQuality, sk_sp<SkImageFilter> input) {
158 return SkMatrixImageFilter::Make(transform, filterQuality, std::move(input));
159 }
160
Merge(sk_sp<SkImageFilter> * const filters,int count,const SkIRect * cropRect)161 sk_sp<SkImageFilter> SkImageFilters::Merge(
162 sk_sp<SkImageFilter>* const filters, int count, const SkIRect* cropRect) {
163 SkImageFilter::CropRect r = make_crop_rect(cropRect);
164 return SkMergeImageFilter::Make(filters, count, &r);
165 }
166
Offset(SkScalar dx,SkScalar dy,sk_sp<SkImageFilter> input,const SkIRect * cropRect)167 sk_sp<SkImageFilter> SkImageFilters::Offset(
168 SkScalar dx, SkScalar dy, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
169 SkImageFilter::CropRect r = make_crop_rect(cropRect);
170 return SkOffsetImageFilter::Make(dx, dy, std::move(input), &r);
171 }
172
Paint(const SkPaint & paint,const SkIRect * cropRect)173 sk_sp<SkImageFilter> SkImageFilters::Paint(const SkPaint& paint, const SkIRect* cropRect) {
174 SkImageFilter::CropRect r = make_crop_rect(cropRect);
175 return SkPaintImageFilter::Make(paint, &r);
176 }
177
Picture(sk_sp<SkPicture> pic,const SkRect & targetRect)178 sk_sp<SkImageFilter> SkImageFilters::Picture(sk_sp<SkPicture> pic, const SkRect& targetRect) {
179 return SkPictureImageFilter::Make(std::move(pic), targetRect);
180 }
181
Tile(const SkRect & src,const SkRect & dst,sk_sp<SkImageFilter> input)182 sk_sp<SkImageFilter> SkImageFilters::Tile(
183 const SkRect& src, const SkRect& dst, sk_sp<SkImageFilter> input) {
184 return SkTileImageFilter::Make(src, dst, std::move(input));
185 }
186
Xfermode(SkBlendMode mode,sk_sp<SkImageFilter> background,sk_sp<SkImageFilter> foreground,const SkIRect * cropRect)187 sk_sp<SkImageFilter> SkImageFilters::Xfermode(
188 SkBlendMode mode, sk_sp<SkImageFilter> background, sk_sp<SkImageFilter> foreground,
189 const SkIRect* cropRect) {
190 SkImageFilter::CropRect r = make_crop_rect(cropRect);
191 return SkXfermodeImageFilter::Make(mode, std::move(background), std::move(foreground), &r);
192 }
193
194 // Morphology filter effects
195
Dilate(int radiusX,int radiusY,sk_sp<SkImageFilter> input,const SkIRect * cropRect)196 sk_sp<SkImageFilter> SkImageFilters::Dilate(
197 int radiusX, int radiusY, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
198 SkImageFilter::CropRect r = make_crop_rect(cropRect);
199 return SkDilateImageFilter::Make(radiusX, radiusY, std::move(input), &r);
200 }
201
Erode(int radiusX,int radiusY,sk_sp<SkImageFilter> input,const SkIRect * cropRect)202 sk_sp<SkImageFilter> SkImageFilters::Erode(
203 int radiusX, int radiusY, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
204 SkImageFilter::CropRect r = make_crop_rect(cropRect);
205 return SkErodeImageFilter::Make(radiusX, radiusY, std::move(input), &r);
206 }
207
208 // Lighting filter effects
209
DistantLitDiffuse(const SkPoint3 & direction,SkColor lightColor,SkScalar surfaceScale,SkScalar kd,sk_sp<SkImageFilter> input,const SkIRect * cropRect)210 sk_sp<SkImageFilter> SkImageFilters::DistantLitDiffuse(
211 const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
212 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
213 SkImageFilter::CropRect r = make_crop_rect(cropRect);
214 return SkLightingImageFilter::MakeDistantLitDiffuse(direction, lightColor, surfaceScale, kd,
215 std::move(input), &r);
216 }
217
PointLitDiffuse(const SkPoint3 & location,SkColor lightColor,SkScalar surfaceScale,SkScalar kd,sk_sp<SkImageFilter> input,const SkIRect * cropRect)218 sk_sp<SkImageFilter> SkImageFilters::PointLitDiffuse(
219 const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
220 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
221 SkImageFilter::CropRect r = make_crop_rect(cropRect);
222 return SkLightingImageFilter::MakePointLitDiffuse(location, lightColor, surfaceScale, kd,
223 std::move(input), &r);
224 }
225
SpotLitDiffuse(const SkPoint3 & location,const SkPoint3 & target,SkScalar falloffExponent,SkScalar cutoffAngle,SkColor lightColor,SkScalar surfaceScale,SkScalar kd,sk_sp<SkImageFilter> input,const SkIRect * cropRect)226 sk_sp<SkImageFilter> SkImageFilters::SpotLitDiffuse(
227 const SkPoint3& location, const SkPoint3& target, SkScalar falloffExponent,
228 SkScalar cutoffAngle, SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
229 sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
230 SkImageFilter::CropRect r = make_crop_rect(cropRect);
231 return SkLightingImageFilter::MakeSpotLitDiffuse(location, target, falloffExponent, cutoffAngle,
232 lightColor, surfaceScale, kd,
233 std::move(input), &r);
234 }
235
DistantLitSpecular(const SkPoint3 & direction,SkColor lightColor,SkScalar surfaceScale,SkScalar ks,SkScalar shininess,sk_sp<SkImageFilter> input,const SkIRect * cropRect)236 sk_sp<SkImageFilter> SkImageFilters::DistantLitSpecular(
237 const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
238 SkScalar shininess, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
239 SkImageFilter::CropRect r = make_crop_rect(cropRect);
240 return SkLightingImageFilter::MakeDistantLitSpecular(direction, lightColor, surfaceScale,
241 ks, shininess, std::move(input), &r);
242 }
243
PointLitSpecular(const SkPoint3 & location,SkColor lightColor,SkScalar surfaceScale,SkScalar ks,SkScalar shininess,sk_sp<SkImageFilter> input,const SkIRect * cropRect)244 sk_sp<SkImageFilter> SkImageFilters::PointLitSpecular(
245 const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
246 SkScalar shininess, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
247 SkImageFilter::CropRect r = make_crop_rect(cropRect);
248 return SkLightingImageFilter::MakePointLitSpecular(location, lightColor, surfaceScale, ks,
249 shininess, std::move(input), &r);
250 }
251
SpotLitSpecular(const SkPoint3 & location,const SkPoint3 & target,SkScalar falloffExponent,SkScalar cutoffAngle,SkColor lightColor,SkScalar surfaceScale,SkScalar ks,SkScalar shininess,sk_sp<SkImageFilter> input,const SkIRect * cropRect)252 sk_sp<SkImageFilter> SkImageFilters::SpotLitSpecular(
253 const SkPoint3& location, const SkPoint3& target, SkScalar falloffExponent,
254 SkScalar cutoffAngle, SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
255 SkScalar shininess, sk_sp<SkImageFilter> input, const SkIRect* cropRect) {
256 SkImageFilter::CropRect r = make_crop_rect(cropRect);
257 return SkLightingImageFilter::MakeSpotLitSpecular(location, target, falloffExponent,
258 cutoffAngle, lightColor, surfaceScale,
259 ks, shininess, std::move(input), &r);
260 }
261