core_graphics2/
gradient.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 array::{CFArray, CFArrayRef},
5 base::{CFTypeID, TCFType},
6};
7use libc::{c_void, size_t};
8
9use crate::{
10 base::CGFloat,
11 color::CGColor,
12 color_space::{CGColorSpace, CGColorSpaceRef},
13};
14
15#[repr(C)]
16pub struct __CGGradient(c_void);
17
18pub type CGGradientRef = *const __CGGradient;
19
20bitflags! {
21 #[repr(C)]
22 #[derive(Clone, Copy, Debug, Default, PartialEq)]
23 pub struct CGGradientDrawingOptions: u32 {
24 #[doc(alias = "kCGGradientDrawsBeforeStartLocation")]
25 const BeforeStartLocation = (1 << 0);
26 #[doc(alias = "kCGGradientDrawsAfterEndLocation")]
27 const AfterEndLocation = (1 << 1);
28 }
29}
30
31extern "C" {
32 pub fn CGGradientGetTypeID() -> CFTypeID;
33 pub fn CGGradientCreateWithColorComponents(
34 space: CGColorSpaceRef,
35 components: *const CGFloat,
36 locations: *const CGFloat,
37 count: size_t,
38 ) -> CGGradientRef;
39 pub fn CGGradientCreateWithColors(space: CGColorSpaceRef, colors: CFArrayRef, locations: *const CGFloat) -> CGGradientRef;
40 pub fn CGGradientRetain(gradient: CGGradientRef) -> CGGradientRef;
41 pub fn CGGradientRelease(gradient: CGGradientRef);
42}
43
44pub struct CGGradient(CGGradientRef);
45
46impl Drop for CGGradient {
47 fn drop(&mut self) {
48 unsafe { CGGradientRelease(self.0) }
49 }
50}
51
52impl_TCFType!(CGGradient, CGGradientRef, CGGradientGetTypeID);
53impl_CFTypeDescription!(CGGradient);
54
55impl CGGradient {
56 pub fn from_color_components(
57 color_space: Option<&CGColorSpace>,
58 components: Option<&[CGFloat]>,
59 locations: Option<&[CGFloat]>,
60 ) -> Option<CGGradient> {
61 unsafe {
62 let gradient = CGGradientCreateWithColorComponents(
63 color_space.map_or(null_mut(), |cs| cs.as_concrete_TypeRef()),
64 components.map_or(null(), |c| c.as_ptr()),
65 locations.map_or(null(), |l| l.as_ptr()),
66 locations.map_or(0, |l| l.len() as size_t),
67 );
68 if gradient.is_null() {
69 None
70 } else {
71 Some(TCFType::wrap_under_create_rule(gradient))
72 }
73 }
74 }
75
76 pub fn from_colors(color_space: Option<&CGColorSpace>, colors: Option<&CFArray<CGColor>>, locations: Option<&[CGFloat]>) -> Option<CGGradient> {
77 unsafe {
78 let gradient = CGGradientCreateWithColors(
79 color_space.map_or(null_mut(), |cs| cs.as_concrete_TypeRef()),
80 colors.map_or(null(), |c| c.as_concrete_TypeRef()),
81 locations.map_or(null(), |l| l.as_ptr()),
82 );
83 if gradient.is_null() {
84 None
85 } else {
86 Some(TCFType::wrap_under_create_rule(gradient))
87 }
88 }
89 }
90}