AF.3: open .afphoto by content without listing it for Finder

The macOS bundle must declare every File › Open extension, and the
packaging of a vector app must not mention raster-editor files. Affinity
Photo documents still open and place: the reader recognizes them by
their content, and a test checks it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
This commit is contained in:
callmeBallochandClaude Opus 5.5 authored and Claude committed 2026-10-08 19:13:50 +00:00
1 parent 2b4d8f4074
commit 2e55ce6d5b
4 files changed
+8 -6

No files matched your search

Generated
+1 -1
View File
@@ -4335,7 +4335,7 @@ dependencies = [
[[package]]
name = "vectorcraft-affinity"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"crc32fast",
"flate2",
+1 -1
View File
@@ -194,7 +194,7 @@ milestones, and honest time-to-parity estimates.
"a power user can't tell the difference". Everyday vector illustration is close to usable: drawing and path tools,
Pathfinder and Shape Builder, paint, gradients, appearance and transparency, type with styles, threading and Hebrew/Arabic bidirectional layout, and
files (SVG, PDF and PDF-compatible `.ai` with PDF/X, EPS, DXF, EMF/WMF, raster formats and PSD, Print, Package).
Affinity documents (`.af` from Affinity 3, `.afdesign`, `.afphoto` and `.afpub` from Affinity 1 and 2) open
Affinity documents (`.af` from Affinity 3, `.afdesign`, `.afpub` and, by their content, `.afphoto` from Affinity 1 and 2) open
and place natively: layers, groups, artboards and pages, curves and shapes, fills, gradients and strokes, clipping
and masks, text and images, with what didn't come in (effects, adjustments, brushes, master pages…) listed in the
import warning; a file whose native data can't be read opens as its embedded preview, saying why. VectorCraft
+3 -3
View File
@@ -556,7 +556,9 @@ pub const FORMATS: &[Format] = &[
Format { id: "wmf", label: "WMF", extensions: &["wmf"], mime: "image/wmf", read: true, write: true, raster: false, options: metafile::OPTIONS },
Format { id: "tga", label: "Targa", extensions: &["tga"], mime: "image/x-tga", read: false, write: true, raster: true, options: TGA_OPTIONS },
Format { id: "psd", label: "PSD", extensions: &["psd"], mime: "image/x-psd", read: false, write: true, raster: true, options: PSD_OPTIONS },
reader("affinity", "Affinity", &["af", "afdesign", "afphoto", "afpub"], "application/vnd.affinity", false),
// Affinity Photo's `.afphoto` opens by its content but isn't listed: Finder shouldn't offer a
// vector app for a raster editor's documents.
reader("affinity", "Affinity", &["af", "afdesign", "afpub"], "application/vnd.affinity", false),
];
/// Every extension `document.open` reads (the "All readable files" filter of open dialogs).
@@ -583,7 +585,6 @@ pub const OPEN_EXTS: &[&str] = &[
"eps",
"af",
"afdesign",
"afphoto",
"afpub",
];
@@ -626,7 +627,6 @@ pub const PLACE_EXTS: &[&str] = &[
"eps",
"af",
"afdesign",
"afphoto",
"afpub",
"txt",
];
@@ -57,7 +57,7 @@ fn preview_opens_with_a_warning_and_never_saves_to_the_source() {
}
let f = format("affinity").unwrap();
assert!(f.read && !f.write);
for ext in ["af", "afdesign", "afphoto", "afpub"] {
for ext in ["af", "afdesign", "afpub"] {
assert!(OPEN_EXTS.contains(&ext) && PLACE_EXTS.contains(&ext), "{ext}");
}
assert!(!SAVE_FORMATS.contains(&"affinity"));
@@ -271,6 +271,8 @@ mod native {
let mut s = Session::new();
let r = open_bytes(&mut s, "native.af", &document(method), Some("/source/native.af".into())).unwrap();
assert_eq!(r["format"], "affinity");
// Affinity Photo's extension isn't listed, but its documents still open by their content.
assert_eq!(open_bytes(&mut Session::new(), "native.afphoto", &document(method), None).unwrap()["format"], "affinity");
assert!(r["warnings"].as_array().unwrap().iter().all(|w| !w.as_str().unwrap().contains("preview")), "{r}");
let st = s.doc().unwrap();
assert!(st.path.is_none(), "Save must not write back over the Affinity file");