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}