From f85653219a85a9f91cb14471485611ca5f6b25ba Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Thu, 13 Jun 2013 16:00:35 +0100 Subject: Make display lists reference counted objects. Remove fz_free_display_list from the API; instead use fz_drop_display_list. --- android/jni/mupdf.c | 6 ++--- apps/mudraw.c | 12 +++++----- apps/pdfapp.c | 68 +++++++++++++++++------------------------------------ fitz/dev_list.c | 41 ++++++++++++++++++++++---------- fitz/fitz.h | 15 ++++++++---- fitz/res_font.c | 2 +- fitz/text_extract.c | 9 ++++++- pdf/pdf_annot.c | 4 ++-- pdf/pdf_page.c | 2 ++ xps/xps_doc.c | 2 ++ 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); -- cgit v1.2.3