summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/pdf/pdf-object.c5
-rw-r--r--source/pdf/pdf-run.c59
-rw-r--r--source/pdf/pdf-xref.c68
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;
+ }
+ }
+ }
+ }
+}