use super::{Canvas, SendSyncWrapper};
use core::{
ops::{Deref, DerefMut},
ptr::NonNull,
};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use wasm_bindgen::JsValue;
#[derive(Debug)]
pub struct OffscreenCanvasWrapper(SendSyncWrapper<OffscreenCanvas>);
impl OffscreenCanvasWrapper {
pub fn new(canvas: OffscreenCanvas) -> Self {
OffscreenCanvasWrapper(SendSyncWrapper(canvas))
}
}
impl Deref for OffscreenCanvasWrapper {
type Target = OffscreenCanvas;
fn deref(&self) -> &Self::Target {
&self.0.0
}
}
impl DerefMut for OffscreenCanvasWrapper {
fn deref_mut(&mut self) -> &mut OffscreenCanvas {
&mut self.0.0
}
}
#[derive(Debug, Clone)]
pub struct OffscreenCanvas {
inner: web_sys::OffscreenCanvas,
pub scale_factor: f32,
handle: u32,
}
#[allow(dead_code)]
impl OffscreenCanvas {
pub const fn new(canvas: web_sys::OffscreenCanvas, scale_factor: f32, handle: u32) -> Self {
Self {
inner: canvas,
scale_factor,
handle,
}
}
pub fn each(self) -> (web_sys::OffscreenCanvas, u32) {
(self.inner, self.handle)
}
pub fn physical_resolution(&self) -> (u32, u32) {
let width = self.inner.width();
let height = self.inner.height();
(width, height)
}
}
impl From<&Canvas> for OffscreenCanvas {
fn from(value: &Canvas) -> Self {
let offscreen = value.element.transfer_control_to_offscreen().unwrap();
let handle = value.handle;
Self::new(offscreen, value.scale_factor, handle)
}
}
impl HasWindowHandle for OffscreenCanvasWrapper {
fn window_handle(
&self,
) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
use raw_window_handle::{RawWindowHandle, WebOffscreenCanvasWindowHandle, WindowHandle};
let value: &JsValue = &self.inner;
let obj: NonNull<core::ffi::c_void> = NonNull::from(value).cast();
let handle = WebOffscreenCanvasWindowHandle::new(obj);
let raw = RawWindowHandle::WebOffscreenCanvas(handle);
unsafe { Ok(WindowHandle::borrow_raw(raw)) }
}
}
impl HasDisplayHandle for OffscreenCanvasWrapper {
fn display_handle(
&self,
) -> Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError> {
use raw_window_handle::{DisplayHandle, RawDisplayHandle, WebDisplayHandle};
let handle = WebDisplayHandle::new();
let raw = RawDisplayHandle::Web(handle);
unsafe { Ok(DisplayHandle::borrow_raw(raw)) }
}
}