Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
SkShadowUtils Class Reference

#include <SkShadowUtils.h>

Static Public Member Functions

static void DrawShadow (SkCanvas *canvas, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags=SkShadowFlags::kNone_ShadowFlag)
 
static bool GetLocalBounds (const SkMatrix &ctm, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, uint32_t flags, SkRect *bounds)
 
static void ComputeTonalColors (SkColor inAmbientColor, SkColor inSpotColor, SkColor *outAmbientColor, SkColor *outSpotColor)
 

Detailed Description

Definition at line 38 of file SkShadowUtils.h.

Member Function Documentation

◆ ComputeTonalColors()

void SkShadowUtils::ComputeTonalColors ( SkColor  inAmbientColor,
SkColor  inSpotColor,
SkColor outAmbientColor,
SkColor outSpotColor 
)
static

Helper routine to compute color values for one-pass tonal alpha.

Parameters
inAmbientColorOriginal ambient color
inSpotColorOriginal spot color
outAmbientColorModified ambient color
outSpotColorModified spot color

Definition at line 478 of file SkShadowUtils.cpp.

479 {
480 // For tonal color we only compute color values for the spot shadow.
481 // The ambient shadow is greyscale only.
482
483 // Ambient
484 *outAmbientColor = SkColorSetARGB(SkColorGetA(inAmbientColor), 0, 0, 0);
485
486 // Spot
487 int spotR = SkColorGetR(inSpotColor);
488 int spotG = SkColorGetG(inSpotColor);
489 int spotB = SkColorGetB(inSpotColor);
490 int max = std::max(std::max(spotR, spotG), spotB);
491 int min = std::min(std::min(spotR, spotG), spotB);
492 SkScalar luminance = 0.5f*(max + min)/255.f;
493 SkScalar origA = SkColorGetA(inSpotColor)/255.f;
494
495 // We compute a color alpha value based on the luminance of the color, scaled by an
496 // adjusted alpha value. We want the following properties to match the UX examples
497 // (assuming a = 0.25) and to ensure that we have reasonable results when the color
498 // is black and/or the alpha is 0:
499 // f(0, a) = 0
500 // f(luminance, 0) = 0
501 // f(1, 0.25) = .5
502 // f(0.5, 0.25) = .4
503 // f(1, 1) = 1
504 // The following functions match this as closely as possible.
505 SkScalar alphaAdjust = (2.6f + (-2.66667f + 1.06667f*origA)*origA)*origA;
506 SkScalar colorAlpha = (3.544762f + (-4.891428f + 2.3466f*luminance)*luminance)*luminance;
507 colorAlpha = SkTPin(alphaAdjust*colorAlpha, 0.0f, 1.0f);
508
509 // Similarly, we set the greyscale alpha based on luminance and alpha so that
510 // f(0, a) = a
511 // f(luminance, 0) = 0
512 // f(1, 0.25) = 0.15
513 SkScalar greyscaleAlpha = SkTPin(origA*(1 - 0.4f*luminance), 0.0f, 1.0f);
514
515 // The final color we want to emulate is generated by rendering a color shadow (C_rgb) using an
516 // alpha computed from the color's luminance (C_a), and then a black shadow with alpha (S_a)
517 // which is an adjusted value of 'a'. Assuming SrcOver, a background color of B_rgb, and
518 // ignoring edge falloff, this becomes
519 //
520 // (C_a - S_a*C_a)*C_rgb + (1 - (S_a + C_a - S_a*C_a))*B_rgb
521 //
522 // Assuming premultiplied alpha, this means we scale the color by (C_a - S_a*C_a) and
523 // set the alpha to (S_a + C_a - S_a*C_a).
524 SkScalar colorScale = colorAlpha*(SK_Scalar1 - greyscaleAlpha);
525 SkScalar tonalAlpha = colorScale + greyscaleAlpha;
526 SkScalar unPremulScale = colorScale / tonalAlpha;
527 *outSpotColor = SkColorSetARGB(tonalAlpha*255.999f,
528 unPremulScale*spotR,
529 unPremulScale*spotG,
530 unPremulScale*spotB);
531}
#define SkColorGetR(color)
Definition SkColor.h:65
#define SkColorGetG(color)
Definition SkColor.h:69
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
#define SkColorGetA(color)
Definition SkColor.h:61
#define SkColorGetB(color)
Definition SkColor.h:73
#define SK_Scalar1
Definition SkScalar.h:18
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
float SkScalar
Definition extension.cpp:12
static float max(float r, float g, float b)
Definition hsl.cpp:49
static float min(float r, float g, float b)
Definition hsl.cpp:48

◆ DrawShadow()

void SkShadowUtils::DrawShadow ( SkCanvas canvas,
const SkPath path,
const SkPoint3 zPlaneParams,
const SkPoint3 lightPos,
SkScalar  lightRadius,
SkColor  ambientColor,
SkColor  spotColor,
uint32_t  flags = SkShadowFlags::kNone_ShadowFlag 
)
static

Draw an offset spot shadow and outlining ambient shadow for the given path using a disc light. The shadow may be cached, depending on the path type and canvas matrix. If the matrix is perspective or the path is volatile, it will not be cached.

Parameters
canvasThe canvas on which to draw the shadows.
pathThe occluder used to generate the shadows.
zPlaneParamsValues for the plane function which returns the Z offset of the occluder from the canvas based on local x and y values (the current matrix is not applied).
lightPosGenerally, the 3D position of the light relative to the canvas plane. If kDirectionalLight_ShadowFlag is set, this specifies a vector pointing towards the light.
lightRadiusGenerally, the radius of the disc light. If DirectionalLight_ShadowFlag is set, this specifies the amount of blur when the occluder is at Z offset == 1. The blur will grow linearly as the Z value increases.
ambientColorThe color of the ambient shadow.
spotColorThe color of the spot shadow.
flagsOptions controlling opaque occluder optimizations, shadow appearance, and light position. See SkShadowFlags.

Definition at line 559 of file SkShadowUtils.cpp.

562 {
563 SkDrawShadowRec rec;
564 if (!fill_shadow_rec(path, zPlaneParams, lightPos, lightRadius, ambientColor, spotColor,
565 flags, canvas->getTotalMatrix(), &rec)) {
566 return;
567 }
568
569 canvas->private_draw_shadow_rec(path, rec);
570}
static bool fill_shadow_rec(const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags, const SkMatrix &ctm, SkDrawShadowRec *rec)
void private_draw_shadow_rec(const SkPath &, const SkDrawShadowRec &)
SkMatrix getTotalMatrix() const
FlutterSemanticsFlag flags

◆ GetLocalBounds()

bool SkShadowUtils::GetLocalBounds ( const SkMatrix ctm,
const SkPath path,
const SkPoint3 zPlaneParams,
const SkPoint3 lightPos,
SkScalar  lightRadius,
uint32_t  flags,
SkRect bounds 
)
static

Generate bounding box for shadows relative to path. Includes both the ambient and spot shadow bounds.

Parameters
ctmCurrent transformation matrix to device space.
pathThe occluder used to generate the shadows.
zPlaneParamsValues for the plane function which returns the Z offset of the occluder from the canvas based on local x and y values (the current matrix is not applied).
lightPosGenerally, the 3D position of the light relative to the canvas plane. If kDirectionalLight_ShadowFlag is set, this specifies a vector pointing towards the light.
lightRadiusGenerally, the radius of the disc light. If DirectionalLight_ShadowFlag is set, this specifies the amount of blur when the occluder is at Z offset == 1. The blur will grow linearly as the Z value increases.
flagsOptions controlling opaque occluder optimizations, shadow appearance, and light position. See SkShadowFlags.
boundsReturn value for shadow bounding box.
Returns
Returns true if successful, false otherwise.

Definition at line 572 of file SkShadowUtils.cpp.

574 {
575 SkDrawShadowRec rec;
576 if (!fill_shadow_rec(path, zPlaneParams, lightPos, lightRadius, SK_ColorBLACK, SK_ColorBLACK,
577 flags, ctm, &rec)) {
578 return false;
579 }
580
581 SkDrawShadowMetrics::GetLocalBounds(path, rec, ctm, bounds);
582
583 return true;
584}
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
void GetLocalBounds(const SkPath &path, const SkDrawShadowRec &rec, const SkMatrix &ctm, SkRect *bounds)

The documentation for this class was generated from the following files: