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.
43static SkImageFilter::CropRect make_crop_rect(const SkIRect* cropRect) {
44 return cropRect ? SkImageFilter::CropRect(SkRect::Make(*cropRect))
45 : SkImageFilter::CropRect(SkRect::MakeEmpty(), 0x0);
46}
47
48void 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
71sk_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
78sk_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
86sk_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
93sk_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
99sk_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
104sk_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
112sk_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
124sk_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
135sk_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
141sk_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
147sk_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
156sk_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
161sk_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
167sk_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
173sk_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
178sk_sp<SkImageFilter> SkImageFilters::Picture(sk_sp<SkPicture> pic, const SkRect& targetRect) {
179 return SkPictureImageFilter::Make(std::move(pic), targetRect);
180}
181
182sk_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
187sk_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
196sk_sp<SkImageFilter> SkImageFilters::Dilate(
197 SkScalar radiusX, SkScalar 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
202sk_sp<SkImageFilter> SkImageFilters::Erode(
203 SkScalar radiusX, SkScalar 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
210sk_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
218sk_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
226sk_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
236sk_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
244sk_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
252sk_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