From 5c10104d91c840aa90485fd61aff983a516da157 Mon Sep 17 00:00:00 2001 From: Toniman575 Date: Tue, 28 Feb 2023 14:16:48 +0100 Subject: [PATCH 1/2] added `from_canvas` methods to `Surface` --- Cargo.toml | 2 +- src/lib.rs | 20 ++++++++++++++++++++ src/web.rs | 42 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 60be9003..98f4e43b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ wasm-bindgen = "0.2.78" [target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] version = "0.3.55" -features = ["CanvasRenderingContext2d", "Document", "Element", "HtmlCanvasElement", "ImageData", "Window"] +features = ["CanvasRenderingContext2d", "Document", "Element", "HtmlCanvasElement", "ImageData", "OffscreenCanvas", "Window"] [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.3" diff --git a/src/lib.rs b/src/lib.rs index 6e424a3b..f7b06cb0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -235,6 +235,26 @@ impl Surface { }) } + #[cfg(target_arch = "wasm32")] + pub fn from_canvas(canvas: web_sys::HtmlCanvasElement) -> Result { + let imple = SurfaceDispatch::Web(web::WebImpl::from_canvas(canvas)?); + + Ok(Self { + surface_impl: Box::new(imple), + }) + } + + #[cfg(target_arch = "wasm32")] + pub fn from_offscreen_canvas( + offscreen_canvas: web_sys::OffscreenCanvas, + ) -> Result { + let imple = SurfaceDispatch::Web(web::WebImpl::from_offscreen_canvas(offscreen_canvas)?); + + Ok(Self { + surface_impl: Box::new(imple), + }) + } + /// Shows the given buffer with the given width and height on the window corresponding to this /// graphics context. Panics if buffer.len() ≠ width*height. If the size of the buffer does /// not match the size of the window, the buffer is drawn in the upper-left corner of the window. diff --git a/src/web.rs b/src/web.rs index f0e9f3d9..f3266339 100644 --- a/src/web.rs +++ b/src/web.rs @@ -4,6 +4,7 @@ use wasm_bindgen::JsCast; use web_sys::CanvasRenderingContext2d; use web_sys::HtmlCanvasElement; use web_sys::ImageData; +use web_sys::OffscreenCanvas; use crate::SoftBufferError; @@ -35,8 +36,13 @@ impl WebDisplayImpl { } } +enum Canvas { + HtmlCanvasElement(HtmlCanvasElement), + OffscreenCanvas(OffscreenCanvas), +} + pub struct WebImpl { - canvas: HtmlCanvasElement, + canvas: Canvas, ctx: CanvasRenderingContext2d, } @@ -56,8 +62,26 @@ impl WebImpl { // We already made sure this was a canvas in `querySelector`. .unchecked_into(); - let ctx = canvas - .get_context("2d") + Self::new_internal(Canvas::HtmlCanvasElement(canvas)) + } + + pub(crate) fn from_canvas(canvas: HtmlCanvasElement) -> Result { + Self::new_internal(Canvas::HtmlCanvasElement(canvas)) + } + + pub(crate) fn from_offscreen_canvas( + offscreen_canvas: OffscreenCanvas, + ) -> Result { + Self::new_internal(Canvas::OffscreenCanvas(offscreen_canvas)) + } + + fn new_internal(canvas: Canvas) -> Result { + let ctx = match &canvas { + Canvas::HtmlCanvasElement(canvas) => canvas.get_context("2d"), + Canvas::OffscreenCanvas(canvas) => canvas.get_context("2d"), + }; + + let ctx = ctx .map_err(|_| { SoftBufferError::PlatformError( Some("Canvas already controlled using `OffscreenCanvas`".into()), @@ -77,8 +101,16 @@ impl WebImpl { } pub(crate) unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) { - self.canvas.set_width(width.into()); - self.canvas.set_height(height.into()); + match &self.canvas { + Canvas::HtmlCanvasElement(canvas) => { + canvas.set_width(width.into()); + canvas.set_height(height.into()); + } + Canvas::OffscreenCanvas(canvas) => { + canvas.set_width(width.into()); + canvas.set_height(height.into()); + } + } let bitmap: Vec<_> = buffer .iter() From 0182e78361629426d8b15e2a14f0d466d19679c9 Mon Sep 17 00:00:00 2001 From: Toniman575 Date: Tue, 28 Feb 2023 14:25:12 +0100 Subject: [PATCH 2/2] added documentation --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f7b06cb0..addfec96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -235,6 +235,7 @@ impl Surface { }) } + /// Creates a new instance of this struct, using the provided [`HtmlCanvasElement`](web_sys::HtmlCanvasElement). #[cfg(target_arch = "wasm32")] pub fn from_canvas(canvas: web_sys::HtmlCanvasElement) -> Result { let imple = SurfaceDispatch::Web(web::WebImpl::from_canvas(canvas)?); @@ -244,6 +245,7 @@ impl Surface { }) } + /// Creates a new instance of this struct, using the provided [`HtmlCanvasElement`](web_sys::OffscreenCanvas). #[cfg(target_arch = "wasm32")] pub fn from_offscreen_canvas( offscreen_canvas: web_sys::OffscreenCanvas,