From f84a189d5f94250e46d2cbd1a75aba00130e2dd6 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 21 Jan 2015 16:42:45 +0100 Subject: Add ctx parameter and remove embedded contexts for API regularity. Purge several embedded contexts: Remove embedded context in fz_output. Remove embedded context in fz_stream. Remove embedded context in fz_device. Remove fz_rebind_stream (since it is no longer necessary). Remove embedded context in svg_device. Remove embedded context in XML parser. Add ctx argument to fz_document functions. Remove embedded context in fz_document. Remove embedded context in pdf_document. Remove embedded context in pdf_obj. Make fz_page independent of fz_document in the interface. We shouldn't need to pass the document to all functions handling a page. If a page is tied to the source document, it's redundant; otherwise it's just pointless. Fix reference counting oddity in fz_new_image_from_pixmap. --- source/xps/xps-doc.c | 269 +++++++++++++++++++++++++++------------------------ 1 file changed, 142 insertions(+), 127 deletions(-) (limited to 'source/xps/xps-doc.c') diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c index 2b8cee8e..41823d56 100644 --- a/source/xps/xps-doc.c +++ b/source/xps/xps-doc.c @@ -15,7 +15,7 @@ "http://schemas.openxps.org/oxps/v1.0/documentstructure" static void -xps_rels_for_part(char *buf, char *name, int buflen) +xps_rels_for_part(fz_context *ctx, xps_document *doc, char *buf, char *name, int buflen) { char *p, *basename; p = strrchr(name, '/'); @@ -34,10 +34,10 @@ xps_rels_for_part(char *buf, char *name, int buflen) */ void -xps_print_page_list(xps_document *doc) +xps_print_page_list(fz_context *ctx, xps_document *doc) { xps_fixdoc *fixdoc = doc->first_fixdoc; - xps_page *page = doc->first_page; + xps_fixpage *page = doc->first_page; if (doc->start_part) printf("start part %s\n", doc->start_part); @@ -56,7 +56,7 @@ xps_print_page_list(xps_document *doc) } static void -xps_add_fixed_document(xps_document *doc, char *name) +xps_add_fixed_document(fz_context *ctx, xps_document *doc, char *name) { xps_fixdoc *fixdoc; @@ -65,8 +65,8 @@ xps_add_fixed_document(xps_document *doc, char *name) if (!strcmp(fixdoc->name, name)) return; - fixdoc = fz_malloc_struct(doc->ctx, xps_fixdoc); - fixdoc->name = fz_strdup(doc->ctx, name); + fixdoc = fz_malloc_struct(ctx, xps_fixdoc); + fixdoc->name = fz_strdup(ctx, name); fixdoc->outline = NULL; fixdoc->next = NULL; @@ -83,7 +83,7 @@ xps_add_fixed_document(xps_document *doc, char *name) } void -xps_add_link(xps_document *doc, const fz_rect *area, char *base_uri, char *target_uri) +xps_add_link(fz_context *ctx, xps_document *doc, const fz_rect *area, char *base_uri, char *target_uri) { int len; char *buffer = NULL; @@ -91,7 +91,6 @@ xps_add_link(xps_document *doc, const fz_rect *area, char *base_uri, char *targe xps_target *target; fz_link_dest dest; fz_link *link; - fz_context *ctx = doc->ctx; fz_var(buffer); @@ -102,9 +101,9 @@ xps_add_link(xps_document *doc, const fz_rect *area, char *base_uri, char *targe { len = 2 + (base_uri ? strlen(base_uri) : 0) + (target_uri ? strlen(target_uri) : 0); - buffer = fz_malloc(doc->ctx, len); - xps_resolve_url(buffer, base_uri, target_uri, len); - if (xps_url_is_remote(buffer)) + buffer = fz_malloc(ctx, len); + xps_resolve_url(ctx, doc, buffer, base_uri, target_uri, len); + if (xps_url_is_remote(ctx, doc, buffer)) { dest.kind = FZ_LINK_URI; dest.ld.uri.is_map = 0; @@ -140,13 +139,13 @@ xps_add_link(xps_document *doc, const fz_rect *area, char *base_uri, char *targe dest.ld.gotor.new_window = 0; } - link = fz_new_link(doc->ctx, area, dest); + link = fz_new_link(ctx, area, dest); link->next = doc->current_page->links; doc->current_page->links = link; } fz_always(ctx) { - fz_free(doc->ctx, buffer); + fz_free(ctx, buffer); } fz_catch(ctx) { @@ -154,32 +153,23 @@ xps_add_link(xps_document *doc, const fz_rect *area, char *base_uri, char *targe } } -fz_link * -xps_load_links(xps_document *doc, xps_page *page) -{ - if (!page->links_resolved) - fz_warn(doc->ctx, "xps_load_links before page has been executed!"); - return fz_keep_link(doc->ctx, page->links); -} - static void -xps_add_fixed_page(xps_document *doc, char *name, int width, int height) +xps_add_fixed_page(fz_context *ctx, xps_document *doc, char *name, int width, int height) { - xps_page *page; + xps_fixpage *page; /* Check for duplicates first */ for (page = doc->first_page; page; page = page->next) if (!strcmp(page->name, name)) return; - page = fz_malloc_struct(doc->ctx, xps_page); - page->name = fz_strdup(doc->ctx, name); + page = fz_malloc_struct(ctx, xps_fixpage); + page->name = fz_strdup(ctx, name); page->number = doc->page_count++; page->width = width; page->height = height; page->links = NULL; page->links_resolved = 0; - page->root = NULL; page->next = NULL; if (!doc->first_page) @@ -195,18 +185,18 @@ xps_add_fixed_page(xps_document *doc, char *name, int width, int height) } static void -xps_add_link_target(xps_document *doc, char *name) +xps_add_link_target(fz_context *ctx, xps_document *doc, char *name) { - xps_page *page = doc->last_page; - xps_target *target = fz_malloc_struct(doc->ctx, xps_target); - target->name = fz_strdup(doc->ctx, name); + xps_fixpage *page = doc->last_page; + xps_target *target = fz_malloc_struct(ctx, xps_target); + target->name = fz_strdup(ctx, name); target->page = page->number; target->next = doc->target; doc->target = target; } int -xps_lookup_link_target(xps_document *doc, char *target_uri) +xps_lookup_link_target(fz_context *ctx, xps_document *doc, char *target_uri) { xps_target *target; char *needle = strrchr(target_uri, '#'); @@ -218,29 +208,28 @@ xps_lookup_link_target(xps_document *doc, char *target_uri) } static void -xps_drop_link_targets(xps_document *doc) +xps_drop_link_targets(fz_context *ctx, xps_document *doc) { xps_target *target = doc->target, *next; while (target) { next = target->next; - fz_free(doc->ctx, target->name); - fz_free(doc->ctx, target); + fz_free(ctx, target->name); + fz_free(ctx, target); target = next; } } static void -xps_drop_fixed_pages(xps_document *doc) +xps_drop_fixed_pages(fz_context *ctx, xps_document *doc) { - xps_page *page = doc->first_page; + xps_fixpage *page = doc->first_page; while (page) { - xps_page *next = page->next; - xps_drop_page(doc, page); - fz_drop_link(doc->ctx, page->links); - fz_free(doc->ctx, page->name); - fz_free(doc->ctx, page); + xps_fixpage *next = page->next; + fz_drop_link(ctx, page->links); + fz_free(ctx, page->name); + fz_free(ctx, page); page = next; } doc->first_page = NULL; @@ -248,15 +237,15 @@ xps_drop_fixed_pages(xps_document *doc) } static void -xps_drop_fixed_documents(xps_document *doc) +xps_drop_fixed_documents(fz_context *ctx, xps_document *doc) { xps_fixdoc *fixdoc = doc->first_fixdoc; while (fixdoc) { xps_fixdoc *next = fixdoc->next; - fz_free(doc->ctx, fixdoc->name); - fz_free(doc->ctx, fixdoc->outline); - fz_free(doc->ctx, fixdoc); + fz_free(ctx, fixdoc->name); + fz_free(ctx, fixdoc->outline); + fz_free(ctx, fixdoc); fixdoc = next; } doc->first_fixdoc = NULL; @@ -264,11 +253,11 @@ xps_drop_fixed_documents(xps_document *doc) } void -xps_drop_page_list(xps_document *doc) +xps_drop_page_list(fz_context *ctx, xps_document *doc) { - xps_drop_fixed_documents(doc); - xps_drop_fixed_pages(doc); - xps_drop_link_targets(doc); + xps_drop_fixed_documents(ctx, doc); + xps_drop_fixed_pages(ctx, doc); + xps_drop_link_targets(ctx, doc); } /* @@ -276,7 +265,7 @@ xps_drop_page_list(xps_document *doc) */ static void -xps_parse_metadata_imp(xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) +xps_parse_metadata_imp(fz_context *ctx, xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) { while (item) { @@ -287,13 +276,13 @@ xps_parse_metadata_imp(xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) if (target && type) { char tgtbuf[1024]; - xps_resolve_url(tgtbuf, doc->base_uri, target, sizeof tgtbuf); + xps_resolve_url(ctx, doc, tgtbuf, doc->base_uri, target, sizeof tgtbuf); if (!strcmp(type, REL_START_PART) || !strcmp(type, REL_START_PART_OXPS)) - doc->start_part = fz_strdup(doc->ctx, tgtbuf); + doc->start_part = fz_strdup(ctx, tgtbuf); if ((!strcmp(type, REL_DOC_STRUCTURE) || !strcmp(type, REL_DOC_STRUCTURE_OXPS)) && fixdoc) - fixdoc->outline = fz_strdup(doc->ctx, tgtbuf); + fixdoc->outline = fz_strdup(ctx, tgtbuf); if (!fz_xml_att(item, "Id")) - fz_warn(doc->ctx, "missing relationship id for %s", target); + fz_warn(ctx, "missing relationship id for %s", target); } } @@ -303,8 +292,8 @@ xps_parse_metadata_imp(xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) if (source) { char srcbuf[1024]; - xps_resolve_url(srcbuf, doc->base_uri, source, sizeof srcbuf); - xps_add_fixed_document(doc, srcbuf); + xps_resolve_url(ctx, doc, srcbuf, doc->base_uri, source, sizeof srcbuf); + xps_add_fixed_document(ctx, doc, srcbuf); } } @@ -318,8 +307,8 @@ xps_parse_metadata_imp(xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) if (source) { char srcbuf[1024]; - xps_resolve_url(srcbuf, doc->base_uri, source, sizeof srcbuf); - xps_add_fixed_page(doc, srcbuf, width, height); + xps_resolve_url(ctx, doc, srcbuf, doc->base_uri, source, sizeof srcbuf); + xps_add_fixed_page(ctx, doc, srcbuf, width, height); } } @@ -327,17 +316,17 @@ xps_parse_metadata_imp(xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc) { char *name = fz_xml_att(item, "Name"); if (name) - xps_add_link_target(doc, name); + xps_add_link_target(ctx, doc, name); } - xps_parse_metadata_imp(doc, fz_xml_down(item), fixdoc); + xps_parse_metadata_imp(ctx, doc, fz_xml_down(item), fixdoc); item = fz_xml_next(item); } } static void -xps_parse_metadata(xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) +xps_parse_metadata(fz_context *ctx, xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) { fz_xml *root; char buf[1024]; @@ -360,31 +349,30 @@ xps_parse_metadata(xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) doc->base_uri = buf; doc->part_uri = part->name; - root = fz_parse_xml(doc->ctx, part->data, part->size, 0); - xps_parse_metadata_imp(doc, root, fixdoc); - fz_drop_xml(doc->ctx, root); + root = fz_parse_xml(ctx, part->data, part->size, 0); + xps_parse_metadata_imp(ctx, doc, root, fixdoc); + fz_drop_xml(ctx, root); doc->base_uri = NULL; doc->part_uri = NULL; } static void -xps_read_and_process_metadata_part(xps_document *doc, char *name, xps_fixdoc *fixdoc) +xps_read_and_process_metadata_part(fz_context *ctx, xps_document *doc, char *name, xps_fixdoc *fixdoc) { - fz_context *ctx = doc->ctx; xps_part *part; - if (!xps_has_part(doc, name)) + if (!xps_has_part(ctx, doc, name)) return; - part = xps_read_part(doc, name); + part = xps_read_part(ctx, doc, name); fz_try(ctx) { - xps_parse_metadata(doc, part, fixdoc); + xps_parse_metadata(ctx, doc, part, fixdoc); } fz_always(ctx) { - xps_drop_part(doc, part); + xps_drop_part(ctx, doc, part); } fz_catch(ctx) { @@ -393,57 +381,56 @@ xps_read_and_process_metadata_part(xps_document *doc, char *name, xps_fixdoc *fi } void -xps_read_page_list(xps_document *doc) +xps_read_page_list(fz_context *ctx, xps_document *doc) { xps_fixdoc *fixdoc; - xps_read_and_process_metadata_part(doc, "/_rels/.rels", NULL); + xps_read_and_process_metadata_part(ctx, doc, "/_rels/.rels", NULL); if (!doc->start_part) - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find fixed document sequence start part"); + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find fixed document sequence start part"); - xps_read_and_process_metadata_part(doc, doc->start_part, NULL); + xps_read_and_process_metadata_part(ctx, doc, doc->start_part, NULL); for (fixdoc = doc->first_fixdoc; fixdoc; fixdoc = fixdoc->next) { char relbuf[1024]; - fz_try(doc->ctx) + fz_try(ctx) { - xps_rels_for_part(relbuf, fixdoc->name, sizeof relbuf); - xps_read_and_process_metadata_part(doc, relbuf, fixdoc); + xps_rels_for_part(ctx, doc, relbuf, fixdoc->name, sizeof relbuf); + xps_read_and_process_metadata_part(ctx, doc, relbuf, fixdoc); } - fz_catch(doc->ctx) + fz_catch(ctx) { - fz_rethrow_if(doc->ctx, FZ_ERROR_TRYLATER); - fz_warn(doc->ctx, "cannot process FixedDocument rels part"); + fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_warn(ctx, "cannot process FixedDocument rels part"); } - xps_read_and_process_metadata_part(doc, fixdoc->name, fixdoc); + xps_read_and_process_metadata_part(ctx, doc, fixdoc->name, fixdoc); } } int -xps_count_pages(xps_document *doc) +xps_count_pages(fz_context *ctx, xps_document *doc) { return doc->page_count; } -static void -xps_load_fixed_page(xps_document *doc, xps_page *page) +static fz_xml * +xps_load_fixed_page(fz_context *ctx, xps_document *doc, xps_fixpage *page) { xps_part *part; fz_xml *root; char *width_att; char *height_att; - fz_context *ctx = doc->ctx; - part = xps_read_part(doc, page->name); + part = xps_read_part(ctx, doc, page->name); fz_try(ctx) { - root = fz_parse_xml(doc->ctx, part->data, part->size, 0); + root = fz_parse_xml(ctx, part->data, part->size, 0); } fz_always(ctx) { - xps_drop_part(doc, part); + xps_drop_part(ctx, doc, part); } fz_catch(ctx) { @@ -451,89 +438,117 @@ xps_load_fixed_page(xps_document *doc, xps_page *page) root = NULL; } if (!root) - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "FixedPage missing root element"); + fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing root element"); if (fz_xml_is_tag(root, "AlternateContent")) { - fz_xml *node = xps_lookup_alternate_content(root); + fz_xml *node = xps_lookup_alternate_content(ctx, doc, root); if (!node) { - fz_drop_xml(doc->ctx, root); - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "FixedPage missing alternate root element"); + fz_drop_xml(ctx, root); + fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing alternate root element"); } fz_detach_xml(node); - fz_drop_xml(doc->ctx, root); + fz_drop_xml(ctx, root); root = node; } if (strcmp(fz_xml_tag(root), "FixedPage")) { - fz_drop_xml(doc->ctx, root); - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "expected FixedPage element"); + fz_drop_xml(ctx, root); + fz_throw(ctx, FZ_ERROR_GENERIC, "expected FixedPage element"); } width_att = fz_xml_att(root, "Width"); if (!width_att) { - fz_drop_xml(doc->ctx, root); - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Width"); + fz_drop_xml(ctx, root); + fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Width"); } height_att = fz_xml_att(root, "Height"); if (!height_att) { - fz_drop_xml(doc->ctx, root); - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Height"); + fz_drop_xml(ctx, root); + fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Height"); } page->width = atoi(width_att); page->height = atoi(height_att); - page->root = root; + + return root; } -xps_page * -xps_load_page(xps_document *doc, int number) +fz_link * +xps_load_links(fz_context *ctx, xps_page *page) { - xps_page *page; - int n = 0; - - for (page = doc->first_page; page; page = page->next) - { - if (n == number) - { - doc->current_page = page; - if (!page->root) - xps_load_fixed_page(doc, page); - return page; - } - n ++; - } - - fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find page %d", number + 1); + if (!page->fix->links_resolved) + fz_warn(ctx, "xps_load_links before page has been executed!"); + return fz_keep_link(ctx, page->fix->links); } fz_rect * -xps_bound_page(xps_document *doc, xps_page *page, fz_rect *bounds) +xps_bound_page(fz_context *ctx, xps_page *page, fz_rect *bounds) { bounds->x0 = bounds->y0 = 0; - bounds->x1 = page->width * 72.0f / 96.0f; - bounds->y1 = page->height * 72.0f / 96.0f; + bounds->x1 = page->fix->width * 72.0f / 96.0f; + bounds->y1 = page->fix->height * 72.0f / 96.0f; return bounds; } void -xps_drop_page(xps_document *doc, xps_page *page) +xps_drop_page_imp(fz_context *ctx, xps_page *page) { if (page == NULL) return; - /* only free the XML contents */ - if (page->root) - fz_drop_xml(doc->ctx, page->root); - page->root = NULL; + fz_drop_document(ctx, &page->doc->super); + fz_drop_xml(ctx, page->root); +} + +xps_page * +xps_load_page(fz_context *ctx, xps_document *doc, int number) +{ + xps_page *page = NULL; + xps_fixpage *fix; + fz_xml *root; + int n = 0; + + fz_var(page); + + for (fix = doc->first_page; fix; fix = fix->next) + { + if (n == number) + { + doc->current_page = fix; + + root = xps_load_fixed_page(ctx, doc, fix); + fz_try(ctx) + { + page = fz_new_page(ctx, sizeof *page); + page->super.load_links = (fz_page_load_links_fn *)xps_load_links; + page->super.bound_page = (fz_page_bound_page_fn *)xps_bound_page; + page->super.run_page_contents = (fz_page_run_page_contents_fn *)xps_run_page; + page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)xps_drop_page_imp; + + page->doc = (xps_document*) fz_keep_document(ctx, &doc->super); + page->fix = fix; + page->root = root; + } + fz_catch(ctx) + { + fz_drop_xml(ctx, root); + fz_rethrow(ctx); + } + return page; + } + n ++; + } + + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find page %d", number + 1); } static int -xps_recognize(fz_context *doc, const char *magic) +xps_recognize(fz_context *ctx, const char *magic) { char *ext = strrchr(magic, '.'); -- cgit v1.2.3