summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-06-13 16:00:35 +0100
committerRobin Watts <robin.watts@artifex.com>2013-06-13 16:37:06 +0100
commitf85653219a85a9f91cb14471485611ca5f6b25ba (patch)
treed0abcf8b18b90f1430d4dddf4d4ae2e9d3deb07e
parent181dca77f819f9953e0eed4b10ee83d0a9153212 (diff)
downloadmupdf-f85653219a85a9f91cb14471485611ca5f6b25ba.tar.xz
Make display lists reference counted objects.
Remove fz_free_display_list from the API; instead use fz_drop_display_list.
-rw-r--r--android/jni/mupdf.c6
-rw-r--r--apps/mudraw.c12
-rw-r--r--apps/pdfapp.c68
-rw-r--r--fitz/dev_list.c41
-rw-r--r--fitz/fitz.h15
-rw-r--r--fitz/res_font.c2
-rw-r--r--fitz/text_extract.c9
-rw-r--r--pdf/pdf_annot.c4
-rw-r--r--pdf/pdf_page.c2
-rw-r--r--xps/xps_doc.c2
10 files changed, 84 insertions, 77 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index f436a65d..e4333df0 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -134,9 +134,9 @@ static void drop_page_cache(globals *glo, page_cache *pc)
fz_document *doc = glo->doc;
LOGI("Drop page %d", pc->number);
- fz_free_display_list(ctx, pc->page_list);
+ fz_drop_display_list(ctx, pc->page_list);
pc->page_list = NULL;
- fz_free_display_list(ctx, pc->annot_list);
+ fz_drop_display_list(ctx, pc->annot_list);
pc->annot_list = NULL;
fz_free_page(doc, pc->page);
pc->page = NULL;
@@ -150,7 +150,7 @@ static void dump_annotation_display_lists(globals *glo)
int i;
for (i = 0; i < NUM_CACHE; i++) {
- fz_free_display_list(ctx, glo->pages[i].annot_list);
+ fz_drop_display_list(ctx, glo->pages[i].annot_list);
glo->pages[i].annot_list = NULL;
}
}
diff --git a/apps/mudraw.c b/apps/mudraw.c
index 38ac47d2..768298f1 100644
--- a/apps/mudraw.c
+++ b/apps/mudraw.c
@@ -389,7 +389,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
fz_catch(ctx)
{
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
fz_throw(ctx, "cannot draw page %d in file '%s'", pagenum, filename);
}
@@ -412,7 +412,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
fz_catch(ctx)
{
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
fz_rethrow(ctx);
}
@@ -459,7 +459,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
fz_catch(ctx)
{
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
fz_rethrow(ctx);
}
@@ -508,7 +508,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
fz_catch(ctx)
{
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
fz_rethrow(ctx);
}
@@ -682,14 +682,14 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
fz_catch(ctx)
{
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
fz_rethrow(ctx);
}
}
if (list)
- fz_free_display_list(ctx, list);
+ fz_drop_display_list(ctx, list);
fz_free_page(doc, page);
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 13d51a30..7371ea0c 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -223,59 +223,44 @@ void pdfapp_open(pdfapp_t *app, char *filename, int reload)
void pdfapp_close(pdfapp_t *app)
{
- if (app->page_list)
- fz_free_display_list(app->ctx, app->page_list);
+ fz_drop_display_list(app->ctx, app->page_list);
app->page_list = NULL;
- if (app->annotations_list)
- fz_free_display_list(app->ctx, app->annotations_list);
+ fz_drop_display_list(app->ctx, app->annotations_list);
app->annotations_list = NULL;
- if (app->page_text)
- fz_free_text_page(app->ctx, app->page_text);
+ fz_free_text_page(app->ctx, app->page_text);
app->page_text = NULL;
- if (app->page_sheet)
- fz_free_text_sheet(app->ctx, app->page_sheet);
+ fz_free_text_sheet(app->ctx, app->page_sheet);
app->page_sheet = NULL;
- if (app->page_links)
- fz_drop_link(app->ctx, app->page_links);
+ fz_drop_link(app->ctx, app->page_links);
app->page_links = NULL;
- if (app->doctitle)
- fz_free(app->ctx, app->doctitle);
+ fz_free(app->ctx, app->doctitle);
app->doctitle = NULL;
- if (app->docpath)
- fz_free(app->ctx, app->docpath);
+ fz_free(app->ctx, app->docpath);
app->docpath = NULL;
- if (app->image)
- fz_drop_pixmap(app->ctx, app->image);
+ fz_drop_pixmap(app->ctx, app->image);
app->image = NULL;
- if (app->new_image)
- fz_drop_pixmap(app->ctx, app->new_image);
+ fz_drop_pixmap(app->ctx, app->new_image);
app->new_image = NULL;
- if (app->old_image)
- fz_drop_pixmap(app->ctx, app->old_image);
+ fz_drop_pixmap(app->ctx, app->old_image);
app->old_image = NULL;
- if (app->outline)
- fz_free_outline(app->ctx, app->outline);
+ fz_free_outline(app->ctx, app->outline);
app->outline = NULL;
- if (app->page)
- fz_free_page(app->doc, app->page);
+ fz_free_page(app->doc, app->page);
app->page = NULL;
- if (app->doc)
- {
- fz_close_document(app->doc);
- app->doc = NULL;
- }
+ fz_close_document(app->doc);
+ app->doc = NULL;
fz_flush_warnings(app->ctx);
}
@@ -417,18 +402,12 @@ static void pdfapp_loadpage(pdfapp_t *app)
fz_var(mdev);
- if (app->page_list)
- fz_free_display_list(app->ctx, app->page_list);
- if (app->annotations_list)
- fz_free_display_list(app->ctx, app->annotations_list);
- if (app->page_text)
- fz_free_text_page(app->ctx, app->page_text);
- if (app->page_sheet)
- fz_free_text_sheet(app->ctx, app->page_sheet);
- if (app->page_links)
- fz_drop_link(app->ctx, app->page_links);
- if (app->page)
- fz_free_page(app->doc, app->page);
+ fz_drop_display_list(app->ctx, app->page_list);
+ fz_drop_display_list(app->ctx, app->annotations_list);
+ fz_free_text_page(app->ctx, app->page_text);
+ fz_free_text_sheet(app->ctx, app->page_sheet);
+ fz_drop_link(app->ctx, app->page_links);
+ fz_free_page(app->doc, app->page);
app->page_list = NULL;
app->annotations_list = NULL;
@@ -503,11 +482,8 @@ static void pdfapp_recreate_annotationslist(pdfapp_t *app)
fz_var(mdev);
- if (app->annotations_list)
- {
- fz_free_display_list(app->ctx, app->annotations_list);
- app->annotations_list = NULL;
- }
+ fz_drop_display_list(app->ctx, app->annotations_list);
+ app->annotations_list = NULL;
fz_try(app->ctx)
{
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index 5caf34fd..972c4ba5 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -52,6 +52,7 @@ struct fz_display_node_s
struct fz_display_list_s
{
+ fz_storable storable;
fz_display_node *first;
fz_display_node *last;
int len;
@@ -586,10 +587,29 @@ fz_new_list_device(fz_context *ctx, fz_display_list *list)
return dev;
}
+static void
+fz_free_display_list(fz_context *ctx, fz_storable *list_)
+{
+ fz_display_list *list = (fz_display_list *)list_;
+ fz_display_node *node;
+
+ if (list == NULL)
+ return;
+ node = list->first;
+ while (node)
+ {
+ fz_display_node *next = node->next;
+ fz_free_display_node(ctx, node);
+ node = next;
+ }
+ fz_free(ctx, list);
+}
+
fz_display_list *
fz_new_display_list(fz_context *ctx)
{
fz_display_list *list = fz_malloc_struct(ctx, fz_display_list);
+ FZ_INIT_STORABLE(list, 1, fz_free_display_list);
list->first = NULL;
list->last = NULL;
list->len = 0;
@@ -598,21 +618,16 @@ fz_new_display_list(fz_context *ctx)
return list;
}
-void
-fz_free_display_list(fz_context *ctx, fz_display_list *list)
+fz_display_list *
+fz_keep_display_list(fz_context *ctx, fz_display_list *list)
{
- fz_display_node *node;
+ return (fz_display_list *)fz_keep_storable(ctx, &list->storable);
+}
- if (list == NULL)
- return;
- node = list->first;
- while (node)
- {
- fz_display_node *next = node->next;
- fz_free_display_node(ctx, node);
- node = next;
- }
- fz_free(ctx, list);
+void
+fz_drop_display_list(fz_context *ctx, fz_display_list *list)
+{
+ fz_drop_storable(ctx, &list->storable);
}
static fz_display_node *
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 1dc12ff9..73bf8bcd 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -2380,7 +2380,7 @@ struct fz_cookie_s
Create a displaylist with fz_new_display_list, hand it over to
fz_new_list_device to have it populated, and later replay the
list (once or many times) by calling fz_run_display_list. When
- the list is no longer needed free it with fz_free_display_list.
+ the list is no longer needed drop it with fz_drop_display_list.
*/
typedef struct fz_display_list_s fz_display_list;
@@ -2434,14 +2434,19 @@ fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
void fz_run_display_list(fz_display_list *list, fz_device *dev, const fz_matrix *ctm, const fz_rect *area, fz_cookie *cookie);
/*
- fz_free_display_list: Frees a display list.
+ fz_keep_display_list: Keep a reference to a display list.
- list: Display list to be freed. Any objects put into the
- display list by a list device will also be freed.
+ Does not throw exceptions.
+*/
+fz_display_list *fz_keep_display_list(fz_context *ctx, fz_display_list *list);
+
+/*
+ fz_drop_display_list: Drop a reference to a display list, freeing it
+ if the reference count reaches zero.
Does not throw exceptions.
*/
-void fz_free_display_list(fz_context *ctx, fz_display_list *list);
+void fz_drop_display_list(fz_context *ctx, fz_display_list *list);
/*
Links
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 3263f88c..db2ffe5d 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -103,7 +103,7 @@ fz_drop_font(fz_context *ctx, fz_font *font)
if (font->t3procs[i])
fz_drop_buffer(ctx, font->t3procs[i]);
if (font->t3lists[i])
- fz_free_display_list(ctx, font->t3lists[i]);
+ fz_drop_display_list(ctx, font->t3lists[i]);
}
fz_free(ctx, font->t3procs);
fz_free(ctx, font->t3lists);
diff --git a/fitz/text_extract.c b/fitz/text_extract.c
index bf50e6a4..01a789fd 100644
--- a/fitz/text_extract.c
+++ b/fitz/text_extract.c
@@ -369,7 +369,12 @@ fz_new_text_sheet(fz_context *ctx)
void
fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet)
{
- fz_text_style *style = sheet->style;
+ fz_text_style *style;
+
+ if (sheet == NULL)
+ return;
+
+ style = sheet->style;
while (style)
{
fz_text_style *next = style->next;
@@ -478,6 +483,8 @@ void
fz_free_text_page(fz_context *ctx, fz_text_page *page)
{
fz_page_block *block;
+ if (page == NULL)
+ return;
for (block = page->blocks; block < page->blocks + page->len; block++)
{
switch (block->type)
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index 4407616a..ad89725b 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -1086,7 +1086,7 @@ pdf_set_markup_obj_appearance(pdf_document *doc, pdf_obj *annot, float color[3],
fz_free_device(dev);
fz_drop_stroke_state(ctx, stroke);
fz_free_path(ctx, path);
- fz_free_display_list(ctx, strike_list);
+ fz_drop_display_list(ctx, strike_list);
}
fz_catch(ctx)
{
@@ -1178,7 +1178,7 @@ pdf_set_ink_obj_appearance(pdf_document *doc, pdf_obj *annot)
fz_free_device(dev);
fz_drop_stroke_state(ctx, stroke);
fz_free_path(ctx, path);
- fz_free_display_list(ctx, strike_list);
+ fz_drop_display_list(ctx, strike_list);
}
fz_catch(ctx)
{
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index 99776f42..c86cc6ee 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -468,6 +468,8 @@ pdf_load_links(pdf_document *xref, pdf_page *page)
void
pdf_free_page(pdf_document *xref, pdf_page *page)
{
+ if (page == NULL)
+ return;
pdf_drop_obj(page->resources);
pdf_drop_obj(page->contents);
if (page->links)
diff --git a/xps/xps_doc.c b/xps/xps_doc.c
index 96eee8bc..178f2d6b 100644
--- a/xps/xps_doc.c
+++ b/xps/xps_doc.c
@@ -523,6 +523,8 @@ xps_bound_page(xps_document *doc, xps_page *page, fz_rect *bounds)
void
xps_free_page(xps_document *doc, xps_page *page)
{
+ if (page == NULL)
+ return;
/* only free the XML contents */
if (page->root)
fz_free_xml(doc->ctx, page->root);