1 | use crate::{prelude::*, scalar, Canvas, Color, Matrix, Path, Point3, Rect}; |
2 | use skia_bindings::{self as sb, SkShadowUtils}; |
3 | |
4 | bitflags! { |
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)] |
21 | pub 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 | |
45 | pub 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 | |
68 | impl 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 | |
94 | pub 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 | |