core_graphics2/
layer.rs

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