use core_graphics::{affine_transform::CGAffineTransform, base::CGFloat, context::CGContext, geometry::CGSize, layer::CGLayer};
use super::{canvas::CoreGraphicsCanvas, device::CoreGraphicsDeviceContext};
use crate::{
base::Dimension,
error::GraphicsError,
geometry::{FSize, ISize},
layer::LayerBackend,
};
#[derive(Clone, Debug)]
pub struct CoreGraphicsLayer {
layer: CGLayer,
context: CGContext,
}
impl Dimension for CoreGraphicsLayer {
fn size(&self) -> FSize {
self.layer.size().into()
}
fn pixel_size(&self) -> ISize {
let size = self.layer.size();
ISize::new(size.width as i32, size.height as i32)
}
}
impl LayerBackend for CoreGraphicsLayer {
type DeviceContextType = CoreGraphicsDeviceContext;
type CanvasType = CoreGraphicsCanvas;
fn new(_context: Option<&Self::DeviceContextType>, width: usize, height: usize, canvas: &Self::CanvasType) -> Result<Self, GraphicsError> {
let layer_size = CGSize::new(width as CGFloat, height as CGFloat);
let layer =
CGLayer::new_with_context(canvas.context(), layer_size, None).ok_or(GraphicsError::CreationFailed(stringify!(CGLayer).to_string()))?;
let ctx_layer = layer.context().ok_or(GraphicsError::InvalidHandle(stringify!(CGContext).to_string()))?;
let layer_size = layer.size();
let ctm = CGAffineTransform {
a: 1.0,
d: -1.0,
tx: 0.0,
ty: layer_size.height,
..Default::default()
};
ctx_layer.concat_ctm(ctm);
Ok(Self {
layer,
context: ctx_layer,
})
}
}
impl CoreGraphicsLayer {
pub(super) fn context(&self) -> &CGContext {
&self.context
}
pub(super) fn context_mut(&mut self) -> &mut CGContext {
&mut self.context
}
pub(super) fn layer(&self) -> &CGLayer {
&self.layer
}
}