diff --git a/Cargo.lock b/Cargo.lock index d5c2537..2c78b55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -935,6 +935,7 @@ dependencies = [ "designcraft-format", "designcraft-geom", "designcraft-idml", + "designcraft-images", "designcraft-pdf", "designcraft-render", "designcraft-textimport", diff --git a/ROADMAP.md b/ROADMAP.md index 97bb107..c6629b1 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -97,6 +97,7 @@ DesignCraft aims at full Adobe InDesign parity — and to be better: faster, ope - Interface language (Edit ▸ Interface Language, `app.language`): German, French, Spanish and Japanese menu titles, common menu items and panel names (our own translations); dialogs and the rest of the UI stay English. - Page transitions (`page.transition/transitions`, Page Transitions panel): twelve transition types with speed and direction per spread, written into exported PDFs as `/Trans` entries through an incremental update. - PDF/X-4 export (`file.exportPdf {standard: "x4"}`): an output intent with our own Generic CMYK ICC profile (lut16 tables generated from the parametric press model), GTS_PDFXVersion in Info and XMP, and built-in PDF/X-4 checks reported as warnings. qpdf finds no errors in the result. +- EPS place: placed at its (high-resolution) bounding box and shown, printed and exported through its TIFF preview, or a placeholder when it has none. PostScript itself isn't interpreted. - Drag and drop text editing: drag selected text to move it (Alt copies) with its formatting (`text.release`). - Image Import Options: place any page of a multi-page PDF (`file.place {pdfPage}`; the app asks which page), shown on screen and embedded as that page in PDF export. - Define Lists: named numbered lists that continue across stories in page order (`list.define`, paragraph `listName` / `startAt`), round-tripped through IDML; `null` in `type.para` / `type.char` now removes an override. diff --git a/apps/designcraft/src/main.rs b/apps/designcraft/src/main.rs index c8f5341..2606072 100644 --- a/apps/designcraft/src/main.rs +++ b/apps/designcraft/src/main.rs @@ -115,6 +115,7 @@ fn services() -> Services { "svg", "pdf", "ai", + "eps", "txt", "docx", "rtf", @@ -132,7 +133,7 @@ fn services() -> Services { "ogg", ], ) - .add_filter("Graphics", &["png", "jpg", "jpeg", "gif", "webp", "tif", "tiff", "bmp", "psd", "svg", "pdf", "ai"]) + .add_filter("Graphics", &["png", "jpg", "jpeg", "gif", "webp", "tif", "tiff", "bmp", "psd", "svg", "pdf", "ai", "eps"]) .add_filter("Text (Word, RTF, plain, Excel)", &["docx", "rtf", "txt", "md", "xlsx"]) .add_filter("Video and sound", &["mp4", "m4v", "mov", "webm", "mp3", "m4a", "wav", "ogg"]) } else { diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index aed43dc..4779435 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -9,6 +9,7 @@ description = "DesignCraft engine: session, documents, history, selection, comma workspace = true [dependencies] +designcraft-images = { workspace = true } designcraft-geom = { workspace = true } designcraft-color = { workspace = true } designcraft-doc = { workspace = true } diff --git a/crates/engine/src/cmd/file.rs b/crates/engine/src/cmd/file.rs index a86d025..3924035 100644 --- a/crates/engine/src/cmd/file.rs +++ b/crates/engine/src/cmd/file.rs @@ -219,6 +219,13 @@ fn file_place(s: &mut Session, p: &Value) -> Result { if lname.ends_with(".idml") || lname.ends_with(".designcraft") { return place_layout_page(s, p, &name, &bytes); } + // EPS: shown and printed through its preview (or a placeholder) at its bounding box size. + let (bytes, eps_size) = if designcraft_images::is_eps(&bytes) { + let (proxy, size) = designcraft_images::eps_proxy(&bytes).ok_or_else(|| bad("file.place", "the EPS has no bounding box"))?; + (proxy, Some(size)) + } else { + (bytes, None) + }; // Video and sound: a media frame (Window › Interactive › Media). if let Some(mime) = designcraft_doc::media_mime(&name) { return super::media::place_media(s, p, name, mime, bytes, link); @@ -245,7 +252,7 @@ fn file_place(s: &mut Session, p: &Value) -> Result { .ok_or_else(|| bad("file.place", "can't read that PDF page"))?, }; // 72 ppi by default unless the file says otherwise; scale so it fits the page when huge. - let (nw, nh) = (pw as f64, ph as f64); + let (nw, nh) = eps_size.unwrap_or((pw as f64, ph as f64)); // Image Import Options › Crop to: the frame shows that box of the PDF page. let crop_box = match str_param(p, "pdfCrop") { Some(k) if designcraft_render::is_pdf(&bytes) => { diff --git a/crates/engine/src/cmd/media.rs b/crates/engine/src/cmd/media.rs index 6eb7564..0b7517f 100644 --- a/crates/engine/src/cmd/media.rs +++ b/crates/engine/src/cmd/media.rs @@ -184,4 +184,17 @@ mod tests { let x = read("OEBPS/content.xhtml"); assert!(x.contains("