Skip to main content

core_graphics2/
layer.rs

1use std::ptr::null;
2
3use core_foundation::{
4    base::{CFType, CFTypeID, TCFType},
5    dictionary::{CFDictionary, CFDictionaryRef},
6    impl_CFTypeDescription, impl_TCFType,
7    string::CFString,
8};
9use libc::c_void;
10
11use crate::{
12    context::{CGContext, CGContextRef},
13    geometry::{CGPoint, CGRect, CGSize},
14};
15
16#[repr(C)]
17pub struct __CGLayer(c_void);
18
19pub type CGLayerRef = *mut __CGLayer;
20
21extern "C" {
22    pub fn CGLayerCreateWithContext(context: CGContextRef, size: CGSize, auxiliaryInfo: CFDictionaryRef) -> CGLayerRef;
23    pub fn CGLayerRetain(layer: CGLayerRef) -> CGLayerRef;
24    pub fn CGLayerRelease(layer: CGLayerRef);
25    pub fn CGLayerGetSize(layer: CGLayerRef) -> CGSize;
26    pub fn CGLayerGetContext(layer: CGLayerRef) -> CGContextRef;
27    pub fn CGContextDrawLayerInRect(context: CGContextRef, rect: CGRect, layer: CGLayerRef);
28    pub fn CGContextDrawLayerAtPoint(context: CGContextRef, point: CGPoint, layer: CGLayerRef);
29    pub fn CGLayerGetTypeID() -> CFTypeID;
30}
31
32pub struct CGLayer(CGLayerRef);
33
34impl Drop for CGLayer {
35    fn drop(&mut self) {
36        unsafe { CGLayerRelease(self.0) }
37    }
38}
39
40impl_TCFType!(CGLayer, CGLayerRef, CGLayerGetTypeID);
41impl_CFTypeDescription!(CGLayer);
42
43impl CGLayer {
44    pub fn new_with_context(context: &CGContext, size: CGSize, auxiliary_info: Option<&CFDictionary<CFString, CFType>>) -> Option<Self> {
45        unsafe {
46            let layer = CGLayerCreateWithContext(context.as_concrete_TypeRef(), size, auxiliary_info.map_or(null(), |ai| ai.as_concrete_TypeRef()));
47            if layer.is_null() {
48                None
49            } else {
50                Some(CGLayer(layer))
51            }
52        }
53    }
54
55    pub fn size(&self) -> CGSize {
56        unsafe { CGLayerGetSize(self.as_concrete_TypeRef()) }
57    }
58
59    pub fn context(&self) -> Option<CGContext> {
60        unsafe {
61            let context = CGLayerGetContext(self.as_concrete_TypeRef());
62            if context.is_null() {
63                None
64            } else {
65                Some(TCFType::wrap_under_get_rule(context))
66            }
67        }
68    }
69
70    pub fn draw_in_rect(&self, context: &CGContext, rect: CGRect) {
71        unsafe { CGContextDrawLayerInRect(context.as_concrete_TypeRef(), rect, self.as_concrete_TypeRef()) }
72    }
73
74    pub fn draw_at_point(&self, context: &CGContext, point: CGPoint) {
75        unsafe { CGContextDrawLayerAtPoint(context.as_concrete_TypeRef(), point, self.as_concrete_TypeRef()) }
76    }
77}
78
79impl CGContext {
80    pub fn draw_layer_in_rect(&self, layer: &CGLayer, rect: CGRect) {
81        layer.draw_in_rect(self, rect)
82    }
83
84    pub fn draw_layer_at_point(&self, layer: &CGLayer, point: CGPoint) {
85        layer.draw_at_point(self, point)
86    }
87}