skia_safe/utils/
shadow_utils.rs

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.native_mut(),
34            path.native(),
35            z_plane_params.into().native(),
36            light_pos.into().native(),
37            light_radius,
38            ambient_color.into().into_native(),
39            spot_color.into().into_native(),
40            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 = crate::Rect::default();
54    unsafe {
55        SkShadowUtils::GetLocalBounds(
56            ctm.native(),
57            path.native(),
58            z_plane_params.into().native(),
59            light_pos.into().native(),
60            light_radius,
61            flags,
62            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::default();
99    let mut out_spot_color = Color::default();
100    unsafe {
101        SkShadowUtils::ComputeTonalColors(
102            ambient_color.into().into_native(),
103            spot_color.into().into_native(),
104            out_ambient_color.native_mut(),
105            out_spot_color.native_mut(),
106        )
107    }
108    (out_ambient_color, out_spot_color)
109}