mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-04 06:59:56 -06:00
New crates/metafile (L3, pure Rust): hand-written EMF and WMF writers over
one shared document walk. EMF keeps Bezier paths, solid brushes, geometric
pens (width, caps, joins, miter limit, user-style dashes), clipping masks as
path clips, images (StretchDIBits, or AlphaBlend with transparency) placed by
a world transform, type as outlines; gradients become images clipped to their
shape and pattern fills their tiles clipped to it. The header's frame is the
artboard in 0.01 mm on a 100 px/mm reference device. WMF flattens curves into
polygons in 16-bit units behind a placeable header (with its checksum),
numbers objects as players do, and reports what it leaves out (clipping,
transparency, gradients, rotated images).
document.export {format: emf|wmf} (and serialize, export) writes one artboard,
or one file per artboard with useArtboards (false: the art's bounds); raster
effects are rendered to images first, as for PDF. Export As lists EMF and WMF.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
38 lines
1.4 KiB
Rust
38 lines
1.4 KiB
Rust
//! Export As → EMF and WMF, drawn headlessly: listed with the other formats, written straight
|
|
//! away (no options dialog), one file per artboard with Use Artboards.
|
|
|
|
use serde_json::json;
|
|
|
|
use super::tests_export::{app, frame, kind, names, set};
|
|
use super::*;
|
|
|
|
/// Does `b` carry the EMF header's signature, or start with the placeable WMF key?
|
|
fn is_emf(b: &[u8]) -> bool {
|
|
b.get(40..44) == Some(&b" EMF"[..])
|
|
}
|
|
|
|
fn is_wmf(b: &[u8]) -> bool {
|
|
b.get(..4) == Some(&[0xD7, 0xCD, 0xC6, 0x9A][..])
|
|
}
|
|
|
|
#[test]
|
|
fn export_as_lists_emf_and_wmf_and_writes_them() {
|
|
let (mut app, written) = app(2);
|
|
app.run("file.exportAs", json!({"format": "emf"})).unwrap();
|
|
assert_eq!(kind(&app), Some("exportAs"));
|
|
assert_eq!(app.ui.dialog.as_ref().unwrap().str("format"), "emf");
|
|
frame(&mut app);
|
|
let r = confirm(&mut app).unwrap();
|
|
assert!(app.ui.dialog.is_none(), "no options dialog follows");
|
|
assert_eq!(r["path"], "/out/Untitled-1.emf");
|
|
assert!(is_emf(&written.borrow()[0].1));
|
|
// WMF, one file per artboard.
|
|
app.run("file.exportAs", json!({"format": "wmf"})).unwrap();
|
|
set(&mut app, "useArtboards", json!(true));
|
|
frame(&mut app);
|
|
confirm(&mut app).unwrap();
|
|
let n = names(&written);
|
|
assert_eq!(&n[1..], ["/out/Untitled-1-Artboard-1.wmf", "/out/Untitled-1-Artboard-2.wmf"]);
|
|
assert!(written.borrow()[1..].iter().all(|(_, b)| is_wmf(b)));
|
|
}
|