Esempio n. 1
0
static void
xps_load_links_in_path(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
		char *base_uri, xps_resource *dict, fz_xml *root, fz_link **link)
{
	char *navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri");
	if (navigate_uri_att)
	{
		char *transform_att = fz_xml_att(root, "RenderTransform");
		fz_xml *transform_tag = fz_xml_down(fz_xml_find_down(root, "Path.RenderTransform"));

		char *data_att = fz_xml_att(root, "Data");
		fz_xml *data_tag = fz_xml_down(fz_xml_find_down(root, "Path.Data"));

		fz_path *path = NULL;
		int fill_rule;
		fz_matrix local_ctm;
		fz_rect area;

		xps_resolve_resource_reference(ctx, doc, dict, &data_att, &data_tag, NULL);
		xps_resolve_resource_reference(ctx, doc, dict, &transform_att, &transform_tag, NULL);

		xps_parse_transform(ctx, doc, transform_att, transform_tag, &local_ctm, ctm);

		if (data_att)
			path = xps_parse_abbreviated_geometry(ctx, doc, data_att, &fill_rule);
		else if (data_tag)
			path = xps_parse_path_geometry(ctx, doc, dict, data_tag, 0, &fill_rule);
		if (path)
		{
			fz_bound_path(ctx, path, NULL, &local_ctm, &area);
			fz_drop_path(ctx, path);
			xps_add_link(ctx, doc, &area, base_uri, navigate_uri_att, link);
		}
	}
}
Esempio n. 2
0
static fz_outline *
epub_parse_ncx_imp(fz_context *ctx, epub_document *doc, fz_xml *node, char *base_uri)
{
	char path[2048];
	fz_outline *outline, *head, **tailp;

	head = NULL;
	tailp = &head;

	node = fz_xml_find_down(node, "navPoint");
	while (node)
	{
		char *text = fz_xml_text(fz_xml_down(fz_xml_find_down(fz_xml_find_down(node, "navLabel"), "text")));
		char *content = fz_xml_att(fz_xml_find_down(node, "content"), "src");
		if (text && content)
		{
			fz_strlcpy(path, base_uri, sizeof path);
			fz_strlcat(path, "/", sizeof path);
			fz_strlcat(path, content, sizeof path);
			fz_urldecode(path);
			fz_cleanname(path);

			*tailp = outline = fz_new_outline(ctx);
			tailp = &(*tailp)->next;
			outline->title = fz_strdup(ctx, text);
			outline->uri = fz_strdup(ctx, path);
			outline->page = -1;
			outline->down = epub_parse_ncx_imp(ctx, doc, node, base_uri);
		}
		node = fz_xml_find_next(node, "navPoint");
	}

	return head;
}
Esempio n. 3
0
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;
	xps_resource *dict = NULL;
	char base_uri[1024];
	char *s;

	if (!page->root)
		return;

	fz_strlcpy(base_uri, page->fix->name, sizeof base_uri);
	s = strrchr(base_uri, '/');
	if (s)
		s[1] = 0;

	resource_tag = fz_xml_down(fz_xml_find_down(page->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))
		xps_load_links_in_element(ctx, doc, ctm, base_uri, dict, node, link);

	if (dict)
		xps_drop_resource_dictionary(ctx, doc, dict);
}
Esempio n. 4
0
static char *
find_metadata(fz_context *ctx, fz_xml *metadata, char *key)
{
	char *text = fz_xml_text(fz_xml_down(fz_xml_find_down(metadata, key)));
	if (text)
		return fz_strdup(ctx, text);
	return NULL;
}
Esempio n. 5
0
static void
xps_load_links_in_canvas(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
		char *base_uri, xps_resource *dict, fz_xml *root, fz_link **link)
{
	xps_resource *new_dict = NULL;
	fz_matrix local_ctm;
	fz_xml *node;

	char *navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri");
	char *transform_att = fz_xml_att(root, "RenderTransform");
	fz_xml *transform_tag = fz_xml_down(fz_xml_find_down(root, "Canvas.RenderTransform"));
	fz_xml *resource_tag = fz_xml_down(fz_xml_find_down(root, "Canvas.Resources"));

	if (resource_tag)
	{
		new_dict = xps_parse_resource_dictionary(ctx, doc, base_uri, resource_tag);
		if (new_dict)
		{
			new_dict->parent = dict;
			dict = new_dict;
		}
	}

	xps_resolve_resource_reference(ctx, doc, dict, &transform_att, &transform_tag, NULL);

	xps_parse_transform(ctx, doc, transform_att, transform_tag, &local_ctm, ctm);

	if (navigate_uri_att)
		fz_warn(ctx, "FixedPage.NavigateUri attribute on Canvas element");

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
		xps_load_links_in_element(ctx, doc, &local_ctm, base_uri, dict, node, link);

	if (new_dict)
		xps_drop_resource_dictionary(ctx, doc, new_dict);
}
Esempio n. 6
0
static const char *
rel_path_from_idref(fz_xml *manifest, const char *idref)
{
	fz_xml *item;
	if (!idref)
		return NULL;
	item = fz_xml_find_down(manifest, "item");
	while (item)
	{
		const char *id = fz_xml_att(item, "id");
		if (id && !strcmp(id, idref))
			return fz_xml_att(item, "href");
		item = fz_xml_find_next(item, "item");
	}
	return NULL;
}
Esempio n. 7
0
static void
xps_load_links_in_glyphs(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
		char *base_uri, xps_resource *dict, fz_xml *root, fz_link **link)
{
	char *navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri");
	if (navigate_uri_att)
	{
		char *transform_att = fz_xml_att(root, "RenderTransform");
		fz_xml *transform_tag = fz_xml_down(fz_xml_find_down(root, "Path.RenderTransform"));

		char *bidi_level_att = fz_xml_att(root, "BidiLevel");
		char *font_size_att = fz_xml_att(root, "FontRenderingEmSize");
		char *font_uri_att = fz_xml_att(root, "FontUri");
		char *origin_x_att = fz_xml_att(root, "OriginX");
		char *origin_y_att = fz_xml_att(root, "OriginY");
		char *is_sideways_att = fz_xml_att(root, "IsSideways");
		char *indices_att = fz_xml_att(root, "Indices");
		char *unicode_att = fz_xml_att(root, "UnicodeString");
		char *style_att = fz_xml_att(root, "StyleSimulations");

		int is_sideways = 0;
		int bidi_level = 0;
		fz_matrix local_ctm;
		fz_font *font;
		fz_text *text;
		fz_rect area;

		xps_resolve_resource_reference(ctx, doc, dict, &transform_att, &transform_tag, NULL);

		xps_parse_transform(ctx, doc, transform_att, transform_tag, &local_ctm, ctm);

		if (is_sideways_att)
			is_sideways = !strcmp(is_sideways_att, "true");
		if (bidi_level_att)
			bidi_level = atoi(bidi_level_att);

		font = xps_lookup_font(ctx, doc, base_uri, font_uri_att, style_att);
		text = xps_parse_glyphs_imp(ctx, doc, &local_ctm, font, fz_atof(font_size_att),
				fz_atof(origin_x_att), fz_atof(origin_y_att),
				is_sideways, bidi_level, indices_att, unicode_att);
		fz_bound_text(ctx, text, NULL, &local_ctm, &area);
		fz_drop_text(ctx, text);
		fz_drop_font(ctx, font);

		xps_add_link(ctx, doc, &area, base_uri, navigate_uri_att, link);
	}
}
Esempio n. 8
0
static fz_css_rule *
html_load_css(fz_context *ctx, fz_archive *zip, const char *base_uri, fz_css_rule *css, fz_xml *root)
{
    fz_xml *html, *head, *node;
    fz_buffer *buf;
    char path[2048];

    fz_var(buf);

    html = fz_xml_find(root, "html");
    head = fz_xml_find_down(html, "head");
    for (node = fz_xml_down(head); node; node = fz_xml_next(node))
    {
        if (fz_xml_is_tag(node, "link"))
        {
            char *rel = fz_xml_att(node, "rel");
            if (rel && !fz_strcasecmp(rel, "stylesheet"))
            {
                char *type = fz_xml_att(node, "type");
                if ((type && !strcmp(type, "text/css")) || !type)
                {
                    char *href = fz_xml_att(node, "href");
                    if (href)
                    {
                        fz_strlcpy(path, base_uri, sizeof path);
                        fz_strlcat(path, "/", sizeof path);
                        fz_strlcat(path, href, sizeof path);
                        fz_urldecode(path);
                        fz_cleanname(path);

                        buf = NULL;
                        fz_try(ctx)
                        {
                            buf = fz_read_archive_entry(ctx, zip, path);
                            fz_write_buffer_byte(ctx, buf, 0);
                            css = fz_parse_css(ctx, css, (char*)buf->data, path);
                        }
                        fz_always(ctx)
                        fz_drop_buffer(ctx, buf);
                        fz_catch(ctx)
                        fz_warn(ctx, "ignoring stylesheet %s", path);
                    }
                }
            }
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}