Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions src/backend/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,32 @@ 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<String>,
/// 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
/// numbers of simultaneous changes.
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 {
Expand All @@ -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.
Expand All @@ -84,9 +103,13 @@ impl Canvas {
parent_element: web_sys::Element,
width: u32,
height: u32,
scale: f64,
background_color: Color,
) -> Result<Self, Error> {
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));
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down