diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/pdf/pdf-object.c | 5 | ||||
-rw-r--r-- | source/pdf/pdf-run.c | 59 | ||||
-rw-r--r-- | source/pdf/pdf-xref.c | 68 |
3 files changed, 128 insertions, 4 deletions
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c index a77f5a62..1576525e 100644 --- a/source/pdf/pdf-object.c +++ b/source/pdf/pdf-object.c @@ -1778,3 +1778,8 @@ pdf_print_ref(pdf_obj *ref) pdf_print_obj(pdf_resolve_indirect(ref)); } #endif + +int pdf_obj_refs(pdf_obj *ref) +{ + return (ref ? ref->refs : 0); +} diff --git a/source/pdf/pdf-run.c b/source/pdf/pdf-run.c index 4ac92bb0..a77dd50e 100644 --- a/source/pdf/pdf-run.c +++ b/source/pdf/pdf-run.c @@ -36,7 +36,24 @@ static void pdf_run_page_contents_with_usage(pdf_document *doc, pdf_page *page, void pdf_run_page_contents(pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie) { - pdf_run_page_contents_with_usage(doc, page, dev, ctm, "View", cookie); + fz_context *ctx = doc->ctx; + int nocache = !!(dev->hints & FZ_NO_CACHE); + + if (nocache) + pdf_mark_xref(doc); + fz_try(ctx) + { + pdf_run_page_contents_with_usage(doc, page, dev, ctm, "View", cookie); + } + fz_always(ctx) + { + if (nocache) + pdf_clear_xref_to_mark(doc); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } if (page->incomplete & PDF_PAGE_INCOMPLETE_CONTENTS) fz_throw(doc->ctx, FZ_ERROR_TRYLATER, "incomplete rendering"); } @@ -44,7 +61,24 @@ void pdf_run_page_contents(pdf_document *doc, pdf_page *page, fz_device *dev, co void pdf_run_annot(pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, fz_cookie *cookie) { - pdf_run_annot_with_usage(doc, page, annot, dev, ctm, "View", cookie); + fz_context *ctx = doc->ctx; + int nocache = !!(dev->hints & FZ_NO_CACHE); + + if (nocache) + pdf_mark_xref(doc); + fz_try(ctx) + { + pdf_run_annot_with_usage(doc, page, annot, dev, ctm, "View", cookie); + } + fz_always(ctx) + { + if (nocache) + pdf_clear_xref_to_mark(doc); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } if (page->incomplete & PDF_PAGE_INCOMPLETE_ANNOTS) fz_throw(doc->ctx, FZ_ERROR_TRYLATER, "incomplete rendering"); } @@ -78,8 +112,25 @@ static void pdf_run_page_annots_with_usage(pdf_document *doc, pdf_page *page, fz void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, char *event, fz_cookie *cookie) { - pdf_run_page_contents_with_usage(doc, page, dev, ctm, event, cookie); - pdf_run_page_annots_with_usage(doc, page, dev, ctm, event, cookie); + fz_context *ctx = doc->ctx; + int nocache = !!(dev->hints & FZ_NO_CACHE); + + if (nocache) + pdf_mark_xref(doc); + fz_try(ctx) + { + pdf_run_page_contents_with_usage(doc, page, dev, ctm, event, cookie); + pdf_run_page_annots_with_usage(doc, page, dev, ctm, event, cookie); + } + fz_always(ctx) + { + if (nocache) + pdf_clear_xref_to_mark(doc); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } if (page->incomplete) fz_throw(doc->ctx, FZ_ERROR_TRYLATER, "incomplete rendering"); } diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 1cf89de9..f9b72a4d 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -2458,3 +2458,71 @@ fz_document_handler pdf_no_run_document_handler = (fz_document_open_fn *)&pdf_open_document_no_run, (fz_document_open_with_stream_fn *)&pdf_open_document_no_run_with_stream }; + +void pdf_mark_xref(pdf_document *doc) +{ + int x, e; + + for (x = 0; x < doc->num_xref_sections; x++) + { + pdf_xref *xref = &doc->xref_sections[x]; + + for (e = 0; e < xref->len; e++) + { + pdf_xref_entry *entry = &xref->table[e]; + + if (entry->obj) + { + entry->flags |= PDF_OBJ_FLAG_MARK; + } + } + } +} + +void pdf_clear_xref(pdf_document *doc) +{ + int x, e; + + for (x = 0; x < doc->num_xref_sections; x++) + { + pdf_xref *xref = &doc->xref_sections[x]; + + for (e = 0; e < xref->len; e++) + { + pdf_xref_entry *entry = &xref->table[e]; + + if (entry->obj) + { + if (pdf_obj_refs(entry->obj) == 1) + { + pdf_drop_obj(entry->obj); + entry->obj = NULL; + } + } + } + } +} + +void pdf_clear_xref_to_mark(pdf_document *doc) +{ + int x, e; + + for (x = 0; x < doc->num_xref_sections; x++) + { + pdf_xref *xref = &doc->xref_sections[x]; + + for (e = 0; e < xref->len; e++) + { + pdf_xref_entry *entry = &xref->table[e]; + + if (entry->obj) + { + if ((entry->flags & PDF_OBJ_FLAG_MARK) == 0 && pdf_obj_refs(entry->obj) == 1) + { + pdf_drop_obj(entry->obj); + entry->obj = NULL; + } + } + } + } +} |