From b1b80f7de4224c5083dfc1475e1988b2ce839a65 Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Thu, 18 Jan 2018 15:19:13 -0500 Subject: Remove tonal color from DrawShadow internals Bug: b/71719631 Change-Id: I676c34dfe5ea9b5e184ea53dd49a8b835d4e8cb6 Reviewed-on: https://skia-review.googlesource.com/95741 Reviewed-by: Robert Phillips Commit-Queue: Jim Van Verth --- include/utils/SkShadowUtils.h | 109 +++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 55 deletions(-) (limited to 'include/utils') diff --git a/include/utils/SkShadowUtils.h b/include/utils/SkShadowUtils.h index 9550a925b9..3eca398fb1 100644 --- a/include/utils/SkShadowUtils.h +++ b/include/utils/SkShadowUtils.h @@ -20,6 +20,30 @@ class SkResourceCache; class SK_API SkShadowUtils { public: /** + * 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. + * + * @param canvas The canvas on which to draw the shadows. + * @param path The occluder used to generate the shadows. + * @param zPlaneParams Values 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). + * @param lightPos The 3D position of the light relative to the canvas plane. This is + * independent of the canvas's current matrix. + * @param lightRadius The radius of the disc light. + * @param ambientColor The color of the ambient shadow. + * @param spotColor The color of the spot shadow. + * @param flags Options controlling opaque occluder optimizations and shadow appearance. See + * SkShadowFlags. + */ + 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); + + /** + * Deprecated version that uses one color and two alphas, and supports tonal color. + * * 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. @@ -37,17 +61,32 @@ public: * @param flags Options controlling opaque occluder optimizations and shadow appearance. See * SkShadowFlags. */ - static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams, + static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlane, const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color, - uint32_t flags = SkShadowFlags::kNone_ShadowFlag); + uint32_t flags = SkShadowFlags::kNone_ShadowFlag) { + SkColor ambientColor; + SkColor spotColor; + if (flags & SkShadowFlags::kDisableTonalColor_ShadowFlag) { + ambientColor = SkColorSetARGB(ambientAlpha*SkColorGetA(color), SkColorGetR(color), + SkColorGetG(color), SkColorGetB(color)); + spotColor = SkColorSetARGB(spotAlpha*SkColorGetA(color), SkColorGetR(color), + SkColorGetG(color), SkColorGetB(color)); + } else { + SkColor inAmbient = SkColorSetA(color, ambientAlpha*SkColorGetA(color)); + SkColor inSpot = SkColorSetA(color, spotAlpha*SkColorGetA(color)); + ComputeTonalColors(inAmbient, inSpot, &ambientColor, &spotColor); + } - /** + DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientColor, spotColor, flags); + } + + /** + * Deprecated version with height value (to be removed when Flutter is updated). + * * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc * light. * - * Deprecated version with height value (to be removed when Flutter is updated). - * * @param canvas The canvas on which to draw the shadows. * @param path The occluder used to generate the shadows. * @param occluderHeight The vertical offset of the occluder from the canvas. This is @@ -70,56 +109,16 @@ public: color, flags); } - /** - * Helper routine to compute scale alpha values for one-pass tonal alpha. - * - * The final color we want to emulate is generated by rendering a color shadow (C_rgb) using an - * alpha computed from the color's luminance (C_a), and then a black shadow with alpha (S_a) - * which is an adjusted value of 'a'. Assuming SrcOver, a background color of B_rgb, and - * ignoring edge falloff, this becomes - * - * (C_a - S_a*C_a)*C_rgb + (1 - (S_a + C_a - S_a*C_a))*B_rgb - * - * Since we use premultiplied alpha, this means we can scale the color by (C_a - S_a*C_a) and - * set the alpha to (S_a + C_a - S_a*C_a). - * - * @param r Red value of color - * @param g Green value of color - * @param b Blue value of color - * @param a Alpha value of color - * @param colorScale Factor to scale color values by - * @param tonalAlpha Value to set alpha to - */ - static inline void ComputeTonalColorParams(SkScalar r, SkScalar g, SkScalar b, SkScalar a, - SkScalar* colorScale, SkScalar* tonalAlpha) { - SkScalar max = SkTMax(SkTMax(r, g), b); - SkScalar min = SkTMin(SkTMin(r, g), b); - SkScalar luminance = 0.5f*(max + min); - - // We compute a color alpha value based on the luminance of the color, scaled by an - // adjusted alpha value. We want the following properties to match the UX examples - // (assuming a = 0.25) and to ensure that we have reasonable results when the color - // is black and/or the alpha is 0: - // f(0, a) = 0 - // f(luminance, 0) = 0 - // f(1, 0.25) = .5 - // f(0.5, 0.25) = .4 - // f(1, 1) = 1 - // The following functions match this as closely as possible. - SkScalar alphaAdjust = (2.6f + (-2.66667f + 1.06667f*a)*a)*a; - SkScalar colorAlpha = (3.544762f + (-4.891428f + 2.3466f*luminance)*luminance)*luminance; - colorAlpha = SkTPin(alphaAdjust*colorAlpha, 0.0f, 1.0f); - - // Similarly, we set the greyscale alpha based on luminance and alpha so that - // f(0, a) = a - // f(luminance, 0) = 0 - // f(1, 0.25) = 0.15 - SkScalar greyscaleAlpha = SkTPin(a*(1 - 0.4f*luminance), 0.0f, 1.0f); - - *colorScale = colorAlpha*(SK_Scalar1 - greyscaleAlpha); - *tonalAlpha = *colorScale + greyscaleAlpha; - } - + /** + * Helper routine to compute color values for one-pass tonal alpha. + * + * @param inAmbientColor Original ambient color + * @param inSpotColor Original spot color + * @param outAmbientColor Modified ambient color + * @param outSpotColor Modified spot color + */ + static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor, + SkColor* outAmbientColor, SkColor* outSpotColor); }; #endif -- cgit v1.2.3