diff --git a/Cargo.lock b/Cargo.lock index 6cd7ecf1b..4489cddd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1128,7 +1128,7 @@ dependencies = [ "craft-drawingml", "craft-math", "craft-offcrypto", - "craft-opc", + "craft-opc 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad6057faf36365fbba736cf)", "craft-wordmodel", "craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad6057faf36365fbba736cf)", "log", @@ -1306,6 +1306,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "craft-opc" +version = "0.1.0" +source = "git+https://github.com/storytold/craft-libs?rev=8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551#8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551" +dependencies = [ + "craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551)", + "craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551)", + "log", + "thiserror 2.0.21", +] + [[package]] name = "craft-opc" version = "0.1.0" @@ -1492,7 +1503,7 @@ version = "0.1.0" source = "git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad6057faf36365fbba736cf#ba24fe2435adb3c81ad6057faf36365fbba736cf" dependencies = [ "craft-drawingml", - "craft-opc", + "craft-opc 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad6057faf36365fbba736cf)", "craft-sheet", "craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad6057faf36365fbba736cf)", "thiserror 2.0.21", @@ -1938,6 +1949,7 @@ name = "designcraft-pptx" version = "0.20.1" dependencies = [ "chrono", + "craft-opc 0.1.0 (git+https://github.com/storytold/craft-libs?rev=8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551)", "designcraft-color", "designcraft-compose", "designcraft-doc", diff --git a/Cargo.toml b/Cargo.toml index ca146fb5e..9dbba9581 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ craft-csv = { git = "https://github.com/storytold/craft-libs", rev = "47bf5650b0 craft-image-codecs = { git = "https://github.com/storytold/craft-libs", rev = "a47b78256c6acf3d7fdc4bc7cfbc25c373eac522", version = "=0.1.0" } craft-psd = { git = "https://github.com/storytold/craft-libs", rev = "a47b78256c6acf3d7fdc4bc7cfbc25c373eac522", version = "=0.1.0" } craft-file-formats = { git = "https://github.com/storytold/craft-libs", rev = "8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551", version = "=0.1.0" } +craft-opc = { git = "https://github.com/storytold/craft-libs", rev = "8abfa9d0f14bafbfc3449fc552ffeafb9ca6a551", version = "=0.1.0" } # Shared keyboard bindings: chords, overrides, conflicts, egui dispatch, the Keyboard Shortcuts dialog. craft-keymap = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.1.0", features = ["egui", "ui"] } # Separations, ink coverage and the ink manager; same revision as craft-pdf and the krilla patch. diff --git a/crates/pptx/Cargo.toml b/crates/pptx/Cargo.toml index afc90c69c..c81e72d48 100644 --- a/crates/pptx/Cargo.toml +++ b/crates/pptx/Cargo.toml @@ -18,9 +18,10 @@ designcraft-images = { workspace = true } skrifa = { workspace = true } image = { workspace = true } thiserror = { workspace = true } -zip = { workspace = true } +craft-opc = { workspace = true } chrono = { workspace = true } [dev-dependencies] +zip = { workspace = true } designcraft-fonts = { workspace = true, features = ["testing"] } quick-xml = { workspace = true } diff --git a/crates/pptx/src/package.rs b/crates/pptx/src/package.rs index 7e9e123e0..5ff1fa160 100644 --- a/crates/pptx/src/package.rs +++ b/crates/pptx/src/package.rs @@ -1,11 +1,9 @@ //! The PresentationML package: one blank master and layout, a theme, the slides and their media. -use std::fmt::Write as _; -use std::io::Write as _; - use crate::fonts::EmbeddedFont; use crate::xml::{emu_len, esc}; use crate::{PptxError, Result}; +use std::fmt::Write as _; pub const NS: &str = r#"xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main""#; const DECL: &str = "\n"; @@ -241,26 +239,10 @@ pub fn write(p: &Package) -> Result> { ), ); - let mut zw = zip::ZipWriter::new(std::io::Cursor::new(Vec::new())); - let deflate = zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Deflated); - let stored = zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); - let zerr = |e: zip::result::ZipError| PptxError::Write(e.to_string()); - let ioerr = |e: std::io::Error| PptxError::Write(e.to_string()); - for (name, bytes) in &parts { - zw.start_file(name.as_str(), deflate).map_err(zerr)?; - zw.write_all(bytes).map_err(ioerr)?; - } - for (name, bytes) in &font_parts { - zw.start_file(name.as_str(), deflate).map_err(zerr)?; - zw.write_all(bytes).map_err(ioerr)?; - } - for m in p.media { - // Compressed formats gain nothing from deflate. - let opts = if m.name.ends_with(".svg") { deflate } else { stored }; - zw.start_file(format!("ppt/media/{}", m.name), opts).map_err(zerr)?; - zw.write_all(&m.bytes).map_err(ioerr)?; - } - Ok(zw.finish().map_err(zerr)?.into_inner()) + let mut entries = parts; + entries.extend(font_parts.into_iter().map(|(name, bytes)| (name, bytes.to_vec()))); + entries.extend(p.media.iter().map(|m| (format!("ppt/media/{}", m.name), m.bytes.clone()))); + craft_opc::zip_entries(&entries).map_err(|e| PptxError::Write(e.to_string())) } fn rel_kind(k: &str) -> &'static str {