1 
2 /*
3  * Copyright 2017 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #ifndef SkShadowUtils_DEFINED
9 #define SkShadowUtils_DEFINED
10 
11 #include "SkColor.h"
12 #include "SkPoint3.h"
13 #include "SkScalar.h"
14 #include "../private/SkShadowFlags.h"
15 
16 class SkCanvas;
17 class SkPath;
18 class SkResourceCache;
19 
20 class SK_API SkShadowUtils {
21 public:
22     /**
23      * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
24      * light. The shadow may be cached, depending on the path type and canvas matrix. If the
25      * matrix is perspective or the path is volatile, it will not be cached.
26      *
27      * @param canvas  The canvas on which to draw the shadows.
28      * @param path  The occluder used to generate the shadows.
29      * @param zPlaneParams  Values for the plane function which returns the Z offset of the
30      *  occluder from the canvas based on local x and y values (the current matrix is not applied).
31      * @param lightPos  The 3D position of the light relative to the canvas plane. This is
32      *  independent of the canvas's current matrix.
33      * @param lightRadius  The radius of the disc light.
34      * @param ambientColor  The color of the ambient shadow.
35      * @param spotColor  The color of the spot shadow.
36      * @param flags  Options controlling opaque occluder optimizations and shadow appearance. See
37      *               SkShadowFlags.
38      */
39     static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
40                            const SkPoint3& lightPos, SkScalar lightRadius,
41                            SkColor ambientColor, SkColor spotColor,
42                            uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
43 
44     /**
45      * Deprecated version that uses one color and two alphas, and supports tonal color.
46      *
47      * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
48      * light. The shadow may be cached, depending on the path type and canvas matrix. If the
49      * matrix is perspective or the path is volatile, it will not be cached.
50      *
51      * @param canvas  The canvas on which to draw the shadows.
52      * @param path  The occluder used to generate the shadows.
53      * @param zPlaneParams  Values for the plane function which returns the Z offset of the
54      *  occluder from the canvas based on local x and y values (the current matrix is not applied).
55      * @param lightPos  The 3D position of the light relative to the canvas plane. This is
56      *  independent of the canvas's current matrix.
57      * @param lightRadius  The radius of the disc light.
58      * @param ambientAlpha  The maximum alpha of the ambient shadow.
59      * @param spotAlpha  The maxium alpha of the spot shadow.
60      * @param color  The shadow color.
61      * @param flags  Options controlling opaque occluder optimizations and shadow appearance. See
62      *               SkShadowFlags.
63      */
64     static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlane,
65                            const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
66                            SkScalar spotAlpha, SkColor color,
67                            uint32_t flags = SkShadowFlags::kNone_ShadowFlag) {
68         SkColor ambientColor;
69         SkColor spotColor;
70         if (flags & SkShadowFlags::kDisableTonalColor_ShadowFlag) {
71             ambientColor = SkColorSetARGB(ambientAlpha*SkColorGetA(color), SkColorGetR(color),
72                                           SkColorGetG(color), SkColorGetB(color));
73             spotColor = SkColorSetARGB(spotAlpha*SkColorGetA(color), SkColorGetR(color),
74                                        SkColorGetG(color), SkColorGetB(color));
75         } else {
76             SkColor inAmbient = SkColorSetA(color, ambientAlpha*SkColorGetA(color));
77             SkColor inSpot = SkColorSetA(color, spotAlpha*SkColorGetA(color));
78             ComputeTonalColors(inAmbient, inSpot, &ambientColor, &spotColor);
79         }
80 
81         DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientColor, spotColor, flags);
82     }
83 
84    /**
85     * Deprecated version with height value (to be removed when Flutter is updated).
86     *
87     * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
88     * light.
89     *
90     * @param canvas  The canvas on which to draw the shadows.
91     * @param path  The occluder used to generate the shadows.
92     * @param occluderHeight  The vertical offset of the occluder from the canvas. This is
93     *  independent of the canvas's current matrix.
94     * @param lightPos  The 3D position of the light relative to the canvas plane. This is
95     *  independent of the canvas's current matrix.
96     * @param lightRadius  The radius of the disc light.
97     * @param ambientAlpha  The maximum alpha of the ambient shadow.
98     * @param spotAlpha  The maxium alpha of the spot shadow.
99     * @param color  The shadow color.
100     * @param flags  Options controlling opaque occluder optimizations and shadow appearance. See
101     *               SkShadowFlags.
102     */
103     static void DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
104                            const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
105                            SkScalar spotAlpha, SkColor color,
106                            uint32_t flags = SkShadowFlags::kNone_ShadowFlag) {
107         SkPoint3 zPlane = SkPoint3::Make(0, 0, occluderHeight);
108         DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
109                    color, flags);
110     }
111 
112    /**
113     * Helper routine to compute color values for one-pass tonal alpha.
114     *
115     * @param inAmbientColor  Original ambient color
116     * @param inSpotColor  Original spot color
117     * @param outAmbientColor  Modified ambient color
118     * @param outSpotColor  Modified spot color
119     */
120     static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor,
121                                    SkColor* outAmbientColor, SkColor* outSpotColor);
122 };
123 
124 #endif
125