x-graphics 0.2.1

Graphics framework for X
Documentation
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
    }
}