• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef SkImageFilters_DEFINED
9 #define SkImageFilters_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkImage.h"
13 #include "include/core/SkImageFilter.h"
14 #include "include/core/SkPicture.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkShader.h"
19 #include "include/core/SkTileMode.h"
20 #include "include/core/SkTypes.h"
21 
22 #include <cstddef>
23 #include <optional>
24 #include <string_view>
25 #include <utility>
26 
27 class SkBlender;
28 class SkColorFilter;
29 class SkMatrix;
30 class SkRuntimeShaderBuilder;
31 enum class SkBlendMode;
32 struct SkIPoint;
33 struct SkISize;
34 struct SkPoint3;
35 struct SkSamplingOptions;
36 
37 // A set of factory functions providing useful SkImageFilter effects. For image filters that take an
38 // input filter, providing nullptr means it will automatically use the dynamic source image. This
39 // source depends on how the filter is applied, but is either the contents of a saved layer when
40 // drawing with SkCanvas, or an explicit SkImage if using one of the SkImages::MakeWithFilter
41 // factories.
42 class SK_API SkImageFilters {
43 public:
44     // This is just a convenience type to allow passing SkIRects, SkRects, and optional pointers
45     // to those types as a crop rect for the image filter factories. It's not intended to be used
46     // directly.
47     struct CropRect : public std::optional<SkRect> {
CropRectCropRect48         CropRect() {}
49         // Intentionally not explicit so callers don't have to use this type but can use SkIRect or
50         // SkRect as desired.
CropRectCropRect51         CropRect(const SkIRect& crop) : std::optional<SkRect>(SkRect::Make(crop)) {}
CropRectCropRect52         CropRect(const SkRect& crop) : std::optional<SkRect>(crop) {}
CropRectCropRect53         CropRect(const std::optional<SkRect>& crop) : std::optional<SkRect>(crop) {}
CropRectCropRect54         CropRect(const std::nullopt_t&) : std::optional<SkRect>() {}
55 
56         // Backwards compatibility for when the APIs used to explicitly accept "const SkRect*"
CropRectCropRect57         CropRect(std::nullptr_t) {}
CropRectCropRect58         CropRect(const SkIRect* optionalCrop) {
59             if (optionalCrop) {
60                 *this = SkRect::Make(*optionalCrop);
61             }
62         }
CropRectCropRect63         CropRect(const SkRect* optionalCrop) {
64             if (optionalCrop) {
65                 *this = *optionalCrop;
66             }
67         }
68 
69         // std::optional doesn't define == when comparing to another optional...
70         bool operator==(const CropRect& o) const {
71             return this->has_value() == o.has_value() &&
72                    (!this->has_value() || this->value() == *o);
73         }
74     };
75 
76     /**
77      *  Create a filter that implements a custom blend mode. Each output pixel is the result of
78      *  combining the corresponding background and foreground pixels using the 4 coefficients:
79      *     k1 * foreground * background + k2 * foreground + k3 * background + k4
80      *  @param k1, k2, k3, k4 The four coefficients used to combine the foreground and background.
81      *  @param enforcePMColor If true, the RGB channels will be clamped to the calculated alpha.
82      *  @param background     The background content, using the source bitmap when this is null.
83      *  @param foreground     The foreground content, using the source bitmap when this is null.
84      *  @param cropRect       Optional rectangle that crops the inputs and output.
85      */
86     static sk_sp<SkImageFilter> Arithmetic(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
87                                            bool enforcePMColor, sk_sp<SkImageFilter> background,
88                                            sk_sp<SkImageFilter> foreground,
89                                            const CropRect& cropRect = {});
90 
91     /**
92      *  This filter takes an SkBlendMode and uses it to composite the two filters together.
93      *  @param mode       The blend mode that defines the compositing operation
94      *  @param background The Dst pixels used in blending, if null the source bitmap is used.
95      *  @param foreground The Src pixels used in blending, if null the source bitmap is used.
96      *  @cropRect         Optional rectangle to crop input and output.
97      */
98     static sk_sp<SkImageFilter> Blend(SkBlendMode mode, sk_sp<SkImageFilter> background,
99                                       sk_sp<SkImageFilter> foreground = nullptr,
100                                       const CropRect& cropRect = {});
101 
102     /**
103      *  This filter takes an SkBlendMode and uses it to composite the two filters together.
104      *  @param blender       The blender that defines the compositing operation
105      *  @param background The Dst pixels used in blending, if null the source bitmap is used.
106      *  @param foreground The Src pixels used in blending, if null the source bitmap is used.
107      *  @cropRect         Optional rectangle to crop input and output.
108      */
109     static sk_sp<SkImageFilter> Blend(sk_sp<SkBlender> blender, sk_sp<SkImageFilter> background,
110                                       sk_sp<SkImageFilter> foreground = nullptr,
111                                       const CropRect& cropRect = {});
112 
113     /**
114      *  Create a filter that blurs its input by the separate X and Y sigmas. The provided tile mode
115      *  is used when the blur kernel goes outside the input image.
116      *  @param sigmaX   The Gaussian sigma value for blurring along the X axis.
117      *  @param sigmaY   The Gaussian sigma value for blurring along the Y axis.
118      *  @param tileMode The tile mode applied at edges .
119      *                  TODO (michaelludwig) - kMirror is not supported yet
120      *  @param input    The input filter that is blurred, uses source bitmap if this is null.
121      *  @param cropRect Optional rectangle that crops the input and output.
122      */
123     static sk_sp<SkImageFilter> Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode,
124                                      sk_sp<SkImageFilter> input, const CropRect& cropRect = {});
125     // As above, but defaults to the decal tile mode.
126     static sk_sp<SkImageFilter> Blur(SkScalar sigmaX, SkScalar sigmaY, sk_sp<SkImageFilter> input,
127                                      const CropRect& cropRect = {}) {
128         return Blur(sigmaX, sigmaY, SkTileMode::kDecal, std::move(input), cropRect);
129     }
130 
131     /**
132      *  Create a filter that applies the color filter to the input filter results.
133      *  @param cf       The color filter that transforms the input image.
134      *  @param input    The input filter, or uses the source bitmap if this is null.
135      *  @param cropRect Optional rectangle that crops the input and output.
136      */
137     static sk_sp<SkImageFilter> ColorFilter(sk_sp<SkColorFilter> cf, sk_sp<SkImageFilter> input,
138                                             const CropRect& cropRect = {});
139 
140     /**
141      *  Create a filter that composes 'inner' with 'outer', such that the results of 'inner' are
142      *  treated as the source bitmap passed to 'outer', i.e. result = outer(inner(source)).
143      *  @param outer The outer filter that evaluates the results of inner.
144      *  @param inner The inner filter that produces the input to outer.
145      */
146     static sk_sp<SkImageFilter> Compose(sk_sp<SkImageFilter> outer, sk_sp<SkImageFilter> inner);
147 
148     /**
149      *  Create a filter that applies a crop to the result of the 'input' filter. Pixels within the
150      *  crop rectangle are unmodified from what 'input' produced. Pixels outside of crop match the
151      *  provided SkTileMode (defaulting to kDecal).
152      *
153      *  NOTE: The optional CropRect argument for many of the factories is equivalent to creating the
154      *  filter without a CropRect and then wrapping it in ::Crop(rect, kDecal). Explicitly adding
155      *  Crop filters lets you control their tiling and use different geometry for the input and the
156      *  output of another filter.
157      *
158      *  @param rect     The cropping geometry
159      *  @param tileMode The tilemode applied to pixels *outside* of 'crop'
160      *  @param input    The input filter that is cropped, uses source image if this is null
161     */
162     static sk_sp<SkImageFilter> Crop(const SkRect& rect,
163                                      SkTileMode tileMode,
164                                      sk_sp<SkImageFilter> input);
Crop(const SkRect & rect,sk_sp<SkImageFilter> input)165     static sk_sp<SkImageFilter> Crop(const SkRect& rect, sk_sp<SkImageFilter> input) {
166         return Crop(rect, SkTileMode::kDecal, std::move(input));
167     }
168 
169     /**
170      *  Create a filter that moves each pixel in its color input based on an (x,y) vector encoded
171      *  in its displacement input filter. Two color components of the displacement image are
172      *  mapped into a vector as scale * (color[xChannel], color[yChannel]), where the channel
173      *  selectors are one of R, G, B, or A.
174      *  @param xChannelSelector RGBA channel that encodes the x displacement per pixel.
175      *  @param yChannelSelector RGBA channel that encodes the y displacement per pixel.
176      *  @param scale            Scale applied to displacement extracted from image.
177      *  @param displacement     The filter defining the displacement image, or null to use source.
178      *  @param color            The filter providing the color pixels to be displaced. If null,
179      *                          it will use the source.
180      *  @param cropRect         Optional rectangle that crops the color input and output.
181      */
182     static sk_sp<SkImageFilter> DisplacementMap(SkColorChannel xChannelSelector,
183                                                 SkColorChannel yChannelSelector,
184                                                 SkScalar scale, sk_sp<SkImageFilter> displacement,
185                                                 sk_sp<SkImageFilter> color,
186                                                 const CropRect& cropRect = {});
187 
188     /**
189      *  Create a filter that draws a drop shadow under the input content. This filter produces an
190      *  image that includes the inputs' content.
191      *  @param dx       The X offset of the shadow.
192      *  @param dy       The Y offset of the shadow.
193      *  @param sigmaX   The blur radius for the shadow, along the X axis.
194      *  @param sigmaY   The blur radius for the shadow, along the Y axis.
195      *  @param color    The color of the drop shadow.
196      *  @param input    The input filter, or will use the source bitmap if this is null.
197      *  @param cropRect Optional rectangle that crops the input and output.
198      */
199     static sk_sp<SkImageFilter> DropShadow(SkScalar dx, SkScalar dy,
200                                            SkScalar sigmaX, SkScalar sigmaY,
201                                            SkColor color, sk_sp<SkImageFilter> input,
202                                            const CropRect& cropRect = {});
203     /**
204      *  Create a filter that renders a drop shadow, in exactly the same manner as ::DropShadow,
205      *  except that the resulting image does not include the input content. This allows the shadow
206      *  and input to be composed by a filter DAG in a more flexible manner.
207      *  @param dx       The X offset of the shadow.
208      *  @param dy       The Y offset of the shadow.
209      *  @param sigmaX   The blur radius for the shadow, along the X axis.
210      *  @param sigmaY   The blur radius for the shadow, along the Y axis.
211      *  @param color    The color of the drop shadow.
212      *  @param input    The input filter, or will use the source bitmap if this is null.
213      *  @param cropRect Optional rectangle that crops the input and output.
214      */
215     static sk_sp<SkImageFilter> DropShadowOnly(SkScalar dx, SkScalar dy,
216                                                SkScalar sigmaX, SkScalar sigmaY,
217                                                SkColor color, sk_sp<SkImageFilter> input,
218                                                const CropRect& cropRect = {});
219 
220     /**
221      * Create a filter that always produces transparent black.
222      */
223     static sk_sp<SkImageFilter> Empty();
224 
225     /**
226      *  Create a filter that draws the 'srcRect' portion of image into 'dstRect' using the given
227      *  filter quality. Similar to SkCanvas::drawImageRect. The returned image filter evaluates
228      *  to transparent black if 'image' is null.
229      *
230      *  @param image    The image that is output by the filter, subset by 'srcRect'.
231      *  @param srcRect  The source pixels sampled into 'dstRect'
232      *  @param dstRect  The local rectangle to draw the image into.
233      *  @param sampling The sampling to use when drawing the image.
234      */
235     static sk_sp<SkImageFilter> Image(sk_sp<SkImage> image, const SkRect& srcRect,
236                                       const SkRect& dstRect, const SkSamplingOptions& sampling);
237 
238     /**
239      *  Create a filter that draws the image using the given sampling.
240      *  Similar to SkCanvas::drawImage. The returned image filter evaluates to transparent black if
241      *  'image' is null.
242      *
243      *  @param image    The image that is output by the filter.
244      *  @param sampling The sampling to use when drawing the image.
245      */
Image(sk_sp<SkImage> image,const SkSamplingOptions & sampling)246     static sk_sp<SkImageFilter> Image(sk_sp<SkImage> image, const SkSamplingOptions& sampling) {
247         if (image) {
248             SkRect r = SkRect::Make(image->bounds());
249             return Image(std::move(image), r, r, sampling);
250         } else {
251             return nullptr;
252         }
253     }
254 
255     /**
256      *  Create a filter that fills 'lensBounds' with a magnification of the input.
257      *
258      *  @param lensBounds The outer bounds of the magnifier effect
259      *  @param zoomAmount The amount of magnification applied to the input image
260      *  @param inset      The size or width of the fish-eye distortion around the magnified content
261      *  @param sampling   The SkSamplingOptions applied to the input image when magnified
262      *  @param input      The input filter that is magnified; if null the source bitmap is used
263      *  @param cropRect   Optional rectangle that crops the input and output.
264      */
265     static sk_sp<SkImageFilter> Magnifier(const SkRect& lensBounds,
266                                           SkScalar zoomAmount,
267                                           SkScalar inset,
268                                           const SkSamplingOptions& sampling,
269                                           sk_sp<SkImageFilter> input,
270                                           const CropRect& cropRect = {});
271 
272     /**
273      *  Create a filter that applies an NxM image processing kernel to the input image. This can be
274      *  used to produce effects such as sharpening, blurring, edge detection, etc.
275      *  @param kernelSize    The kernel size in pixels, in each dimension (N by M).
276      *  @param kernel        The image processing kernel. Must contain N * M elements, in row order.
277      *  @param gain          A scale factor applied to each pixel after convolution. This can be
278      *                       used to normalize the kernel, if it does not already sum to 1.
279      *  @param bias          A bias factor added to each pixel after convolution.
280      *  @param kernelOffset  An offset applied to each pixel coordinate before convolution.
281      *                       This can be used to center the kernel over the image
282      *                       (e.g., a 3x3 kernel should have an offset of {1, 1}).
283      *  @param tileMode      How accesses outside the image are treated.
284      *                       TODO (michaelludwig) - kMirror is not supported yet
285      *  @param convolveAlpha If true, all channels are convolved. If false, only the RGB channels
286      *                       are convolved, and alpha is copied from the source image.
287      *  @param input         The input image filter, if null the source bitmap is used instead.
288      *  @param cropRect      Optional rectangle to which the output processing will be limited.
289      */
290     static sk_sp<SkImageFilter> MatrixConvolution(const SkISize& kernelSize,
291                                                   const SkScalar kernel[], SkScalar gain,
292                                                   SkScalar bias, const SkIPoint& kernelOffset,
293                                                   SkTileMode tileMode, bool convolveAlpha,
294                                                   sk_sp<SkImageFilter> input,
295                                                   const CropRect& cropRect = {});
296 
297     /**
298      *  Create a filter that transforms the input image by 'matrix'. This matrix transforms the
299      *  local space, which means it effectively happens prior to any transformation coming from the
300      *  SkCanvas initiating the filtering.
301      *  @param matrix   The matrix to apply to the original content.
302      *  @param sampling How the image will be sampled when it is transformed
303      *  @param input    The image filter to transform, or null to use the source image.
304      */
305     static sk_sp<SkImageFilter> MatrixTransform(const SkMatrix& matrix,
306                                                 const SkSamplingOptions& sampling,
307                                                 sk_sp<SkImageFilter> input);
308 
309     /**
310      *  Create a filter that merges the 'count' filters together by drawing their results in order
311      *  with src-over blending.
312      *  @param filters  The input filter array to merge, which must have 'count' elements. Any null
313      *                  filter pointers will use the source bitmap instead.
314      *  @param count    The number of input filters to be merged.
315      *  @param cropRect Optional rectangle that crops all input filters and the output.
316      */
317     static sk_sp<SkImageFilter> Merge(sk_sp<SkImageFilter>* const filters, int count,
318                                       const CropRect& cropRect = {});
319     /**
320      *  Create a filter that merges the results of the two filters together with src-over blending.
321      *  @param first    The first input filter, or the source bitmap if this is null.
322      *  @param second   The second input filter, or the source bitmap if this null.
323      *  @param cropRect Optional rectangle that crops the inputs and output.
324      */
325     static sk_sp<SkImageFilter> Merge(sk_sp<SkImageFilter> first, sk_sp<SkImageFilter> second,
326                                       const CropRect& cropRect = {}) {
327         sk_sp<SkImageFilter> array[] = { std::move(first), std::move(second) };
328         return Merge(array, 2, cropRect);
329     }
330 
331     /**
332      *  Create a filter that offsets the input filter by the given vector.
333      *  @param dx       The x offset in local space that the image is shifted.
334      *  @param dy       The y offset in local space that the image is shifted.
335      *  @param input    The input that will be moved, if null the source bitmap is used instead.
336      *  @param cropRect Optional rectangle to crop the input and output.
337      */
338     static sk_sp<SkImageFilter> Offset(SkScalar dx, SkScalar dy, sk_sp<SkImageFilter> input,
339                                        const CropRect& cropRect = {});
340 
341     /**
342      *  Create a filter that produces the SkPicture as its output, clipped to both 'targetRect' and
343      *  the picture's internal cull rect.
344      *
345      *  If 'pic' is null, the returned image filter produces transparent black.
346      *
347      *  @param pic        The picture that is drawn for the filter output.
348      *  @param targetRect The drawing region for the picture.
349      */
350     static sk_sp<SkImageFilter> Picture(sk_sp<SkPicture> pic, const SkRect& targetRect);
351     // As above, but uses SkPicture::cullRect for the drawing region.
Picture(sk_sp<SkPicture> pic)352     static sk_sp<SkImageFilter> Picture(sk_sp<SkPicture> pic) {
353         SkRect target = pic ? pic->cullRect() : SkRect::MakeEmpty();
354         return Picture(std::move(pic), target);
355     }
356 
357     /**
358      *  Create a filter that fills the output with the per-pixel evaluation of the SkShader produced
359      *  by the SkRuntimeShaderBuilder. The shader is defined in the image filter's local coordinate
360      *  system, so it will automatically be affected by SkCanvas' transform.
361      *
362      *  This variant assumes that the runtime shader samples 'childShaderName' with the same input
363      *  coordinate passed to to shader.
364      *
365      *  This requires a GPU backend or SkSL to be compiled in.
366      *
367      *  @param builder         The builder used to produce the runtime shader, that will in turn
368      *                         fill the result image
369      *  @param childShaderName The name of the child shader defined in the builder that will be
370      *                         bound to the input param (or the source image if the input param
371      *                         is null).  If empty, the builder can have exactly one child shader,
372      *                         which automatically binds the input param.
373      *  @param input           The image filter that will be provided as input to the runtime
374      *                         shader. If null the implicit source image is used instead
375      */
RuntimeShader(const SkRuntimeShaderBuilder & builder,std::string_view childShaderName,sk_sp<SkImageFilter> input)376     static sk_sp<SkImageFilter> RuntimeShader(const SkRuntimeShaderBuilder& builder,
377                                               std::string_view childShaderName,
378                                               sk_sp<SkImageFilter> input) {
379         return RuntimeShader(builder, /*sampleRadius=*/0.f, childShaderName, std::move(input));
380     }
381 
382     /**
383      * As above, but 'sampleRadius' defines the sampling radius of 'childShaderName' relative to
384      * the runtime shader produced by 'builder'. If greater than 0, the coordinate passed to
385      * childShader.eval() will be up to 'sampleRadius' away (maximum absolute offset in 'x' or 'y')
386      * from the coordinate passed into the runtime shader.
387      *
388      * This allows Skia to provide sampleable values for the image filter without worrying about
389      * boundary conditions.
390      *
391      * This requires a GPU backend or SkSL to be compiled in.
392     */
393     static sk_sp<SkImageFilter> RuntimeShader(const SkRuntimeShaderBuilder& builder,
394                                               SkScalar sampleRadius,
395                                               std::string_view childShaderName,
396                                               sk_sp<SkImageFilter> input);
397 
398     /**
399      *  Create a filter that fills the output with the per-pixel evaluation of the SkShader produced
400      *  by the SkRuntimeShaderBuilder. The shader is defined in the image filter's local coordinate
401      *  system, so it will automatically be affected by SkCanvas' transform.
402      *
403      *  This requires a GPU backend or SkSL to be compiled in.
404      *
405      *  @param builder          The builder used to produce the runtime shader, that will in turn
406      *                          fill the result image
407      *  @param childShaderNames The names of the child shaders defined in the builder that will be
408      *                          bound to the input params (or the source image if the input param
409      *                          is null). If any name is null, or appears more than once, factory
410      *                          fails and returns nullptr.
411      *  @param inputs           The image filters that will be provided as input to the runtime
412      *                          shader. If any are null, the implicit source image is used instead.
413      *  @param inputCount       How many entries are present in 'childShaderNames' and 'inputs'.
414      */
RuntimeShader(const SkRuntimeShaderBuilder & builder,std::string_view childShaderNames[],const sk_sp<SkImageFilter> inputs[],int inputCount)415     static sk_sp<SkImageFilter> RuntimeShader(const SkRuntimeShaderBuilder& builder,
416                                               std::string_view childShaderNames[],
417                                               const sk_sp<SkImageFilter> inputs[],
418                                               int inputCount) {
419         return RuntimeShader(builder, /*maxSampleRadius=*/0.f, childShaderNames,
420                              inputs, inputCount);
421     }
422 
423     /**
424      * As above, but 'maxSampleRadius' defines the sampling limit on coordinates provided to all
425      * child shaders. Like the single-child variant with a sample radius, this can be used to
426      * inform Skia that the runtime shader guarantees that all dynamic children (defined in
427      * childShaderNames) will be evaluated with coordinates at most 'maxSampleRadius' away from the
428      * coordinate provided to the runtime shader itself.
429      *
430      *  This requires a GPU backend or SkSL to be compiled in.
431      */
432     static sk_sp<SkImageFilter> RuntimeShader(const SkRuntimeShaderBuilder& builder,
433                                               SkScalar maxSampleRadius,
434                                               std::string_view childShaderNames[],
435                                               const sk_sp<SkImageFilter> inputs[],
436                                               int inputCount);
437 
438     enum class Dither : bool {
439         kNo = false,
440         kYes = true
441     };
442 
443     /**
444      *  Create a filter that fills the output with the per-pixel evaluation of the SkShader. The
445      *  shader is defined in the image filter's local coordinate system, so will automatically
446      *  be affected by SkCanvas' transform.
447      *
448      *  Like Image() and Picture(), this is a leaf filter that can be used to introduce inputs to
449      *  a complex filter graph, but should generally be combined with a filter that as at least
450      *  one null input to use the implicit source image.
451      *
452      *  Returns an image filter that evaluates to transparent black if 'shader' is null.
453      *
454      *  @param shader The shader that fills the result image
455      */
456     static sk_sp<SkImageFilter> Shader(sk_sp<SkShader> shader, const CropRect& cropRect = {}) {
457         return Shader(std::move(shader), Dither::kNo, cropRect);
458     }
459     static sk_sp<SkImageFilter> Shader(sk_sp<SkShader> shader, Dither dither,
460                                        const CropRect& cropRect = {});
461 
462     /**
463      *  Create a tile image filter.
464      *  @param src   Defines the pixels to tile
465      *  @param dst   Defines the pixel region that the tiles will be drawn to
466      *  @param input The input that will be tiled, if null the source bitmap is used instead.
467      */
468     static sk_sp<SkImageFilter> Tile(const SkRect& src, const SkRect& dst,
469                                      sk_sp<SkImageFilter> input);
470 
471     // Morphology filter effects
472 
473     /**
474      *  Create a filter that dilates each input pixel's channel values to the max value within the
475      *  given radii along the x and y axes.
476      *  @param radiusX  The distance to dilate along the x axis to either side of each pixel.
477      *  @param radiusY  The distance to dilate along the y axis to either side of each pixel.
478      *  @param input    The image filter that is dilated, using source bitmap if this is null.
479      *  @param cropRect Optional rectangle that crops the input and output.
480      */
481     static sk_sp<SkImageFilter> Dilate(SkScalar radiusX, SkScalar radiusY,
482                                        sk_sp<SkImageFilter> input,
483                                        const CropRect& cropRect = {});
484 
485     /**
486      *  Create a filter that erodes each input pixel's channel values to the minimum channel value
487      *  within the given radii along the x and y axes.
488      *  @param radiusX  The distance to erode along the x axis to either side of each pixel.
489      *  @param radiusY  The distance to erode along the y axis to either side of each pixel.
490      *  @param input    The image filter that is eroded, using source bitmap if this is null.
491      *  @param cropRect Optional rectangle that crops the input and output.
492      */
493     static sk_sp<SkImageFilter> Erode(SkScalar radiusX, SkScalar radiusY,
494                                       sk_sp<SkImageFilter> input,
495                                       const CropRect& cropRect = {});
496 
497     // Lighting filter effects
498 
499     /**
500      *  Create a filter that calculates the diffuse illumination from a distant light source,
501      *  interpreting the alpha channel of the input as the height profile of the surface (to
502      *  approximate normal vectors).
503      *  @param direction    The direction to the distance light.
504      *  @param lightColor   The color of the diffuse light source.
505      *  @param surfaceScale Scale factor to transform from alpha values to physical height.
506      *  @param kd           Diffuse reflectance coefficient.
507      *  @param input        The input filter that defines surface normals (as alpha), or uses the
508      *                      source bitmap when null.
509      *  @param cropRect     Optional rectangle that crops the input and output.
510      */
511     static sk_sp<SkImageFilter> DistantLitDiffuse(const SkPoint3& direction, SkColor lightColor,
512                                                   SkScalar surfaceScale, SkScalar kd,
513                                                   sk_sp<SkImageFilter> input,
514                                                   const CropRect& cropRect = {});
515     /**
516      *  Create a filter that calculates the diffuse illumination from a point light source, using
517      *  alpha channel of the input as the height profile of the surface (to approximate normal
518      *  vectors).
519      *  @param location     The location of the point light.
520      *  @param lightColor   The color of the diffuse light source.
521      *  @param surfaceScale Scale factor to transform from alpha values to physical height.
522      *  @param kd           Diffuse reflectance coefficient.
523      *  @param input        The input filter that defines surface normals (as alpha), or uses the
524      *                      source bitmap when null.
525      *  @param cropRect     Optional rectangle that crops the input and output.
526      */
527     static sk_sp<SkImageFilter> PointLitDiffuse(const SkPoint3& location, SkColor lightColor,
528                                                 SkScalar surfaceScale, SkScalar kd,
529                                                 sk_sp<SkImageFilter> input,
530                                                 const CropRect& cropRect = {});
531     /**
532      *  Create a filter that calculates the diffuse illumination from a spot light source, using
533      *  alpha channel of the input as the height profile of the surface (to approximate normal
534      *  vectors). The spot light is restricted to be within 'cutoffAngle' of the vector between
535      *  the location and target.
536      *  @param location        The location of the spot light.
537      *  @param target          The location that the spot light is point towards
538      *  @param falloffExponent Exponential falloff parameter for illumination outside of cutoffAngle
539      *  @param cutoffAngle     Maximum angle from lighting direction that receives full light
540      *  @param lightColor      The color of the diffuse light source.
541      *  @param surfaceScale    Scale factor to transform from alpha values to physical height.
542      *  @param kd              Diffuse reflectance coefficient.
543      *  @param input           The input filter that defines surface normals (as alpha), or uses the
544      *                         source bitmap when null.
545      *  @param cropRect        Optional rectangle that crops the input and output.
546      */
547     static sk_sp<SkImageFilter> SpotLitDiffuse(const SkPoint3& location, const SkPoint3& target,
548                                                SkScalar falloffExponent, SkScalar cutoffAngle,
549                                                SkColor lightColor, SkScalar surfaceScale,
550                                                SkScalar kd, sk_sp<SkImageFilter> input,
551                                                const CropRect& cropRect = {});
552 
553     /**
554      *  Create a filter that calculates the specular illumination from a distant light source,
555      *  interpreting the alpha channel of the input as the height profile of the surface (to
556      *  approximate normal vectors).
557      *  @param direction    The direction to the distance light.
558      *  @param lightColor   The color of the specular light source.
559      *  @param surfaceScale Scale factor to transform from alpha values to physical height.
560      *  @param ks           Specular reflectance coefficient.
561      *  @param shininess    The specular exponent determining how shiny the surface is.
562      *  @param input        The input filter that defines surface normals (as alpha), or uses the
563      *                      source bitmap when null.
564      *  @param cropRect     Optional rectangle that crops the input and output.
565      */
566     static sk_sp<SkImageFilter> DistantLitSpecular(const SkPoint3& direction, SkColor lightColor,
567                                                    SkScalar surfaceScale, SkScalar ks,
568                                                    SkScalar shininess, sk_sp<SkImageFilter> input,
569                                                    const CropRect& cropRect = {});
570     /**
571      *  Create a filter that calculates the specular illumination from a point light source, using
572      *  alpha channel of the input as the height profile of the surface (to approximate normal
573      *  vectors).
574      *  @param location     The location of the point light.
575      *  @param lightColor   The color of the specular light source.
576      *  @param surfaceScale Scale factor to transform from alpha values to physical height.
577      *  @param ks           Specular reflectance coefficient.
578      *  @param shininess    The specular exponent determining how shiny the surface is.
579      *  @param input        The input filter that defines surface normals (as alpha), or uses the
580      *                      source bitmap when null.
581      *  @param cropRect     Optional rectangle that crops the input and output.
582      */
583     static sk_sp<SkImageFilter> PointLitSpecular(const SkPoint3& location, SkColor lightColor,
584                                                  SkScalar surfaceScale, SkScalar ks,
585                                                  SkScalar shininess, sk_sp<SkImageFilter> input,
586                                                  const CropRect& cropRect = {});
587     /**
588      *  Create a filter that calculates the specular illumination from a spot light source, using
589      *  alpha channel of the input as the height profile of the surface (to approximate normal
590      *  vectors). The spot light is restricted to be within 'cutoffAngle' of the vector between
591      *  the location and target.
592      *  @param location        The location of the spot light.
593      *  @param target          The location that the spot light is point towards
594      *  @param falloffExponent Exponential falloff parameter for illumination outside of cutoffAngle
595      *  @param cutoffAngle     Maximum angle from lighting direction that receives full light
596      *  @param lightColor      The color of the specular light source.
597      *  @param surfaceScale    Scale factor to transform from alpha values to physical height.
598      *  @param ks              Specular reflectance coefficient.
599      *  @param shininess       The specular exponent determining how shiny the surface is.
600      *  @param input           The input filter that defines surface normals (as alpha), or uses the
601      *                         source bitmap when null.
602      *  @param cropRect        Optional rectangle that crops the input and output.
603      */
604     static sk_sp<SkImageFilter> SpotLitSpecular(const SkPoint3& location, const SkPoint3& target,
605                                                 SkScalar falloffExponent, SkScalar cutoffAngle,
606                                                 SkColor lightColor, SkScalar surfaceScale,
607                                                 SkScalar ks, SkScalar shininess,
608                                                 sk_sp<SkImageFilter> input,
609                                                 const CropRect& cropRect = {});
610 
611 private:
612     SkImageFilters() = delete;
613 };
614 
615 #endif // SkImageFilters_DEFINED
616