static void xps_parse_metadata(fz_context *ctx, xps_document *doc, xps_part *part, xps_fixdoc *fixdoc) { fz_xml *root; char buf[1024]; char *s; /* Save directory name part */ fz_strlcpy(buf, part->name, sizeof buf); s = strrchr(buf, '/'); if (s) s[0] = 0; /* _rels parts are voodoo: their URI references are from * the part they are associated with, not the actual _rels * part being parsed. */ s = strstr(buf, "/_rels"); if (s) *s = 0; doc->base_uri = buf; doc->part_uri = part->name; 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; }
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_css_rule *css; fz_css_match match; fz_html *box; xml = fz_parse_xml(ctx, buf->data, buf->len, 1); css = fz_parse_css(ctx, NULL, default_css, "<default>"); if (user_css) css = fz_parse_css(ctx, NULL, user_css, "<user>"); css = html_load_css(ctx, zip, base_uri, css, xml); // print_rules(css); box = new_box(ctx); match.up = NULL; match.count = 0; generate_boxes(ctx, set, zip, base_uri, xml, box, css, &match); fz_drop_css(ctx, css); fz_drop_xml(ctx, xml); return box; }
static void 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); }
void xps_drop_page_imp(fz_context *ctx, xps_page *page) { if (page == NULL) return; fz_drop_document(ctx, &page->doc->super); fz_drop_xml(ctx, page->root); }
void xps_drop_resource_dictionary(fz_context *ctx, xps_document *doc, xps_resource *dict) { xps_resource *next; while (dict) { next = dict->next; fz_drop_xml(ctx, dict->base_xml); fz_free(ctx, dict->base_uri); fz_free(ctx, dict); dict = next; } }
static xps_resource * xps_parse_remote_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, char *source_att) { char part_name[1024]; char part_uri[1024]; xps_part *part; 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(ctx); } return dict; }
static void epub_parse_ncx(fz_context *ctx, epub_document *doc, const char *path) { fz_archive *zip = doc->zip; fz_buffer *buf; fz_xml *ncx; char base_uri[2048]; unsigned char *data; size_t len; fz_dirname(base_uri, path, sizeof base_uri); buf = fz_read_archive_entry(ctx, zip, path); fz_write_buffer_byte(ctx, buf, 0); len = fz_buffer_storage(ctx, buf, &data); ncx = fz_parse_xml(ctx, data, len, 0); fz_drop_buffer(ctx, buf); doc->outline = epub_parse_ncx_imp(ctx, doc, fz_xml_find_down(ncx, "navMap"), base_uri); fz_drop_xml(ctx, ncx); }
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) { 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 ++; }
static void epub_parse_header(fz_context *ctx, epub_document *doc) { fz_archive *zip = doc->zip; fz_buffer *buf; fz_xml *container_xml, *content_opf; fz_xml *container, *rootfiles, *rootfile; fz_xml *package, *manifest, *spine, *itemref, *metadata; char base_uri[2048]; const char *full_path; const char *version; char ncx[2048], s[2048]; epub_chapter **tailp; size_t len; unsigned char *data; if (fz_has_archive_entry(ctx, zip, "META-INF/rights.xml")) fz_throw(ctx, FZ_ERROR_GENERIC, "EPUB is locked by DRM"); if (fz_has_archive_entry(ctx, zip, "META-INF/encryption.xml")) fz_throw(ctx, FZ_ERROR_GENERIC, "EPUB is locked by DRM"); /* parse META-INF/container.xml to find OPF */ buf = fz_read_archive_entry(ctx, zip, "META-INF/container.xml"); fz_write_buffer_byte(ctx, buf, 0); len = fz_buffer_storage(ctx, buf, &data); container_xml = fz_parse_xml(ctx, data, len, 0); fz_drop_buffer(ctx, buf); container = fz_xml_find(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"); if (!full_path) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find root file in EPUB"); fz_dirname(base_uri, full_path, sizeof base_uri); /* parse OPF to find NCX and spine */ buf = fz_read_archive_entry(ctx, zip, full_path); fz_write_buffer_byte(ctx, buf, 0); len = fz_buffer_storage(ctx, buf, &data); content_opf = fz_parse_xml(ctx, data, len, 0); fz_drop_buffer(ctx, buf); package = fz_xml_find(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>"); metadata = fz_xml_find_down(package, "metadata"); if (metadata) { doc->dc_title = find_metadata(ctx, metadata, "title"); doc->dc_creator = find_metadata(ctx, metadata, "creator"); } manifest = fz_xml_find_down(package, "manifest"); spine = fz_xml_find_down(package, "spine"); if (path_from_idref(ncx, manifest, base_uri, fz_xml_att(spine, "toc"), sizeof ncx)) { epub_parse_ncx(ctx, doc, ncx); } doc->spine = NULL; tailp = &doc->spine; itemref = fz_xml_find_down(spine, "itemref"); while (itemref) { if (path_from_idref(s, manifest, base_uri, fz_xml_att(itemref, "idref"), sizeof s)) { *tailp = epub_parse_chapter(ctx, doc, s); tailp = &(*tailp)->next; } itemref = fz_xml_find_next(itemref, "itemref"); } fz_drop_xml(ctx, container_xml); fz_drop_xml(ctx, content_opf); }
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; part = xps_read_part(ctx, doc, page->name); fz_try(ctx) { root = fz_parse_xml(ctx, part->data, part->size, 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"); if (fz_xml_is_tag(root, "AlternateContent")) { fz_xml *node = xps_lookup_alternate_content(ctx, doc, root); if (!node) { fz_drop_xml(ctx, root); fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing alternate root element"); } 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"); } width_att = fz_xml_att(root, "Width"); if (!width_att) { 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(ctx, root); fz_throw(ctx, FZ_ERROR_GENERIC, "FixedPage missing required attribute: Height"); } page->width = atoi(width_att); page->height = atoi(height_att); return root; }
static void epub_parse_header(fz_context *ctx, epub_document *doc) { fz_archive *zip = doc->zip; fz_buffer *buf; fz_xml *container_xml, *content_opf; fz_xml *container, *rootfiles, *rootfile; fz_xml *package, *manifest, *spine, *itemref; char base_uri[2048]; const char *full_path; const char *version; char ncx[2048], s[2048]; epub_chapter *head, *tail; if (fz_has_archive_entry(ctx, zip, "META-INF/rights.xml")) fz_throw(ctx, FZ_ERROR_GENERIC, "EPUB is locked by DRM"); if (fz_has_archive_entry(ctx, zip, "META-INF/encryption.xml")) fz_throw(ctx, FZ_ERROR_GENERIC, "EPUB is locked by DRM"); /* parse META-INF/container.xml to find OPF */ buf = fz_read_archive_entry(ctx, zip, "META-INF/container.xml"); fz_write_buffer_byte(ctx, buf, 0); container_xml = fz_parse_xml(ctx, buf->data, buf->len, 0); fz_drop_buffer(ctx, buf); container = fz_xml_find(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"); if (!full_path) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find root file in EPUB"); printf("epub: found root: %s\n", full_path); fz_dirname(base_uri, full_path, sizeof base_uri); /* parse OPF to find NCX and spine */ buf = fz_read_archive_entry(ctx, zip, full_path); fz_write_buffer_byte(ctx, buf, 0); content_opf = fz_parse_xml(ctx, buf->data, buf->len, 0); fz_drop_buffer(ctx, buf); package = fz_xml_find(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>"); manifest = fz_xml_find_down(package, "manifest"); spine = fz_xml_find_down(package, "spine"); if (path_from_idref(ncx, manifest, base_uri, fz_xml_att(spine, "toc"), sizeof ncx)) { /* TODO: parse NCX to create fz_outline */ printf("epub: found outline: %s\n", ncx); } head = tail = NULL; itemref = fz_xml_find_down(spine, "itemref"); while (itemref) { if (path_from_idref(s, manifest, base_uri, fz_xml_att(itemref, "idref"), sizeof s)) { printf("epub: found spine %s\n", s); if (!head) head = tail = epub_parse_chapter(ctx, doc, s); else tail = tail->next = epub_parse_chapter(ctx, doc, s); } itemref = fz_xml_find_next(itemref, "itemref"); } doc->spine = head; printf("epub: done.\n"); fz_drop_xml(ctx, container_xml); fz_drop_xml(ctx, content_opf); }