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