From a14c8288f3160f6ff55db61829c3efa918951f1c Mon Sep 17 00:00:00 2001 From: Jiayi Zhuang Date: Tue, 19 Aug 2025 08:48:49 +0800 Subject: [PATCH 1/3] feat(canvas): add scale factor to canvas options --- src/backend/canvas.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/backend/canvas.rs b/src/backend/canvas.rs index 33dea067..64aade85 100644 --- a/src/backend/canvas.rs +++ b/src/backend/canvas.rs @@ -35,12 +35,14 @@ const CELL_WIDTH: f64 = 10.0; const CELL_HEIGHT: f64 = 19.0; /// Options for the [`CanvasBackend`]. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct CanvasBackendOptions { /// The element ID. grid_id: Option, /// Override the automatically detected size. size: Option<(u32, u32)>, + /// Scale factor for the canvas. + scale: f64, /// Always clip foreground drawing to the cell rectangle. Helpful when /// dealing with out-of-bounds rendering from problematic fonts. Enabling /// this option may cause some performance issues when dealing with large @@ -48,6 +50,17 @@ pub struct CanvasBackendOptions { always_clip_cells: bool, } +impl Default for CanvasBackendOptions { + fn default() -> Self { + Self { + grid_id: None, + size: None, + scale: 1.0, + always_clip_cells: false, + } + } +} + impl CanvasBackendOptions { /// Constructs a new [`CanvasBackendOptions`]. pub fn new() -> Self { @@ -65,6 +78,12 @@ impl CanvasBackendOptions { self.size = Some(size); self } + + /// Sets the scale factor for the canvas. + pub fn scale(mut self, scale: f64) -> Self { + self.scale = scale; + self + } } /// Canvas renderer. @@ -84,9 +103,13 @@ impl Canvas { parent_element: web_sys::Element, width: u32, height: u32, + scale: f64, background_color: Color, ) -> Result { - let canvas = create_canvas_in_element(&parent_element, width, height)?; + let inner_width = (width as f64 * scale) as u32; + let inner_height = (height as f64 * scale) as u32; + let canvas = create_canvas_in_element(&parent_element, inner_width, inner_height)?; + canvas.set_attribute("style", &format!("width: {width}px; height: {height}px;"))?; let context_options = Map::new(); context_options.set(&JsValue::from_str("alpha"), &Boolean::from(JsValue::TRUE)); @@ -101,6 +124,9 @@ impl Canvas { .expect("Unable to cast canvas context"); context.set_font("16px monospace"); context.set_text_baseline("top"); + context + .scale(scale, scale) + .expect("Failed to scale canvas context"); Ok(Self { inner: canvas, @@ -162,7 +188,7 @@ impl CanvasBackend { .size .unwrap_or_else(|| (parent.client_width() as u32, parent.client_height() as u32)); - let canvas = Canvas::new(parent, width, height, Color::Black)?; + let canvas = Canvas::new(parent, width, height, options.scale, Color::Black)?; let buffer = get_sized_buffer_from_canvas(&canvas.inner); let changed_cells = bitvec![0; buffer.len() * buffer[0].len()]; Ok(Self { From 101a1067ad31ffdf06e02c9f30197861fc7b977d Mon Sep 17 00:00:00 2001 From: Jiayi Zhuang Date: Mon, 8 Sep 2025 09:01:53 +0800 Subject: [PATCH 2/3] chore: improve error handling in scale factor settings --- src/backend/canvas.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/backend/canvas.rs b/src/backend/canvas.rs index 64aade85..e652ec5a 100644 --- a/src/backend/canvas.rs +++ b/src/backend/canvas.rs @@ -80,7 +80,14 @@ impl CanvasBackendOptions { } /// Sets the scale factor for the canvas. + /// + /// # Panics + /// + /// Panics if `scale` is not positive. pub fn scale(mut self, scale: f64) -> Self { + if scale <= 0.0 { + panic!("Scale must be greater than 0"); + } self.scale = scale; self } @@ -124,9 +131,7 @@ impl Canvas { .expect("Unable to cast canvas context"); context.set_font("16px monospace"); context.set_text_baseline("top"); - context - .scale(scale, scale) - .expect("Failed to scale canvas context"); + context.scale(scale, scale)?; Ok(Self { inner: canvas, From dea1accb28f99a591d6f4e634a2be8cefd92ad22 Mon Sep 17 00:00:00 2001 From: Jiayi Zhuang Date: Mon, 8 Sep 2025 09:03:20 +0800 Subject: [PATCH 3/3] chore: improve the document of scale factor --- src/backend/canvas.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/backend/canvas.rs b/src/backend/canvas.rs index e652ec5a..165c29e1 100644 --- a/src/backend/canvas.rs +++ b/src/backend/canvas.rs @@ -41,7 +41,16 @@ pub struct CanvasBackendOptions { grid_id: Option, /// Override the automatically detected size. size: Option<(u32, u32)>, - /// Scale factor for the canvas. + /// Scale factor for the canvas. Setting this to a value greater than 1.0 + /// will improve the rendering quality on high-DPI displays, at the cost + /// of performance. + /// + /// The memory usage of the canvas will increase with the square of the scale factor. + /// For example, a scale factor of 2.0 will use 4 times the memory. + /// + /// The default value is 1.0. + /// + /// Generally, a scale factor of 2.0 is a good compromise between quality and performance. scale: f64, /// Always clip foreground drawing to the cell rectangle. Helpful when /// dealing with out-of-bounds rendering from problematic fonts. Enabling @@ -79,7 +88,16 @@ impl CanvasBackendOptions { self } - /// Sets the scale factor for the canvas. + /// Sets the scale factor for the canvas. Setting this to a value greater than 1.0 + /// will improve the rendering quality on high-DPI displays, at the cost + /// of performance. + /// + /// The memory usage of the canvas will increase with the square of the scale factor. + /// For example, a scale factor of 2.0 will use 4 times the memory. + /// + /// The default value is 1.0. + /// + /// Generally, a scale factor of 2.0 is a good compromise between quality and performance. /// /// # Panics ///