1*c8dee2aaSAndroid Build Coastguard Worker 2*c8dee2aaSAndroid Build Coastguard Worker /* 3*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc. 4*c8dee2aaSAndroid Build Coastguard Worker * 5*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 6*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 7*c8dee2aaSAndroid Build Coastguard Worker */ 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkShadowUtils_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkShadowUtils_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas; 18*c8dee2aaSAndroid Build Coastguard Worker class SkMatrix; 19*c8dee2aaSAndroid Build Coastguard Worker class SkPath; 20*c8dee2aaSAndroid Build Coastguard Worker struct SkPoint3; 21*c8dee2aaSAndroid Build Coastguard Worker struct SkRect; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker enum SkShadowFlags { 24*c8dee2aaSAndroid Build Coastguard Worker kNone_ShadowFlag = 0x00, 25*c8dee2aaSAndroid Build Coastguard Worker /** The occluding object is not opaque. Knowing that the occluder is opaque allows 26*c8dee2aaSAndroid Build Coastguard Worker * us to cull shadow geometry behind it and improve performance. */ 27*c8dee2aaSAndroid Build Coastguard Worker kTransparentOccluder_ShadowFlag = 0x01, 28*c8dee2aaSAndroid Build Coastguard Worker /** Don't try to use analytic shadows. */ 29*c8dee2aaSAndroid Build Coastguard Worker kGeometricOnly_ShadowFlag = 0x02, 30*c8dee2aaSAndroid Build Coastguard Worker /** Light position represents a direction, light radius is blur radius at elevation 1 */ 31*c8dee2aaSAndroid Build Coastguard Worker kDirectionalLight_ShadowFlag = 0x04, 32*c8dee2aaSAndroid Build Coastguard Worker /** Concave paths will only use blur to generate the shadow */ 33*c8dee2aaSAndroid Build Coastguard Worker kConcaveBlurOnly_ShadowFlag = 0x08, 34*c8dee2aaSAndroid Build Coastguard Worker /** mask for all shadow flags */ 35*c8dee2aaSAndroid Build Coastguard Worker kAll_ShadowFlag = 0x0F 36*c8dee2aaSAndroid Build Coastguard Worker }; 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker class SK_API SkShadowUtils { 39*c8dee2aaSAndroid Build Coastguard Worker public: 40*c8dee2aaSAndroid Build Coastguard Worker /** 41*c8dee2aaSAndroid Build Coastguard Worker * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc 42*c8dee2aaSAndroid Build Coastguard Worker * light. The shadow may be cached, depending on the path type and canvas matrix. If the 43*c8dee2aaSAndroid Build Coastguard Worker * matrix is perspective or the path is volatile, it will not be cached. 44*c8dee2aaSAndroid Build Coastguard Worker * 45*c8dee2aaSAndroid Build Coastguard Worker * @param canvas The canvas on which to draw the shadows. 46*c8dee2aaSAndroid Build Coastguard Worker * @param path The occluder used to generate the shadows. 47*c8dee2aaSAndroid Build Coastguard Worker * @param zPlaneParams Values for the plane function which returns the Z offset of the 48*c8dee2aaSAndroid Build Coastguard Worker * occluder from the canvas based on local x and y values (the current matrix is not applied). 49*c8dee2aaSAndroid Build Coastguard Worker * @param lightPos Generally, the 3D position of the light relative to the canvas plane. 50*c8dee2aaSAndroid Build Coastguard Worker * If kDirectionalLight_ShadowFlag is set, this specifies a vector pointing 51*c8dee2aaSAndroid Build Coastguard Worker * towards the light. 52*c8dee2aaSAndroid Build Coastguard Worker * @param lightRadius Generally, the radius of the disc light. 53*c8dee2aaSAndroid Build Coastguard Worker * If DirectionalLight_ShadowFlag is set, this specifies the amount of 54*c8dee2aaSAndroid Build Coastguard Worker * blur when the occluder is at Z offset == 1. The blur will grow linearly 55*c8dee2aaSAndroid Build Coastguard Worker * as the Z value increases. 56*c8dee2aaSAndroid Build Coastguard Worker * @param ambientColor The color of the ambient shadow. 57*c8dee2aaSAndroid Build Coastguard Worker * @param spotColor The color of the spot shadow. 58*c8dee2aaSAndroid Build Coastguard Worker * @param flags Options controlling opaque occluder optimizations, shadow appearance, 59*c8dee2aaSAndroid Build Coastguard Worker * and light position. See SkShadowFlags. 60*c8dee2aaSAndroid Build Coastguard Worker */ 61*c8dee2aaSAndroid Build Coastguard Worker static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams, 62*c8dee2aaSAndroid Build Coastguard Worker const SkPoint3& lightPos, SkScalar lightRadius, 63*c8dee2aaSAndroid Build Coastguard Worker SkColor ambientColor, SkColor spotColor, 64*c8dee2aaSAndroid Build Coastguard Worker uint32_t flags = SkShadowFlags::kNone_ShadowFlag); 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker /** 67*c8dee2aaSAndroid Build Coastguard Worker * Generate bounding box for shadows relative to path. Includes both the ambient and spot 68*c8dee2aaSAndroid Build Coastguard Worker * shadow bounds. 69*c8dee2aaSAndroid Build Coastguard Worker * 70*c8dee2aaSAndroid Build Coastguard Worker * @param ctm Current transformation matrix to device space. 71*c8dee2aaSAndroid Build Coastguard Worker * @param path The occluder used to generate the shadows. 72*c8dee2aaSAndroid Build Coastguard Worker * @param zPlaneParams Values for the plane function which returns the Z offset of the 73*c8dee2aaSAndroid Build Coastguard Worker * occluder from the canvas based on local x and y values (the current matrix is not applied). 74*c8dee2aaSAndroid Build Coastguard Worker * @param lightPos Generally, the 3D position of the light relative to the canvas plane. 75*c8dee2aaSAndroid Build Coastguard Worker * If kDirectionalLight_ShadowFlag is set, this specifies a vector pointing 76*c8dee2aaSAndroid Build Coastguard Worker * towards the light. 77*c8dee2aaSAndroid Build Coastguard Worker * @param lightRadius Generally, the radius of the disc light. 78*c8dee2aaSAndroid Build Coastguard Worker * If DirectionalLight_ShadowFlag is set, this specifies the amount of 79*c8dee2aaSAndroid Build Coastguard Worker * blur when the occluder is at Z offset == 1. The blur will grow linearly 80*c8dee2aaSAndroid Build Coastguard Worker * as the Z value increases. 81*c8dee2aaSAndroid Build Coastguard Worker * @param flags Options controlling opaque occluder optimizations, shadow appearance, 82*c8dee2aaSAndroid Build Coastguard Worker * and light position. See SkShadowFlags. 83*c8dee2aaSAndroid Build Coastguard Worker * @param bounds Return value for shadow bounding box. 84*c8dee2aaSAndroid Build Coastguard Worker * @return Returns true if successful, false otherwise. 85*c8dee2aaSAndroid Build Coastguard Worker */ 86*c8dee2aaSAndroid Build Coastguard Worker static bool GetLocalBounds(const SkMatrix& ctm, const SkPath& path, 87*c8dee2aaSAndroid Build Coastguard Worker const SkPoint3& zPlaneParams, const SkPoint3& lightPos, 88*c8dee2aaSAndroid Build Coastguard Worker SkScalar lightRadius, uint32_t flags, SkRect* bounds); 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker /** 91*c8dee2aaSAndroid Build Coastguard Worker * Helper routine to compute color values for one-pass tonal alpha. 92*c8dee2aaSAndroid Build Coastguard Worker * 93*c8dee2aaSAndroid Build Coastguard Worker * @param inAmbientColor Original ambient color 94*c8dee2aaSAndroid Build Coastguard Worker * @param inSpotColor Original spot color 95*c8dee2aaSAndroid Build Coastguard Worker * @param outAmbientColor Modified ambient color 96*c8dee2aaSAndroid Build Coastguard Worker * @param outSpotColor Modified spot color 97*c8dee2aaSAndroid Build Coastguard Worker */ 98*c8dee2aaSAndroid Build Coastguard Worker static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor, 99*c8dee2aaSAndroid Build Coastguard Worker SkColor* outAmbientColor, SkColor* outSpotColor); 100*c8dee2aaSAndroid Build Coastguard Worker }; 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker #endif 103