diff --git a/Cargo.lock b/Cargo.lock index f2861501..3b92e7fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2441,6 +2441,7 @@ dependencies = [ "indexmap", "pdf-writer", "png", + "rayon", "rustc-hash 2.1.3", "rustybuzz", "siphasher", diff --git a/crates/pdf/Cargo.toml b/crates/pdf/Cargo.toml index 50f9adbd..24298af0 100644 --- a/crates/pdf/Cargo.toml +++ b/crates/pdf/Cargo.toml @@ -18,3 +18,8 @@ kurbo = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } log = { workspace = true } + +# Off the web build, krilla compresses each slide's artwork on a background thread while the next +# slide renders (the same bytes, in parallel). +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +krilla = { workspace = true, features = ["rayon"] } diff --git a/crates/pdf/src/lib.rs b/crates/pdf/src/lib.rs index 65f42de2..f55a9e0a 100644 --- a/crates/pdf/src/lib.rs +++ b/crates/pdf/src/lib.rs @@ -269,7 +269,9 @@ impl Exporter<'_> { let scale = (b.width() / 72.0 * self.opts.dpi.clamp(36.0, 600.0)) / sw; let img = deckcraft_render::render_slide(pres, i, &RenderOpts { scale, threads: 4, ..Default::default() }); if img.width > 0 && img.height > 0 { - let mut rgba = img.pixels.clone(); + let (w, h) = (img.width, img.height); + // Taken, not copied: a print-resolution slide is ~16 MB. + let mut rgba = img.pixels; for px in rgba.as_chunks_mut::<4>().0 { // Composite onto white (slides are normally opaque). let a = px[3] as u32; @@ -278,7 +280,7 @@ impl Exporter<'_> { } px[3] = 255; } - let image = Image::from_rgba8(rgba, img.width, img.height); + let image = Image::from_rgba8(rgba, w, h); if let Some(size) = Size::from_wh(b.width() as f32, b.height() as f32) { s.push_transform(&Transform::from_translate(b.x0 as f32, b.y0 as f32)); s.draw_image(image, size);