blob: 3eca398fb1f0ee0f28e4922cef74a018a0e93cd9 [file] [log] [blame]
Jim Van Verth43475ad2017-01-13 14:37:37 -05001
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"
Mike Reed54518ac2017-07-22 08:29:48 -040012#include "SkPoint3.h"
Jim Van Verth43475ad2017-01-13 14:37:37 -050013#include "SkScalar.h"
Jim Van Verth2103cf02017-01-16 13:03:37 -050014#include "../private/SkShadowFlags.h"
Jim Van Verth43475ad2017-01-13 14:37:37 -050015
16class SkCanvas;
17class SkPath;
Brian Salomon804e0912017-02-23 09:34:03 -050018class SkResourceCache;
Jim Van Verth43475ad2017-01-13 14:37:37 -050019
Derek Sollenberger2fbf1bc2017-09-20 15:51:08 -040020class SK_API SkShadowUtils {
Jim Van Verth43475ad2017-01-13 14:37:37 -050021public:
Brian Salomon804e0912017-02-23 09:34:03 -050022 /**
23 * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
Jim Van Verth37c5a962017-05-10 14:13:24 -040024 * 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.
Brian Salomon804e0912017-02-23 09:34:03 -050026 *
27 * @param canvas The canvas on which to draw the shadows.
28 * @param path The occluder used to generate the shadows.
Jim Van Verth37c5a962017-05-10 14:13:24 -040029 * @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).
Brian Salomon804e0912017-02-23 09:34:03 -050031 * @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.
Jim Van Verthb1b80f72018-01-18 15:19:13 -050034 * @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.
Brian Salomon804e0912017-02-23 09:34:03 -050058 * @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.
Brian Salomon804e0912017-02-23 09:34:03 -050063 */
Jim Van Verthb1b80f72018-01-18 15:19:13 -050064 static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlane,
Jim Van Verth37c5a962017-05-10 14:13:24 -040065 const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
66 SkScalar spotAlpha, SkColor color,
Jim Van Verthb1b80f72018-01-18 15:19:13 -050067 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 }
Jim Van Verth37c5a962017-05-10 14:13:24 -040080
Jim Van Verthb1b80f72018-01-18 15:19:13 -050081 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 *
Jim Van Verth37c5a962017-05-10 14:13:24 -040087 * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
88 * light.
89 *
Jim Van Verth37c5a962017-05-10 14:13:24 -040090 * @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 */
Brian Salomon804e0912017-02-23 09:34:03 -0500103 static void DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
104 const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
105 SkScalar spotAlpha, SkColor color,
Jim Van Verth37c5a962017-05-10 14:13:24 -0400106 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 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400111
Jim Van Verthb1b80f72018-01-18 15:19:13 -0500112 /**
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);
Jim Van Verth43475ad2017-01-13 14:37:37 -0500122};
123
124#endif