1use crate::{prelude::*, scalar, Canvas, Color, Matrix, Path, Point3, Rect};
2use skia_bindings::{self as sb, SkShadowUtils};
3
4bitflags! {
5 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6 pub struct ShadowFlags: u32 {
7 #[allow(clippy::unnecessary_cast)]
8 const TRANSPARENT_OCCLUDER = sb::SkShadowFlags_kTransparentOccluder_ShadowFlag as u32;
9 #[allow(clippy::unnecessary_cast)]
10 const GEOMETRIC_ONLY = sb::SkShadowFlags_kGeometricOnly_ShadowFlag as u32;
11 #[allow(clippy::unnecessary_cast)]
12 const DIRECTIONAL_LIGHT = sb::SkShadowFlags_kDirectionalLight_ShadowFlag as u32;
13 #[allow(clippy::unnecessary_cast)]
14 const CONCAVE_BLUR_ONLY = sb::SkShadowFlags_kConcaveBlurOnly_ShadowFlag as u32;
15 const ALL = Self::TRANSPARENT_OCCLUDER.bits() | Self::GEOMETRIC_ONLY.bits()
16 | Self::DIRECTIONAL_LIGHT.bits() | Self::CONCAVE_BLUR_ONLY.bits();
17 }
18}
19
20#[allow(clippy::too_many_arguments)]
21pub fn draw_shadow(
22 canvas: &Canvas,
23 path: &Path,
24 z_plane_params: impl Into<Point3>,
25 light_pos: impl Into<Point3>,
26 light_radius: scalar,
27 ambient_color: impl Into<Color>,
28 spot_color: impl Into<Color>,
29 flags: impl Into<Option<ShadowFlags>>,
30) {
31 unsafe {
32 SkShadowUtils::DrawShadow(
33 canvas:canvas.native_mut(),
34 path:path.native(),
35 zPlaneParams:z_plane_params.into().native(),
36 lightPos:light_pos.into().native(),
37 lightRadius:light_radius,
38 ambientColor:ambient_color.into().into_native(),
39 spotColor:spot_color.into().into_native(),
40 flags:flags.into().unwrap_or_else(ShadowFlags::empty).bits(),
41 )
42 }
43}
44
45pub fn local_bounds(
46 ctm: &Matrix,
47 path: &Path,
48 z_plane_params: impl Into<Point3>,
49 light_pos: impl Into<Point3>,
50 light_radius: scalar,
51 flags: u32,
52) -> Option<Rect> {
53 let mut r: Rect = crate::Rect::default();
54 unsafebool {
55 SkShadowUtils::GetLocalBounds(
56 ctm:ctm.native(),
57 path:path.native(),
58 zPlaneParams:z_plane_params.into().native(),
59 lightPos:light_pos.into().native(),
60 lightRadius:light_radius,
61 flags,
62 bounds:r.native_mut(),
63 )
64 }
65 .if_true_some(r)
66}
67
68impl Canvas {
69 #[allow(clippy::too_many_arguments)]
70 pub fn draw_shadow(
71 &self,
72 path: &Path,
73 z_plane_params: impl Into<Point3>,
74 light_pos: impl Into<Point3>,
75 light_radius: scalar,
76 ambient_color: impl Into<Color>,
77 spot_color: impl Into<Color>,
78 flags: impl Into<Option<ShadowFlags>>,
79 ) -> &Self {
80 draw_shadow(
81 self,
82 path,
83 z_plane_params,
84 light_pos,
85 light_radius,
86 ambient_color,
87 spot_color,
88 flags,
89 );
90 self
91 }
92}
93
94pub fn compute_tonal_colors(
95 ambient_color: impl Into<Color>,
96 spot_color: impl Into<Color>,
97) -> (Color, Color) {
98 let mut out_ambient_color: Color = Color::default();
99 let mut out_spot_color: Color = Color::default();
100 unsafe {
101 SkShadowUtils::ComputeTonalColors(
102 inAmbientColor:ambient_color.into().into_native(),
103 inSpotColor:spot_color.into().into_native(),
104 outAmbientColor:out_ambient_color.native_mut(),
105 outSpotColor:out_spot_color.native_mut(),
106 )
107 }
108 (out_ambient_color, out_spot_color)
109}
110