summaryrefslogtreecommitdiff
path: root/xps/xps_doc.c
diff options
context:
space:
mode:
Diffstat (limited to 'xps/xps_doc.c')
-rw-r--r--xps/xps_doc.c191
1 files changed, 151 insertions, 40 deletions
diff --git a/xps/xps_doc.c b/xps/xps_doc.c
index 94fb32d7..c9a4eec5 100644
--- a/xps/xps_doc.c
+++ b/xps/xps_doc.c
@@ -1,35 +1,13 @@
#include "fitz.h"
#include "muxps.h"
-xps_part *
-xps_new_part(xps_context *ctx, char *name, int size)
-{
- xps_part *part;
-
- part = fz_malloc(sizeof(xps_part));
- part->name = fz_strdup(name);
- part->size = size;
- part->data = fz_malloc(size + 1);
- part->data[size] = 0; /* null-terminate for xml parser */
-
- return part;
-}
-
-void
-xps_free_part(xps_context *ctx, xps_part *part)
-{
- fz_free(part->name);
- fz_free(part->data);
- fz_free(part);
-}
-
/*
* The FixedDocumentSequence and FixedDocument parts determine
* which parts correspond to actual pages, and the page order.
*/
void
-xps_debug_fixdocseq(xps_context *ctx)
+xps_debug_page_list(xps_context *ctx)
{
xps_document *fixdoc = ctx->first_fixdoc;
xps_page *page = ctx->first_page;
@@ -76,21 +54,6 @@ xps_add_fixed_document(xps_context *ctx, char *name)
}
}
-void
-xps_free_fixed_documents(xps_context *ctx)
-{
- xps_document *node = ctx->first_fixdoc;
- while (node)
- {
- xps_document *next = node->next;
- fz_free(node->name);
- fz_free(node);
- node = next;
- }
- ctx->first_fixdoc = NULL;
- ctx->last_fixdoc = NULL;
-}
-
static void
xps_add_fixed_page(xps_context *ctx, char *name, int width, int height)
{
@@ -120,7 +83,7 @@ xps_add_fixed_page(xps_context *ctx, char *name, int width, int height)
}
}
-void
+static void
xps_free_fixed_pages(xps_context *ctx)
{
xps_page *node = ctx->first_page;
@@ -135,6 +98,28 @@ xps_free_fixed_pages(xps_context *ctx)
ctx->last_page = NULL;
}
+static void
+xps_free_fixed_documents(xps_context *ctx)
+{
+ xps_document *node = ctx->first_fixdoc;
+ while (node)
+ {
+ xps_document *next = node->next;
+ fz_free(node->name);
+ fz_free(node);
+ node = next;
+ }
+ ctx->first_fixdoc = NULL;
+ ctx->last_fixdoc = NULL;
+}
+
+void
+xps_free_page_list(xps_context *ctx)
+{
+ xps_free_fixed_documents(ctx);
+ xps_free_fixed_pages(ctx);
+}
+
/*
* Parse the fixed document sequence structure and _rels/.rels to find the start part.
*/
@@ -189,7 +174,7 @@ xps_parse_metadata_imp(xps_context *ctx, xml_element *item)
}
}
-int
+static int
xps_parse_metadata(xps_context *ctx, xps_part *part)
{
xml_element *root;
@@ -226,3 +211,129 @@ xps_parse_metadata(xps_context *ctx, xps_part *part)
return fz_okay;
}
+
+static int
+xps_read_and_process_metadata_part(xps_context *ctx, char *name)
+{
+ xps_part *part;
+ int code;
+
+ part = xps_read_part(ctx, name);
+ if (!part)
+ return fz_rethrow(-1, "cannot read zip part '%s'", name);
+
+ code = xps_parse_metadata(ctx, part);
+ if (code)
+ return fz_rethrow(code, "cannot process metadata part '%s'", name);
+
+ xps_free_part(ctx, part);
+
+ return fz_okay;
+}
+
+int
+xps_read_page_list(xps_context *ctx)
+{
+ xps_document *doc;
+ int code;
+
+ code = xps_read_and_process_metadata_part(ctx, "/_rels/.rels");
+ if (code)
+ return fz_rethrow(code, "cannot process root relationship part");
+
+ if (!ctx->start_part)
+ return fz_throw("cannot find fixed document sequence start part");
+
+ code = xps_read_and_process_metadata_part(ctx, ctx->start_part);
+ if (code)
+ return fz_rethrow(code, "cannot process FixedDocumentSequence part");
+
+ for (doc = ctx->first_fixdoc; doc; doc = doc->next)
+ {
+ code = xps_read_and_process_metadata_part(ctx, doc->name);
+ if (code)
+ return fz_rethrow(code, "cannot process FixedDocument part");
+ }
+
+ return fz_okay;
+}
+
+int
+xps_count_pages(xps_context *ctx)
+{
+ xps_page *page;
+ int n = 0;
+ for (page = ctx->first_page; page; page = page->next)
+ n ++;
+ return n;
+}
+
+static int
+xps_load_fixed_page(xps_context *ctx, xps_page *page)
+{
+ xps_part *part;
+ xml_element *root;
+ char *width_att;
+ char *height_att;
+
+ part = xps_read_part(ctx, page->name);
+ if (!part)
+ return fz_rethrow(-1, "cannot read zip part '%s'", page->name);
+
+ root = xml_parse_document(part->data, part->size);
+ if (!root)
+ return fz_rethrow(-1, "cannot parse xml part '%s'", page->name);
+
+ xps_free_part(ctx, part);
+
+ if (strcmp(xml_tag(root), "FixedPage"))
+ return fz_throw("expected FixedPage element (found %s)", xml_tag(root));
+
+ width_att = xml_att(root, "Width");
+ if (!width_att)
+ return fz_throw("FixedPage missing required attribute: Width");
+
+ height_att = xml_att(root, "Height");
+ if (!height_att)
+ return fz_throw("FixedPage missing required attribute: Height");
+
+ page->width = atoi(width_att);
+ page->height = atoi(height_att);
+ page->root = root;
+
+ return 0;
+}
+
+xps_page *
+xps_load_page(xps_context *ctx, int number)
+{
+ xps_page *page;
+ int code;
+ int n = 0;
+
+ for (page = ctx->first_page; page; page = page->next)
+ {
+ if (n == number)
+ {
+ if (!page->root)
+ {
+ code = xps_load_fixed_page(ctx, page);
+ if (code) {
+ fz_rethrow(code, "cannot load page %d", number + 1);
+ return NULL;
+ }
+ }
+ return page;
+ }
+ n ++;
+ }
+ return nil;
+}
+
+void
+xps_free_page(xps_context *ctx, xps_page *page)
+{
+ if (page->root)
+ xml_free_element(page->root);
+ page->root = NULL;
+}