core_graphics2/
function.rs

1use std::ptr::null;
2
3use core_foundation::base::{CFTypeID, TCFType};
4use libc::c_void;
5
6use crate::base::CGFloat;
7
8#[repr(C)]
9pub struct __CGFunction(c_void);
10
11pub type CGFunctionRef = *const __CGFunction;
12
13pub type CGFunctionEvaluateCallback = extern "C" fn(*const c_void, *const CGFloat, *mut CGFloat);
14pub type CGFunctionReleaseInfoCallback = extern "C" fn(*mut c_void);
15
16#[repr(C)]
17pub struct CGFunctionCallbacks {
18    pub version: u32,
19    pub evaluate: CGFunctionEvaluateCallback,
20    pub releaseInfo: CGFunctionReleaseInfoCallback,
21}
22
23extern "C" {
24    pub fn CGFunctionGetTypeID() -> CFTypeID;
25    pub fn CGFunctionCreate(
26        info: *mut c_void,
27        domainDimension: usize,
28        domain: *const CGFloat,
29        rangeDimension: usize,
30        range: *const CGFloat,
31        callbacks: *const CGFunctionCallbacks,
32    ) -> CGFunctionRef;
33    pub fn CGFunctionRetain(function: CGFunctionRef) -> CGFunctionRef;
34    pub fn CGFunctionRelease(function: CGFunctionRef);
35}
36
37pub struct CGFunction(CGFunctionRef);
38
39impl Drop for CGFunction {
40    fn drop(&mut self) {
41        unsafe { CGFunctionRelease(self.0) }
42    }
43}
44
45impl_TCFType!(CGFunction, CGFunctionRef, CGFunctionGetTypeID);
46impl_CFTypeDescription!(CGFunction);
47
48impl CGFunction {
49    pub unsafe fn new(
50        info: *mut c_void,
51        domain: Option<&[CGFloat]>,
52        range: Option<&[CGFloat]>,
53        callbacks: Option<&CGFunctionCallbacks>,
54    ) -> Option<Self> {
55        let domain_dimension = domain.map_or(0, |d| d.len());
56        let domain = domain.map_or(null(), |d| d.as_ptr());
57        let range_dimension = range.map_or(0, |r| r.len());
58        let range = range.map_or(null(), |r| r.as_ptr());
59        let callbacks = callbacks.map_or(null(), |c| c as *const _);
60        let function = CGFunctionCreate(info, domain_dimension, domain, range_dimension, range, callbacks);
61        if function.is_null() {
62            None
63        } else {
64            Some(TCFType::wrap_under_create_rule(function))
65        }
66    }
67}