mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
This commit is contained in:
1 parent
eb75e5a9d9
commit
6fd053b918
2 files changed
+52
-1
No files matched your search
@@ -195,7 +195,7 @@ pub fn delete_pages(doc: &mut Document, indices: &[usize]) -> Result<(), Organiz
|
||||
}
|
||||
|
||||
/// Bookmarks, and links on the `keep` pages, that go to one of the `gone` pages lose that
|
||||
/// destination (/Dest, or a GoTo /A), rather than pointing at nothing.
|
||||
/// destination (/Dest, or a GoTo /A), rather than pointing at nothing; so does the catalog's /OpenAction.
|
||||
fn drop_destinations_to(doc: &mut Document, gone: &[ObjRef], keep: &[(ObjRef, Dict)]) -> Result<(), OrganizeError> {
|
||||
let mut holders = outline::items(doc);
|
||||
for (p, _) in keep {
|
||||
@@ -222,6 +222,18 @@ fn drop_destinations_to(doc: &mut Document, gone: &[ObjRef], keep: &[(ObjRef, Di
|
||||
dead.push((h, b"A"));
|
||||
}
|
||||
}
|
||||
// The catalog's /OpenAction is either a destination array or a GoTo action; one that opens a
|
||||
// deleted page is dropped, as a bookmark's would be.
|
||||
if let Some(root) = doc.root() {
|
||||
let open = doc.get(root).as_dict().and_then(|c| c.get(b"OpenAction").map(|o| doc.resolve(o)));
|
||||
let opens_gone = match open.as_deref() {
|
||||
Some(Object::Dict(a)) => a.name(b"S") == Some(b"GoTo") && to_gone(a.get(b"D")),
|
||||
other => to_gone(other),
|
||||
};
|
||||
if opens_gone {
|
||||
dead.push((root, b"OpenAction"));
|
||||
}
|
||||
}
|
||||
for (h, key) in dead {
|
||||
doc.update_dict(h, |d| {
|
||||
d.remove(key);
|
||||
|
||||
@@ -170,6 +170,45 @@ fn deleted_pages_are_not_kept_by_what_points_at_them() {
|
||||
assert_eq!(form.as_dict().and_then(|f| f.get(b"Fields")).and_then(Object::as_array).map(Vec::len), Some(0), "the field went with its page");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deleting_the_opening_page_drops_the_open_action() {
|
||||
let open_action = |doc: &Document| doc.get(doc.root().unwrap()).as_dict().unwrap().get(b"OpenAction").cloned();
|
||||
let set_open = |doc: &mut Document, value: Object| {
|
||||
let root = doc.root().unwrap();
|
||||
doc.update_dict(root, |c| c.set(b"OpenAction".to_vec(), value)).unwrap();
|
||||
};
|
||||
let page = |doc: &Document, i: usize| pages(doc).unwrap()[i].obj;
|
||||
for as_action in [false, true] {
|
||||
let target = |doc: &Document, i: usize| {
|
||||
let dest = Object::Array(vec![Object::Ref(page(doc, i)), Object::Name(b"Fit".to_vec())]);
|
||||
if as_action {
|
||||
let mut a = Dict::new();
|
||||
a.set(b"S".to_vec(), Object::Name(b"GoTo".to_vec()));
|
||||
a.set(b"D".to_vec(), dest);
|
||||
Object::Dict(a)
|
||||
} else {
|
||||
dest
|
||||
}
|
||||
};
|
||||
// The opening page goes: no OpenAction is left to point at nothing.
|
||||
let mut doc = doc_a();
|
||||
let open = target(&doc, 0);
|
||||
set_open(&mut doc, open);
|
||||
delete_pages(&mut doc, &[0]).unwrap();
|
||||
let out = full_roundtrip(&doc);
|
||||
assert_eq!(labels(&out), ["A2", "A3"]);
|
||||
assert_eq!(open_action(&out), None);
|
||||
// Another page goes: the opening page keeps its OpenAction.
|
||||
let mut doc = doc_a();
|
||||
let open = target(&doc, 0);
|
||||
set_open(&mut doc, open);
|
||||
delete_pages(&mut doc, &[2]).unwrap();
|
||||
let out = full_roundtrip(&doc);
|
||||
assert_eq!(labels(&out), ["A1", "A2"]);
|
||||
assert!(open_action(&out).is_some());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_delete_every_page_or_missing_pages() {
|
||||
let mut doc = open(fixture());
|
||||
|
||||
Reference in new issue
Block a user