core_graphics2/
shading.rs

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