core_graphics2/
shading.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::ptr::{null, null_mut};

use core_foundation::base::{CFTypeID, TCFType};
use libc::c_void;

use crate::{
    color_space::{CGColorSpace, CGColorSpaceRef},
    function::{CGFunction, CGFunctionRef},
    geometry::CGPoint,
};

#[repr(C)]
pub struct __CGShading(c_void);

pub type CGShadingRef = *mut __CGShading;

extern "C" {
    pub fn CGShadingGetTypeID() -> CFTypeID;
    pub fn CGShadingCreateAxial(
        space: CGColorSpaceRef,
        start: CGPoint,
        end: CGPoint,
        function: CGFunctionRef,
        extendStart: bool,
        extendEnd: bool,
    ) -> CGShadingRef;
    pub fn CGShadingCreateRadial(
        space: CGColorSpaceRef,
        start: CGPoint,
        startRadius: f64,
        end: CGPoint,
        endRadius: f64,
        function: CGFunctionRef,
        extendStart: bool,
        extendEnd: bool,
    ) -> CGShadingRef;
    pub fn CGShadingRetain(shading: CGShadingRef) -> CGShadingRef;
    pub fn CGShadingRelease(shading: CGShadingRef);
}

pub struct CGShading(CGShadingRef);

impl Drop for CGShading {
    fn drop(&mut self) {
        unsafe { CGShadingRelease(self.0) }
    }
}

impl_TCFType!(CGShading, CGShadingRef, CGShadingGetTypeID);
impl_CFTypeDescription!(CGShading);

impl CGShading {
    pub fn new_axial(
        space: Option<&CGColorSpace>,
        start: CGPoint,
        end: CGPoint,
        function: Option<&CGFunction>,
        extend_start: bool,
        extend_end: bool,
    ) -> Option<Self> {
        unsafe {
            let shading = CGShadingCreateAxial(
                space.map_or(null_mut(), |s| s.as_concrete_TypeRef()),
                start,
                end,
                function.map_or(null(), |f| f.as_concrete_TypeRef()),
                extend_start,
                extend_end,
            );
            if shading.is_null() {
                None
            } else {
                Some(TCFType::wrap_under_create_rule(shading))
            }
        }
    }

    pub fn new_radial(
        space: Option<&CGColorSpace>,
        start: CGPoint,
        start_radius: f64,
        end: CGPoint,
        end_radius: f64,
        function: Option<&CGFunction>,
        extend_start: bool,
        extend_end: bool,
    ) -> Option<Self> {
        unsafe {
            let shading = CGShadingCreateRadial(
                space.map_or(null_mut(), |s| s.as_concrete_TypeRef()),
                start,
                start_radius,
                end,
                end_radius,
                function.map_or(null(), |f| f.as_concrete_TypeRef()),
                extend_start,
                extend_end,
            );
            if shading.is_null() {
                None
            } else {
                Some(TCFType::wrap_under_create_rule(shading))
            }
        }
    }
}