From 2be04fd23c9650820fa5abd1196647ccf1b73921 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Tue, 15 Nov 2011 19:05:59 +0000 Subject: 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. --- apps/pdfclean.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'apps') 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); + } } /* -- cgit v1.2.3