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