Skip to main content

core_graphics2/
shading.rs

1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4    base::{CFTypeID, TCFType},
5    impl_CFTypeDescription, impl_TCFType,
6};
7use libc::c_void;
8
9use crate::{
10    color_space::{CGColorSpace, CGColorSpaceRef},
11    function::{CGFunction, CGFunctionRef},
12    geometry::CGPoint,
13};
14
15#[repr(C)]
16pub struct __CGShading(c_void);
17
18pub type CGShadingRef = *mut __CGShading;
19
20extern "C" {
21    pub fn CGShadingGetTypeID() -> CFTypeID;
22    pub fn CGShadingCreateAxial(
23        space: CGColorSpaceRef,
24        start: CGPoint,
25        end: CGPoint,
26        function: CGFunctionRef,
27        extendStart: bool,
28        extendEnd: bool,
29    ) -> CGShadingRef;
30    pub fn CGShadingCreateRadial(
31        space: CGColorSpaceRef,
32        start: CGPoint,
33        startRadius: f64,
34        end: CGPoint,
35        endRadius: f64,
36        function: CGFunctionRef,
37        extendStart: bool,
38        extendEnd: bool,
39    ) -> CGShadingRef;
40    pub fn CGShadingRetain(shading: CGShadingRef) -> CGShadingRef;
41    pub fn CGShadingRelease(shading: CGShadingRef);
42}
43
44pub struct CGShading(CGShadingRef);
45
46impl Drop for CGShading {
47    fn drop(&mut self) {
48        unsafe { CGShadingRelease(self.0) }
49    }
50}
51
52impl_TCFType!(CGShading, CGShadingRef, CGShadingGetTypeID);
53impl_CFTypeDescription!(CGShading);
54
55impl CGShading {
56    pub fn new_axial(
57        space: Option<&CGColorSpace>,
58        start: CGPoint,
59        end: CGPoint,
60        function: Option<&CGFunction>,
61        extend_start: bool,
62        extend_end: bool,
63    ) -> Option<Self> {
64        unsafe {
65            let shading = CGShadingCreateAxial(
66                space.map_or(null_mut(), |s| s.as_concrete_TypeRef()),
67                start,
68                end,
69                function.map_or(null(), |f| f.as_concrete_TypeRef()),
70                extend_start,
71                extend_end,
72            );
73            if shading.is_null() {
74                None
75            } else {
76                Some(TCFType::wrap_under_create_rule(shading))
77            }
78        }
79    }
80
81    pub fn new_radial(
82        space: Option<&CGColorSpace>,
83        start: CGPoint,
84        start_radius: f64,
85        end: CGPoint,
86        end_radius: f64,
87        function: Option<&CGFunction>,
88        extend_start: bool,
89        extend_end: bool,
90    ) -> Option<Self> {
91        unsafe {
92            let shading = CGShadingCreateRadial(
93                space.map_or(null_mut(), |s| s.as_concrete_TypeRef()),
94                start,
95                start_radius,
96                end,
97                end_radius,
98                function.map_or(null(), |f| f.as_concrete_TypeRef()),
99                extend_start,
100                extend_end,
101            );
102            if shading.is_null() {
103                None
104            } else {
105                Some(TCFType::wrap_under_create_rule(shading))
106            }
107        }
108    }
109}