mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 12:32:52 +00:00
M5: an exported appearance leaves the source page out (comment.export-fdf-xfdf)
A page or page tree reached from a comment's appearance is written as NULL in <appearance>, as FDF export already nulls source /Page and /Pages dictionaries, so the XFDF never carries the document's pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
This commit is contained in:
1 parent
a90502f2c9
commit
6ae0527883
2 files changed
+23
No files matched your search
@@ -120,6 +120,12 @@ impl Writer<'_> {
|
||||
}
|
||||
self.out.push_str("</ARRAY>\n");
|
||||
}
|
||||
// A page (or the page tree) reached from the appearance is the source document's, not
|
||||
// the comment's: written in place it would carry every page along.
|
||||
Object::Dict(d) if matches!(d.name(b"Type"), Some(b"Page" | b"Pages")) => self.out.push_str(&format!(
|
||||
"<NULL{k}/>
|
||||
"
|
||||
)),
|
||||
Object::Dict(d) => self.dict(key, d, depth)?,
|
||||
Object::Stream(s) => {
|
||||
// The data plus its hexadecimal form must fit what is left of the budget.
|
||||
|
||||
@@ -567,6 +567,23 @@ fn appearance_cycles_and_strings_survive_export() {
|
||||
assert!(sub_dict(&dst, &res, b"Pattern").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_appearance_that_names_its_page_does_not_carry_the_page_along() {
|
||||
let mut src = pages(1);
|
||||
image_stamp(&mut src, "pg", "Stamp");
|
||||
let d = named(&src, "pg");
|
||||
let n = sub_dict(&src, &d, b"AP").get(b"N").and_then(Object::as_ref).unwrap();
|
||||
let page = page_ref(&src, 0);
|
||||
let Object::Stream(mut form) = (*src.get(n)).clone() else { panic!("no form") };
|
||||
form.dict.set(b"PieceInfo".to_vec(), Object::Ref(page));
|
||||
src.set(n, Object::Stream(form));
|
||||
let xml = export_xfdf(&src, true, false, "src.pdf");
|
||||
let b64: String = xml.split("<appearance>").nth(1).unwrap().split("</appearance>").next().unwrap().split_whitespace().collect();
|
||||
let inner = String::from_utf8(base64::engine::general_purpose::STANDARD.decode(b64).unwrap()).unwrap();
|
||||
assert!(inner.contains(r#"<NULL KEY="PieceInfo"/>"#), "{inner}");
|
||||
assert!(!inner.contains("Kids") && !inner.contains("MediaBox"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fdf_carries_appearances_with_their_resources() {
|
||||
let mut src = pages(1);
|
||||
|
||||
Reference in new issue
Block a user