| 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.native_mut(), |
| 34 | 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.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.native(), |
| 57 | 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 | |