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