diff options
author | Robin Watts <robin.watts@artifex.com> | 2011-11-15 19:05:59 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2011-11-17 18:32:06 +0000 |
commit | 2be04fd23c9650820fa5abd1196647ccf1b73921 (patch) | |
tree | 0828c91a4154cc8a3d4041db4f64611c43a93a2d /apps | |
parent | 9b56c6c88522b7ff6c592c93ff8ec33ee158747a (diff) | |
download | mupdf-2be04fd23c9650820fa5abd1196647ccf1b73921.tar.xz |
Bug 692487: Make pdfclean keep internal links where possible.
Take on a (cosmetically tweaked) version of Zenikos patch to allow
pdfclean to keep link destinations that are in preserved pages.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/pdfclean.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/apps/pdfclean.c b/apps/pdfclean.c index f46c4b76..b436a9cb 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -278,16 +278,18 @@ static void renumberobjs(void) static void retainpages(int argc, char **argv) { fz_error error; - fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent; + fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; /* Load the old page tree */ error = pdf_load_page_tree(xref); if (error) die(fz_rethrow(error, "cannot load page tree")); - /* Keep only pages/type entry to avoid references to unretained pages */ + /* Keep only pages/type and (reduced) dest entries to avoid + * references to unretained pages */ oldroot = fz_dict_gets(xref->trailer, "Root"); pages = fz_dict_gets(oldroot, "Pages"); + olddests = pdf_load_name_tree(xref, "Dests"); root = fz_new_dict(2); fz_dict_puts(root, "Type", fz_dict_gets(oldroot, "Type")); @@ -359,6 +361,41 @@ static void retainpages(int argc, char **argv) fz_drop_obj(countobj); fz_dict_puts(pages, "Kids", kids); fz_drop_obj(kids); + + /* Also preserve the (partial) Dests name tree */ + if (olddests) + { + int i; + fz_obj *names = fz_new_dict(1); + fz_obj *dests = fz_new_dict(1); + fz_obj *names_list = fz_new_array(32); + + for (i = 0; i < fz_dict_len(olddests); i++) + { + fz_obj *key = fz_dict_get_key(olddests, i); + fz_obj *val = fz_dict_get_val(olddests, i); + fz_obj *key_str = fz_new_string(fz_to_name(key), strlen(fz_to_name(key))); + fz_obj *dest = fz_dict_gets(val, "D"); + + dest = fz_array_get(dest ? dest : val, 0); + if (fz_array_contains(fz_dict_gets(pages, "Kids"), dest)) + { + fz_array_push(names_list, key_str); + fz_array_push(names_list, val); + } + fz_drop_obj(key_str); + } + + root = fz_dict_gets(xref->trailer, "Root"); + fz_dict_puts(dests, "Names", names_list); + fz_dict_puts(names, "Dests", dests); + fz_dict_puts(root, "Names", names); + + fz_drop_obj(names); + fz_drop_obj(dests); + fz_drop_obj(names_list); + fz_drop_obj(olddests); + } } /* |