summaryrefslogtreecommitdiff
path: root/source/xps/xps-doc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/xps/xps-doc.c')
-rw-r--r--source/xps/xps-doc.c269
1 files changed, 142 insertions, 127 deletions
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, '.');