summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2017-12-07 15:15:26 +0100
committerTor Andersson <tor.andersson@artifex.com>2017-12-13 15:01:05 +0100
commiteacd070190d0c7a7fbc905a2a292f38e282b5a82 (patch)
tree57971ec5acec6b5867cc313c3d2f6f6f619e35fe
parentfa9cd085533f68367c299e058ab3fbb7ad8a2dc6 (diff)
downloadmupdf-eacd070190d0c7a7fbc905a2a292f38e282b5a82.tar.xz
Parse XML using pool allocator.
This needs adding a fz_xml_doc type to hold the pool.
-rw-r--r--include/mupdf/fitz/xml.h29
-rw-r--r--source/fitz/xml.c63
-rw-r--r--source/html/epub-doc.c12
-rw-r--r--source/html/html-layout.c14
-rw-r--r--source/svg/svg-doc.c14
-rw-r--r--source/svg/svg-imp.h2
-rw-r--r--source/xps/xps-doc.c92
-rw-r--r--source/xps/xps-imp.h4
-rw-r--r--source/xps/xps-link.c10
-rw-r--r--source/xps/xps-outline.c23
-rw-r--r--source/xps/xps-resource.c45
-rw-r--r--source/xps/xps-tile.c7
12 files changed, 150 insertions, 165 deletions
diff --git a/include/mupdf/fitz/xml.h b/include/mupdf/fitz/xml.h
index caf5b3ba..d3cbd647 100644
--- a/include/mupdf/fitz/xml.h
+++ b/include/mupdf/fitz/xml.h
@@ -8,6 +8,7 @@
XML document model
*/
+typedef struct fz_xml_doc_s fz_xml_doc;
typedef struct fz_xml_s fz_xml;
/*
@@ -15,7 +16,23 @@ typedef struct fz_xml_s fz_xml;
preserve_white: whether to keep or delete all-whitespace nodes.
*/
-fz_xml *fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white);
+fz_xml_doc *fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white);
+
+/*
+ fz_drop_xml: Free the XML node and all its children and siblings.
+*/
+void fz_drop_xml(fz_context *ctx, fz_xml_doc *xml);
+
+/*
+ fz_detach_xml: Detach a node from the tree, unlinking it from its parent,
+ and setting the document root to the node.
+*/
+void fz_detach_xml(fz_context *ctx, fz_xml_doc *xml, fz_xml *node);
+
+/*
+ fz_xml_root: Get the root node for the document.
+*/
+fz_xml *fz_xml_root(fz_xml_doc *xml);
/*
fz_xml_prev: Return previous sibling of XML node.
@@ -60,16 +77,6 @@ char *fz_xml_att(fz_xml *item, const char *att);
char *fz_xml_text(fz_xml *item);
/*
- fz_drop_xml: Free the XML node and all its children and siblings.
-*/
-void fz_drop_xml(fz_context *doc, fz_xml *item);
-
-/*
- fz_detach_xml: Detach a node from the tree, unlinking it from its parent.
-*/
-void fz_detach_xml(fz_xml *node);
-
-/*
fz_debug_xml: Pretty-print an XML tree to stdout.
*/
void fz_debug_xml(fz_xml *item, int level);
diff --git a/source/fitz/xml.c b/source/fitz/xml.c
index 06583952..cac3692e 100644
--- a/source/fitz/xml.c
+++ b/source/fitz/xml.c
@@ -68,6 +68,7 @@ static const struct { const char *ent; int ucs; } html_entities[] = {
struct parser
{
+ fz_pool *pool;
fz_xml *head;
int preserve_white;
int depth;
@@ -80,6 +81,12 @@ struct attribute
struct attribute *next;
};
+struct fz_xml_doc_s
+{
+ fz_pool *pool;
+ fz_xml *root;
+};
+
struct fz_xml_s
{
char name[40];
@@ -220,37 +227,22 @@ fz_xml *fz_xml_find_down(fz_xml *item, const char *tag)
return fz_xml_find(item, tag);
}
-static void xml_free_attribute(fz_context *ctx, struct attribute *att)
+fz_xml *fz_xml_root(fz_xml_doc *xml)
{
- while (att) {
- struct attribute *next = att->next;
- if (att->value)
- fz_free(ctx, att->value);
- fz_free(ctx, att);
- att = next;
- }
+ return xml ? xml->root : NULL;
}
-void fz_drop_xml(fz_context *ctx, fz_xml *item)
+void fz_drop_xml(fz_context *ctx, fz_xml_doc *xml)
{
- while (item)
- {
- fz_xml *next = item->next;
- if (item->text)
- fz_free(ctx, item->text);
- if (item->atts)
- xml_free_attribute(ctx, item->atts);
- if (item->down)
- fz_drop_xml(ctx, item->down);
- fz_free(ctx, item);
- item = next;
- }
+ if (xml)
+ fz_drop_pool(ctx, xml->pool);
}
-void fz_detach_xml(fz_xml *node)
+void fz_detach_xml(fz_context *ctx, fz_xml_doc *xml, fz_xml *node)
{
if (node->up)
node->up->down = NULL;
+ xml->root = node;
}
static size_t xml_parse_entity(int *c, char *a)
@@ -323,7 +315,7 @@ static void xml_emit_open_tag(fz_context *ctx, struct parser *parser, char *a, c
if (*ns == ':')
a = ns + 1;
- head = fz_malloc_struct(ctx, fz_xml);
+ head = fz_pool_alloc(ctx, parser->pool, sizeof *head);
if (b - a > sizeof(head->name) - 1)
b = a + sizeof(head->name) - 1;
memcpy(head->name, a, b - a);
@@ -356,7 +348,7 @@ static void xml_emit_att_name(fz_context *ctx, struct parser *parser, char *a, c
fz_xml *head = parser->head;
struct attribute *att;
- att = fz_malloc_struct(ctx, struct attribute);
+ att = fz_pool_alloc(ctx, parser->pool, sizeof *att);
if (b - a > sizeof(att->name) - 1)
b = a + sizeof(att->name) - 1;
memcpy(att->name, a, b - a);
@@ -374,7 +366,7 @@ static void xml_emit_att_value(fz_context *ctx, struct parser *parser, char *a,
int c;
/* entities are all longer than UTFmax so runetochar is safe */
- s = att->value = fz_malloc(ctx, b - a + 1);
+ s = att->value = fz_pool_alloc(ctx, parser->pool, b - a + 1);
while (a < b) {
if (*a == '&') {
a += xml_parse_entity(&c, a);
@@ -419,7 +411,7 @@ static void xml_emit_text(fz_context *ctx, struct parser *parser, char *a, char
head = parser->head;
/* entities are all longer than UTFmax so runetochar is safe */
- s = head->text = fz_malloc(ctx, b - a + 1);
+ s = head->text = fz_pool_alloc(ctx, parser->pool, b - a + 1);
while (a < b) {
if (*a == '&') {
a += xml_parse_entity(&c, a);
@@ -443,7 +435,7 @@ static void xml_emit_cdata(fz_context *ctx, struct parser *parser, char *a, char
xml_emit_open_tag(ctx, parser, empty, empty);
head = parser->head;
- s = head->text = fz_malloc(ctx, b - a + 1);
+ s = head->text = fz_pool_alloc(ctx, parser->pool, b - a + 1);
while (a < b)
*s++ = *a++;
*s = 0;
@@ -630,10 +622,11 @@ static char *convert_to_utf8(fz_context *doc, const unsigned char *s, size_t n,
return (char*)s;
}
-fz_xml *
+fz_xml_doc *
fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white)
{
struct parser parser;
+ fz_xml_doc *xml = NULL;
fz_xml root, *node;
char *p, *error;
int dofree;
@@ -645,6 +638,7 @@ fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white)
n = fz_buffer_storage(ctx, buf, &s);
memset(&root, 0, sizeof(root));
+ parser.pool = fz_new_pool(ctx);
parser.head = &root;
parser.preserve_white = preserve_white;
parser.depth = 0;
@@ -656,6 +650,13 @@ fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white)
error = xml_parse_document_imp(ctx, &parser, p);
if (error)
fz_throw(ctx, FZ_ERROR_GENERIC, "%s", error);
+
+ for (node = root.down; node; node = node->next)
+ node->up = NULL;
+
+ xml = fz_pool_alloc(ctx, parser.pool, sizeof *xml);
+ xml->pool = parser.pool;
+ xml->root = root.down;
}
fz_always(ctx)
{
@@ -664,11 +665,9 @@ fz_parse_xml(fz_context *ctx, fz_buffer *buf, int preserve_white)
}
fz_catch(ctx)
{
- fz_drop_xml(ctx, root.down);
+ fz_drop_pool(ctx, parser.pool);
fz_rethrow(ctx);
}
- for (node = root.down; node; node = node->next)
- node->up = NULL;
- return root.down;
+ return xml;
}
diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c
index 41b21361..91d6e6b5 100644
--- a/source/html/epub-doc.c
+++ b/source/html/epub-doc.c
@@ -358,7 +358,7 @@ epub_parse_ncx(fz_context *ctx, epub_document *doc, const char *path)
{
fz_archive *zip = doc->zip;
fz_buffer *buf;
- fz_xml *ncx;
+ fz_xml_doc *ncx;
char base_uri[2048];
fz_dirname(base_uri, path, sizeof base_uri);
@@ -367,7 +367,7 @@ epub_parse_ncx(fz_context *ctx, epub_document *doc, const char *path)
ncx = fz_parse_xml(ctx, buf, 0);
fz_drop_buffer(ctx, buf);
- doc->outline = epub_parse_ncx_imp(ctx, doc, fz_xml_find_down(ncx, "navMap"), base_uri);
+ doc->outline = epub_parse_ncx_imp(ctx, doc, fz_xml_find_down(fz_xml_root(ncx), "navMap"), base_uri);
fz_drop_xml(ctx, ncx);
}
@@ -386,8 +386,8 @@ epub_parse_header(fz_context *ctx, epub_document *doc)
{
fz_archive *zip = doc->zip;
fz_buffer *buf = NULL;
- fz_xml *container_xml = NULL;
- fz_xml *content_opf = NULL;
+ fz_xml_doc *container_xml = NULL;
+ fz_xml_doc *content_opf = NULL;
fz_xml *container, *rootfiles, *rootfile;
fz_xml *package, *manifest, *spine, *itemref, *metadata;
char base_uri[2048];
@@ -414,7 +414,7 @@ epub_parse_header(fz_context *ctx, epub_document *doc)
fz_drop_buffer(ctx, buf);
buf = NULL;
- container = fz_xml_find(container_xml, "container");
+ container = fz_xml_find(fz_xml_root(container_xml), "container");
rootfiles = fz_xml_find_down(container, "rootfiles");
rootfile = fz_xml_find_down(rootfiles, "rootfile");
full_path = fz_xml_att(rootfile, "full-path");
@@ -430,7 +430,7 @@ epub_parse_header(fz_context *ctx, epub_document *doc)
fz_drop_buffer(ctx, buf);
buf = NULL;
- package = fz_xml_find(content_opf, "package");
+ package = fz_xml_find(fz_xml_root(content_opf), "package");
version = fz_xml_att(package, "version");
if (!version || strcmp(version, "2.0"))
fz_warn(ctx, "unknown epub version: %s", version ? version : "<none>");
diff --git a/source/html/html-layout.c b/source/html/html-layout.c
index e5e4f597..d6f63975 100644
--- a/source/html/html-layout.c
+++ b/source/html/html-layout.c
@@ -2672,7 +2672,8 @@ detect_directionality(fz_context *ctx, fz_pool *pool, fz_html_box *box)
fz_html *
fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const char *base_uri, fz_buffer *buf, const char *user_css)
{
- fz_xml *xml;
+ fz_xml_doc *xml;
+ fz_xml *root;
fz_html *html = NULL;
fz_css_match match;
@@ -2689,6 +2690,7 @@ fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const cha
g.last_brk_cls = UCDN_LINEBREAK_CLASS_OP;
xml = fz_parse_xml(ctx, buf, 1);
+ root = fz_xml_root(xml);
fz_try(ctx)
g.css = fz_new_css(ctx);
@@ -2700,20 +2702,20 @@ fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const cha
fz_try(ctx)
{
- if (fz_xml_find(xml, "FictionBook"))
+ if (fz_xml_find(root, "FictionBook"))
{
g.is_fb2 = 1;
fz_parse_css(ctx, g.css, fb2_default_css, "<default:fb2>");
if (fz_use_document_css(ctx))
- fb2_load_css(ctx, g.zip, g.base_uri, g.css, xml);
- g.images = load_fb2_images(ctx, xml);
+ fb2_load_css(ctx, g.zip, g.base_uri, g.css, root);
+ g.images = load_fb2_images(ctx, root);
}
else
{
g.is_fb2 = 0;
fz_parse_css(ctx, g.css, html_default_css, "<default:html>");
if (fz_use_document_css(ctx))
- html_load_css(ctx, g.zip, g.base_uri, g.css, xml);
+ html_load_css(ctx, g.zip, g.base_uri, g.css, root);
g.images = NULL;
}
@@ -2743,7 +2745,7 @@ fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const cha
fz_apply_css_style(ctx, g.set, &html->root->style, &match);
// TODO: transfer page margins out of this hacky box
- generate_boxes(ctx, xml, html->root, &match, 0, DEFAULT_DIR, FZ_LANG_UNSET, &g);
+ generate_boxes(ctx, root, html->root, &match, 0, DEFAULT_DIR, FZ_LANG_UNSET, &g);
detect_directionality(ctx, g.pool, html->root);
}
diff --git a/source/svg/svg-doc.c b/source/svg/svg-doc.c
index d89093a3..a651c9ae 100644
--- a/source/svg/svg-doc.c
+++ b/source/svg/svg-doc.c
@@ -14,7 +14,7 @@ svg_drop_document(fz_context *ctx, fz_document *doc_)
{
svg_document *doc = (svg_document*)doc_;
fz_drop_tree(ctx, doc->idmap, NULL);
- fz_drop_xml(ctx, doc->root);
+ fz_drop_xml(ctx, doc->xml);
}
static int
@@ -29,7 +29,7 @@ svg_bound_page(fz_context *ctx, fz_page *page_, fz_rect *rect)
svg_page *page = (svg_page*)page_;
svg_document *doc = page->doc;
- svg_parse_document_bounds(ctx, doc, doc->root);
+ svg_parse_document_bounds(ctx, doc, fz_xml_root(doc->xml));
rect->x0 = 0;
rect->y0 = 0;
@@ -43,7 +43,7 @@ svg_run_page(fz_context *ctx, fz_page *page_, fz_device *dev, const fz_matrix *c
{
svg_page *page = (svg_page*)page_;
svg_document *doc = page->doc;
- svg_run_document(ctx, doc, doc->root, dev, ctm);
+ svg_run_document(ctx, doc, fz_xml_root(doc->xml), dev, ctm);
}
static void
@@ -87,19 +87,19 @@ static fz_document *
svg_open_document_with_buffer(fz_context *ctx, fz_buffer *buf)
{
svg_document *doc;
- fz_xml *root;
+ fz_xml_doc *xml;
- root = fz_parse_xml(ctx, buf, 0);
+ xml = fz_parse_xml(ctx, buf, 0);
doc = fz_new_derived_document(ctx, svg_document);
doc->super.drop_document = svg_drop_document;
doc->super.count_pages = svg_count_pages;
doc->super.load_page = svg_load_page;
- doc->root = root;
+ doc->xml = xml;
doc->idmap = NULL;
- svg_build_id_map(ctx, doc, root);
+ svg_build_id_map(ctx, doc, fz_xml_root(xml));
return (fz_document*)doc;
}
diff --git a/source/svg/svg-imp.h b/source/svg/svg-imp.h
index 45566074..ad86b536 100644
--- a/source/svg/svg-imp.h
+++ b/source/svg/svg-imp.h
@@ -6,7 +6,7 @@ typedef struct svg_document_s svg_document;
struct svg_document_s
{
fz_document super;
- fz_xml *root;
+ fz_xml_doc *xml;
fz_tree *idmap;
float width;
float height;
diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c
index 9be8dec1..a58aab72 100644
--- a/source/xps/xps-doc.c
+++ b/source/xps/xps-doc.c
@@ -237,7 +237,7 @@ xps_parse_metadata_imp(fz_context *ctx, xps_document *doc, fz_xml *item, xps_fix
static void
xps_parse_metadata(fz_context *ctx, xps_document *doc, xps_part *part, xps_fixdoc *fixdoc)
{
- fz_xml *root;
+ fz_xml_doc *xml;
char buf[1024];
char *s;
@@ -258,9 +258,9 @@ xps_parse_metadata(fz_context *ctx, xps_document *doc, xps_part *part, xps_fixdo
doc->base_uri = buf;
doc->part_uri = part->name;
- root = fz_parse_xml(ctx, part->data, 0);
- xps_parse_metadata_imp(ctx, doc, root, fixdoc);
- fz_drop_xml(ctx, root);
+ xml = fz_parse_xml(ctx, part->data, 0);
+ xps_parse_metadata_imp(ctx, doc, fz_xml_root(xml), fixdoc);
+ fz_drop_xml(ctx, xml);
doc->base_uri = NULL;
doc->part_uri = NULL;
@@ -325,68 +325,56 @@ xps_count_pages(fz_context *ctx, fz_document *doc_)
return doc->page_count;
}
-static fz_xml *
+static fz_xml_doc *
xps_load_fixed_page(fz_context *ctx, xps_document *doc, xps_fixpage *page)
{
xps_part *part;
- fz_xml *root = NULL;
+ fz_xml_doc *xml = NULL;
+ fz_xml *root;
char *width_att;
char *height_att;
part = xps_read_part(ctx, doc, page->name);
fz_try(ctx)
{
- root = fz_parse_xml(ctx, part->data, 0);
- }
- fz_always(ctx)
- {
- xps_drop_part(ctx, doc, part);
- }
- fz_catch(ctx)
- {
- fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
- root = NULL;
- }
- if (!root)
- fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing root element");
+ xml = fz_parse_xml(ctx, part->data, 0);
- if (fz_xml_is_tag(root, "AlternateContent"))
- {
- fz_xml *node = xps_lookup_alternate_content(ctx, doc, root);
- if (!node)
+ root = fz_xml_root(xml);
+ if (!root)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing root element");
+
+ if (fz_xml_is_tag(root, "AlternateContent"))
{
- fz_drop_xml(ctx, root);
- fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing alternate root element");
+ fz_xml *node = xps_lookup_alternate_content(ctx, doc, root);
+ if (!node)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing alternate root element");
+ fz_detach_xml(ctx, xml, node);
+ root = node;
}
- fz_detach_xml(node);
- fz_drop_xml(ctx, root);
- root = node;
- }
- if (!fz_xml_is_tag(root, "FixedPage"))
- {
- fz_drop_xml(ctx, root);
- fz_throw(ctx, FZ_ERROR_GENERIC, "expected FixedPage element");
+ if (!fz_xml_is_tag(root, "FixedPage"))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected FixedPage element");
+ width_att = fz_xml_att(root, "Width");
+ if (!width_att)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Width");
+ height_att = fz_xml_att(root, "Height");
+ if (!height_att)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Height");
+
+ page->width = atoi(width_att);
+ page->height = atoi(height_att);
}
-
- width_att = fz_xml_att(root, "Width");
- if (!width_att)
+ fz_always(ctx)
{
- fz_drop_xml(ctx, root);
- fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Width");
+ xps_drop_part(ctx, doc, part);
}
-
- height_att = fz_xml_att(root, "Height");
- if (!height_att)
+ fz_catch(ctx)
{
- fz_drop_xml(ctx, root);
- fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Height");
+ fz_drop_xml(ctx, xml);
+ fz_rethrow(ctx);
}
- page->width = atoi(width_att);
- page->height = atoi(height_att);
-
- return root;
+ return xml;
}
static fz_rect *
@@ -404,7 +392,7 @@ xps_drop_page_imp(fz_context *ctx, fz_page *page_)
{
xps_page *page = (xps_page*)page_;
fz_drop_document(ctx, &page->doc->super);
- fz_drop_xml(ctx, page->root);
+ fz_drop_xml(ctx, page->xml);
}
fz_page *
@@ -413,7 +401,7 @@ xps_load_page(fz_context *ctx, fz_document *doc_, int number)
xps_document *doc = (xps_document*)doc_;
xps_page *page = NULL;
xps_fixpage *fix;
- fz_xml *root;
+ fz_xml_doc *xml;
int n = 0;
fz_var(page);
@@ -422,7 +410,7 @@ xps_load_page(fz_context *ctx, fz_document *doc_, int number)
{
if (n == number)
{
- root = xps_load_fixed_page(ctx, doc, fix);
+ xml = xps_load_fixed_page(ctx, doc, fix);
fz_try(ctx)
{
page = fz_new_derived_page(ctx, xps_page);
@@ -433,11 +421,11 @@ xps_load_page(fz_context *ctx, fz_document *doc_, int number)
page->doc = (xps_document*) fz_keep_document(ctx, (fz_document*)doc);
page->fix = fix;
- page->root = root;
+ page->xml = xml;
}
fz_catch(ctx)
{
- fz_drop_xml(ctx, root);
+ fz_drop_xml(ctx, xml);
fz_rethrow(ctx);
}
return (fz_page*)page;
diff --git a/source/xps/xps-imp.h b/source/xps/xps-imp.h
index 7eff5670..1d2baaf0 100644
--- a/source/xps/xps-imp.h
+++ b/source/xps/xps-imp.h
@@ -69,7 +69,7 @@ struct xps_page_s
fz_page super;
xps_document *doc;
xps_fixpage *fix;
- fz_xml *root;
+ fz_xml_doc *xml;
};
struct xps_target_s
@@ -126,7 +126,7 @@ struct xps_resource_s
{
char *name;
char *base_uri; /* only used in the head nodes */
- fz_xml *base_xml; /* only used in the head nodes, to free the xml document */
+ fz_xml_doc *base_xml; /* only used in the head nodes, to free the xml document */
fz_xml *data;
xps_resource *next;
xps_resource *parent; /* up to the previous dict in the stack */
diff --git a/source/xps/xps-link.c b/source/xps/xps-link.c
index c26a8d99..59b4d1a5 100644
--- a/source/xps/xps-link.c
+++ b/source/xps/xps-link.c
@@ -161,12 +161,14 @@ xps_load_links_in_element(fz_context *ctx, xps_document *doc, const fz_matrix *c
static void
xps_load_links_in_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, xps_page *page, fz_link **link)
{
- fz_xml *node, *resource_tag;
+ fz_xml *root, *node, *resource_tag;
xps_resource *dict = NULL;
char base_uri[1024];
char *s;
- if (!page->root)
+ root = fz_xml_root(page->xml);
+
+ if (!root)
return;
fz_strlcpy(base_uri, page->fix->name, sizeof base_uri);
@@ -174,11 +176,11 @@ xps_load_links_in_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix
if (s)
s[1] = 0;
- resource_tag = fz_xml_down(fz_xml_find_down(page->root, "FixedPage.Resources"));
+ resource_tag = fz_xml_down(fz_xml_find_down(root, "FixedPage.Resources"));
if (resource_tag)
dict = xps_parse_resource_dictionary(ctx, doc, base_uri, resource_tag);
- for (node = fz_xml_down(page->root); node; node = fz_xml_next(node))
+ for (node = fz_xml_down(root); node; node = fz_xml_next(node))
xps_load_links_in_element(ctx, doc, ctm, base_uri, dict, node, link);
if (dict)
diff --git a/source/xps/xps-outline.c b/source/xps/xps-outline.c
index 61736992..bf43f251 100644
--- a/source/xps/xps-outline.c
+++ b/source/xps/xps-outline.c
@@ -83,37 +83,26 @@ static fz_outline *
xps_load_document_structure(fz_context *ctx, xps_document *doc, xps_fixdoc *fixdoc)
{
xps_part *part;
- fz_xml *root = NULL;
+ fz_xml_doc *xml = NULL;
fz_outline *outline = NULL;
+ fz_var(xml);
+
part = xps_read_part(ctx, doc, fixdoc->outline);
fz_try(ctx)
{
- root = fz_parse_xml(ctx, part->data, 0);
+ xml = fz_parse_xml(ctx, part->data, 0);
+ outline = xps_parse_document_structure(ctx, doc, fz_xml_root(xml));
}
fz_always(ctx)
{
+ fz_drop_xml(ctx, xml);
xps_drop_part(ctx, doc, part);
}
fz_catch(ctx)
{
fz_rethrow(ctx);
}
- if (!root)
- return NULL;
-
- fz_try(ctx)
- {
- outline = xps_parse_document_structure(ctx, doc, root);
- }
- fz_always(ctx)
- {
- fz_drop_xml(ctx, root);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
return outline;
}
diff --git a/source/xps/xps-resource.c b/source/xps/xps-resource.c
index 8e81ab83..4a344902 100644
--- a/source/xps/xps-resource.c
+++ b/source/xps/xps-resource.c
@@ -59,48 +59,45 @@ xps_parse_remote_resource_dictionary(fz_context *ctx, xps_document *doc, char *b
{
char part_name[1024];
char part_uri[1024];
- xps_resource *dict;
xps_part *part;
- fz_xml *xml = NULL;
+ xps_resource *dict = NULL;
+ fz_xml_doc *xml = NULL;
char *s;
+ fz_var(xml);
+
/* External resource dictionaries MUST NOT reference other resource dictionaries */
xps_resolve_url(ctx, doc, part_name, base_uri, source_att, sizeof part_name);
+
part = xps_read_part(ctx, doc, part_name);
fz_try(ctx)
{
xml = fz_parse_xml(ctx, part->data, 0);
+ if (!fz_xml_is_tag(fz_xml_root(xml), "ResourceDictionary"))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected ResourceDictionary element");
+
+ fz_strlcpy(part_uri, part_name, sizeof part_uri);
+ s = strrchr(part_uri, '/');
+ if (s)
+ s[1] = 0;
+
+ dict = xps_parse_resource_dictionary(ctx, doc, part_uri, fz_xml_root(xml));
+ if (dict)
+ {
+ dict->base_xml = xml; /* pass on ownership */
+ xml = NULL;
+ }
}
fz_always(ctx)
{
xps_drop_part(ctx, doc, part);
+ fz_drop_xml(ctx, xml);
}
fz_catch(ctx)
{
- fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
- xml = NULL;
+ fz_rethrow(ctx);
}
- if (!xml)
- return NULL;
-
- if (!fz_xml_is_tag(xml, "ResourceDictionary"))
- {
- fz_drop_xml(ctx, xml);
- fz_throw(ctx, FZ_ERROR_GENERIC, "expected ResourceDictionary element");
- }
-
- fz_strlcpy(part_uri, part_name, sizeof part_uri);
- s = strrchr(part_uri, '/');
- if (s)
- s[1] = 0;
-
- dict = xps_parse_resource_dictionary(ctx, doc, part_uri, xml);
- if (dict)
- dict->base_xml = xml; /* pass on ownership */
- else
- fz_drop_xml(ctx, xml);
-
return dict;
}
diff --git a/source/xps/xps-tile.c b/source/xps/xps-tile.c
index f0e196a0..3e144123 100644
--- a/source/xps/xps-tile.c
+++ b/source/xps/xps-tile.c
@@ -331,7 +331,7 @@ xps_parse_canvas(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const
void
xps_parse_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, xps_page *page)
{
- fz_xml *node;
+ fz_xml *root, *node;
xps_resource *dict;
char base_uri[1024];
fz_rect area;
@@ -348,7 +348,8 @@ xps_parse_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, x
doc->opacity_top = 0;
doc->opacity[0] = 1;
- if (!page->root)
+ root = fz_xml_root(page->xml);
+ if (!root)
return;
area = fz_unit_rect;
@@ -356,7 +357,7 @@ xps_parse_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, x
fz_try(ctx)
{
- for (node = fz_xml_down(page->root); node; node = fz_xml_next(node))
+ for (node = fz_xml_down(root); node; node = fz_xml_next(node))
{
if (fz_xml_is_tag(node, "FixedPage.Resources") && fz_xml_down(node))
{