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}