x-graphics 0.2.1

Graphics framework for X
Documentation
use wasm_bindgen::JsCast;
use web_sys::{OffscreenCanvas, OffscreenCanvasRenderingContext2d};

use super::{canvas::WebCanvas, device::WebDeviceContext};
use crate::{
    base::Dimension,
    canvas::CanvasBackend,
    error::GraphicsError,
    geometry::{FSize, ISize},
    layer::LayerBackend,
    Float,
};

#[derive(Clone, Debug)]
pub struct WebLayer {
    layer: OffscreenCanvas,
}

impl Dimension for WebLayer {
    fn size(&self) -> FSize {
        FSize::new(self.layer.width() as Float, self.layer.height() as Float)
    }

    fn pixel_size(&self) -> ISize {
        ISize::new(self.layer.width() as i32, self.layer.height() as i32)
    }
}

impl LayerBackend for WebLayer {
    type DeviceContextType = WebDeviceContext;
    type CanvasType = WebCanvas;

    fn new(_context: Option<&Self::DeviceContextType>, width: usize, height: usize, canvas: &Self::CanvasType) -> Result<Self, GraphicsError> {
        let matrix = canvas.get_matrix().matrix;
        let scale_x = matrix.m11();
        let scale_y = matrix.m22();
        let width = (width as f64 * scale_x).ceil() as u32;
        let height = (height as f64 * scale_y).ceil() as u32;
        OffscreenCanvas::new(width, height)
            .map(|layer| {
                let context = layer.get_context("2d").unwrap().unwrap().dyn_into::<OffscreenCanvasRenderingContext2d>().unwrap();
                context.scale(scale_x, scale_y).ok();
                Self {
                    layer,
                }
            })
            .map_err(|err| GraphicsError::CreationFailed(err.as_string().unwrap_or(stringify!(OffscreenCanvas).to_string())))
    }
}

impl WebLayer {
    pub(super) fn layer(&self) -> &OffscreenCanvas {
        &self.layer
    }
}