Beispiel #1
0
static void
xps_parse_metadata_imp(fz_context *ctx, xps_document *doc, fz_xml *item, xps_fixdoc *fixdoc)
{
	while (item)
	{
		if (fz_xml_is_tag(item, "Relationship"))
		{
			char *target = fz_xml_att(item, "Target");
			char *type = fz_xml_att(item, "Type");
			if (target && type)
			{
				char tgtbuf[1024];
				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(ctx, tgtbuf);
				if ((!strcmp(type, REL_DOC_STRUCTURE) || !strcmp(type, REL_DOC_STRUCTURE_OXPS)) && fixdoc)
					fixdoc->outline = fz_strdup(ctx, tgtbuf);
				if (!fz_xml_att(item, "Id"))
					fz_warn(ctx, "missing relationship id for %s", target);
			}
		}

		if (fz_xml_is_tag(item, "DocumentReference"))
		{
			char *source = fz_xml_att(item, "Source");
			if (source)
			{
				char srcbuf[1024];
				xps_resolve_url(ctx, doc, srcbuf, doc->base_uri, source, sizeof srcbuf);
				xps_add_fixed_document(ctx, doc, srcbuf);
			}
		}

		if (fz_xml_is_tag(item, "PageContent"))
		{
			char *source = fz_xml_att(item, "Source");
			char *width_att = fz_xml_att(item, "Width");
			char *height_att = fz_xml_att(item, "Height");
			int width = width_att ? atoi(width_att) : 0;
			int height = height_att ? atoi(height_att) : 0;
			if (source)
			{
				char srcbuf[1024];
				xps_resolve_url(ctx, doc, srcbuf, doc->base_uri, source, sizeof srcbuf);
				xps_add_fixed_page(ctx, doc, srcbuf, width, height);
			}
		}

		if (fz_xml_is_tag(item, "LinkTarget"))
		{
			char *name = fz_xml_att(item, "Name");
			if (name)
				xps_add_link_target(ctx, doc, name);
		}

		xps_parse_metadata_imp(ctx, doc, fz_xml_down(item), fixdoc);

		item = fz_xml_next(item);
	}
}
Beispiel #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;
}
Beispiel #3
0
static fz_css_condition *fz_new_css_condition(fz_context *ctx, int type, const char *key, const char *val)
{
	fz_css_condition *cond = fz_malloc_struct(ctx, fz_css_condition);
	cond->type = type;
	cond->key = key ? fz_strdup(ctx, key) : NULL;
	cond->val = val ? fz_strdup(ctx, val) : NULL;
	cond->next = NULL;
	return cond;
}
static xps_outline *
xps_new_outline(char *title, char *target)
{
	xps_outline *outline = fz_malloc(sizeof(xps_outline));

	outline->title = fz_strdup(title);
	outline->target = fz_strdup(target);
	outline->next = NULL;
	outline->child = NULL;

	return outline;
}
Beispiel #5
0
static fz_outline *
xps_parse_document_outline(xps_context *ctx, xml_element *root)
{
	xml_element *node;
	fz_outline *head = NULL, *entry, *tail;
	int last_level = 1, this_level;
	for (node = xml_down(root); node; node = xml_next(node))
	{
		if (!strcmp(xml_tag(node), "OutlineEntry"))
		{
			char *level = xml_att(node, "OutlineLevel");
			char *target = xml_att(node, "OutlineTarget");
			char *description = xml_att(node, "Description");
			/* SumatraPDF: allow target-less outline entries */
			if (!description)
				continue;

			entry = fz_malloc(ctx->ctx, sizeof *entry);
			entry->title = fz_strdup(ctx->ctx, description);
			entry->page = -1;
			/* SumatraPDF: extended outline actions */
			entry->data = target ? fz_strdup(ctx->ctx, target) : NULL;
			if (target && !xps_is_external_uri(target))
				entry->page = xps_find_link_target(ctx, target);
			entry->free_data = fz_free;
			entry->down = NULL;
			entry->next = NULL;

			this_level = level ? atoi(level) : 1;
			entry->is_open = this_level == 1; /* SumatraPDF: support expansion states */

			if (!head)
{
				head = entry;
}
			else
{
				tail = xps_find_last_outline_at_level(head, 1, this_level);
				if (this_level > last_level)
					tail->down = entry;
				else
					tail->next = entry;
}

			last_level = this_level;
}
}
	return head;
}
static void
xps_add_fixed_page(xps_context *ctx, char *name, int width, int height)
{
	xps_page *page;

	/* Check for duplicates first */
	for (page = ctx->first_page; page; page = page->next)
		if (!strcmp(page->name, name))
			return;

	page = fz_malloc(sizeof(xps_page));
	page->name = fz_strdup(name);
	page->width = width;
	page->height = height;
	page->root = NULL;
	page->next = NULL;

	if (!ctx->first_page)
	{
		ctx->first_page = page;
		ctx->last_page = page;
	}
	else
	{
		ctx->last_page->next = page;
		ctx->last_page = page;
	}
}
static void
xps_add_fixed_document(xps_context *ctx, char *name)
{
	xps_document *fixdoc;

	/* Check for duplicates first */
	for (fixdoc = ctx->first_fixdoc; fixdoc; fixdoc = fixdoc->next)
		if (!strcmp(fixdoc->name, name))
			return;

	fixdoc = fz_malloc(sizeof(xps_document));
	fixdoc->name = fz_strdup(name);
	fixdoc->next = NULL;

	if (!ctx->first_fixdoc)
	{
		ctx->first_fixdoc = fixdoc;
		ctx->last_fixdoc = fixdoc;
	}
	else
	{
		ctx->last_fixdoc->next = fixdoc;
		ctx->last_fixdoc = fixdoc;
	}
}
Beispiel #8
0
static float
pdf_extract_font_size(pdf_xref *xref, char *appearance, char **font_name)
{
	fz_context *ctx = xref->ctx;
	fz_stream *stream = fz_open_memory(ctx, appearance, strlen(appearance));
	float font_size = 0;
	int tok, len;

	*font_name = NULL;
	do
	{
		fz_error error = pdf_lex(&tok, stream, xref->scratch, sizeof(xref->scratch), &len);
		if (error || tok == PDF_TOK_EOF)
		{
			fz_free(ctx, *font_name);
			*font_name = NULL;
			break;
		}
		if (tok == PDF_TOK_NAME)
		{
			fz_free(ctx, *font_name);
			*font_name = fz_strdup(ctx, xref->scratch);
		}
		else if (tok == PDF_TOK_REAL || tok == PDF_TOK_INT)
		{
			font_size = fz_atof(xref->scratch);
		}
	} while (tok != PDF_TOK_KEYWORD || strcmp(xref->scratch, "Tf") != 0);
	fz_close(stream);
	return font_size;
}
Beispiel #9
0
static epub_chapter *
epub_parse_chapter(fz_context *ctx, epub_document *doc, const char *path)
{
	fz_archive *zip = doc->zip;
	fz_buffer *buf = NULL;
	epub_chapter *ch;
	char base_uri[2048];

	fz_dirname(base_uri, path, sizeof base_uri);

	ch = fz_malloc_struct(ctx, epub_chapter);
	ch->path = NULL;
	ch->html = NULL;
	ch->next = NULL;

	fz_var(buf);

	fz_try(ctx)
	{
		buf = fz_read_archive_entry(ctx, zip, path);
		ch->path = fz_strdup(ctx, path);
		ch->html = fz_parse_html(ctx, doc->set, zip, base_uri, buf, fz_user_css(ctx));
	}
	fz_always(ctx)
		fz_drop_buffer(ctx, buf);
	fz_catch(ctx)
	{
		fz_drop_html(ctx, ch->html);
		fz_free(ctx, ch->path);
		fz_free(ctx, ch);
		fz_rethrow(ctx);
	}

	return ch;
}
Beispiel #10
0
fz_document_writer *
fz_new_pixmap_writer(fz_context *ctx, const char *path, const char *options,
	const char *default_path, int n,
	void (*save)(fz_context *ctx, fz_pixmap *pix, const char *filename))
{
	fz_pixmap_writer *wri = fz_new_derived_document_writer(ctx, fz_pixmap_writer, pixmap_begin_page, pixmap_end_page, NULL, pixmap_drop_writer);

	fz_try(ctx)
	{
		fz_parse_draw_options(ctx, &wri->options, options);
		wri->path = fz_strdup(ctx, path ? path : default_path);
		wri->save = save;
		switch (n)
		{
		case 1: wri->options.colorspace = fz_device_gray(ctx); break;
		case 3: wri->options.colorspace = fz_device_rgb(ctx); break;
		case 4: wri->options.colorspace = fz_device_cmyk(ctx); break;
		}
	}
	fz_catch(ctx)
	{
		fz_free(ctx, wri);
		fz_rethrow(ctx);
	}

	return (fz_document_writer*)wri;
}
Beispiel #11
0
static void
xps_add_fixed_document(fz_context *ctx, xps_document *doc, char *name)
{
	xps_fixdoc *fixdoc;

	/* Check for duplicates first */
	for (fixdoc = doc->first_fixdoc; fixdoc; fixdoc = fixdoc->next)
		if (!strcmp(fixdoc->name, name))
			return;

	fixdoc = fz_malloc_struct(ctx, xps_fixdoc);
	fixdoc->name = fz_strdup(ctx, name);
	fixdoc->outline = NULL;
	fixdoc->next = NULL;

	if (!doc->first_fixdoc)
	{
		doc->first_fixdoc = fixdoc;
		doc->last_fixdoc = fixdoc;
	}
	else
	{
		doc->last_fixdoc->next = fixdoc;
		doc->last_fixdoc = fixdoc;
	}
}
Beispiel #12
0
static void
xps_add_fixed_page(fz_context *ctx, xps_document *doc, char *name, int width, int height)
{
	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(ctx, xps_fixpage);
	page->name = fz_strdup(ctx, name);
	page->number = doc->page_count++;
	page->width = width;
	page->height = height;
	page->next = NULL;

	if (!doc->first_page)
	{
		doc->first_page = page;
		doc->last_page = page;
	}
	else
	{
		doc->last_page->next = page;
		doc->last_page = page;
	}
}
Beispiel #13
0
void
xps_extract_anchor_info(xps_context *ctx, xml_element *node, fz_rect rect)
{
	char *value;

	if (ctx->link_root && (value = xml_att(node, "FixedPage.NavigateUri")))
	{
		xps_anchor *link = fz_malloc(ctx->ctx, sizeof(xps_anchor));
		link->target = fz_strdup(ctx->ctx, value);
		link->rect = rect;
		// insert the links in bottom-to-top order (first one is to be preferred)
		link->next = ctx->link_root->next;
		ctx->link_root->next = link;
	}

	if ((value = xml_att(node, "Name")))
	{
		xps_target *target;
		char *valueId = fz_malloc(ctx->ctx, strlen(value) + 2);
		sprintf(valueId, "#%s", value);
		target = xps_find_link_target_obj(ctx, valueId);
		if (target)
			target->rect = rect;
		fz_free(ctx->ctx, valueId);
	}
}
Beispiel #14
0
fz_error
fz_newfontfromfile(fz_font **fontp, char *path, int index)
{
	fz_error error;
	fz_font *font;
	int fterr;

	error = fz_initfreetype();
	if (error)
		return fz_rethrow(error, "cannot init freetype library");

	font = fz_newfont();

	fterr = FT_New_Face(fz_ftlib, path, index, (FT_Face*)&font->ftface);
	if (fterr)
	{
		fz_free(font);
		return fz_throw("freetype: cannot load font: %s", ft_errorstring(fterr));
	}

	/* SumatraPDF */
	font->_data = fz_strdup(path);
	font->_data_len = 0;

	*fontp = font;
	return fz_okay;
}
int main(int argc, char **argv)
{
    MSG msg;
    char buf[1024];
    char *filename;

    fz_cpudetect();
    fz_accelerate();

    pdfapp_init(&gapp);

    associate(argv[0]);
    winopen();

    if (argc == 2)
	filename = fz_strdup(argv[1]);
    else
    {
	if (!winfilename(buf, sizeof buf))
	    exit(0);
	filename = buf;
    }

    pdfapp_open(&gapp, filename);

    while (GetMessage(&msg, NULL, 0, 0))
    {
	TranslateMessage(&msg);
	DispatchMessage(&msg);
    }

    pdfapp_close(&gapp);

    return 0;
}
Beispiel #16
0
void fz_set_user_css(fz_context *ctx, const char *user_css)
{
	fz_lock(ctx, FZ_LOCK_ALLOC);
	fz_free(ctx, ctx->style->user_css);
	ctx->style->user_css = fz_strdup(ctx, user_css);
	fz_unlock(ctx, FZ_LOCK_ALLOC);
}
Beispiel #17
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;
}
Beispiel #18
0
static fz_css_value *fz_new_css_value(fz_context *ctx, int type, const char *data)
{
	fz_css_value *val = fz_malloc_struct(ctx, fz_css_value);
	val->type = type;
	val->data = fz_strdup(ctx, data);
	val->args = NULL;
	val->next = NULL;
	return val;
}
Beispiel #19
0
static fz_css_property *fz_new_css_property(fz_context *ctx, const char *name, fz_css_value *value, int spec)
{
	fz_css_property *prop = fz_malloc_struct(ctx, fz_css_property);
	prop->name = fz_strdup(ctx, name);
	prop->value = value;
	prop->spec = spec;
	prop->next = NULL;
	return prop;
}
Beispiel #20
0
static void
xps_insert_font(fz_context *ctx, xps_document *doc, char *name, fz_font *font)
{
    xps_font_cache *cache = fz_malloc_struct(ctx, xps_font_cache);
    cache->name = fz_strdup(ctx, name);
    cache->font = fz_keep_font(ctx, font);
    cache->next = doc->font_table;
    doc->font_table = cache;
}
Beispiel #21
0
static fz_tree *fz_tree_new_node(fz_context *ctx, const char *key, void *value)
{
	fz_tree *node = fz_malloc_struct(ctx, fz_tree);
	node->key = fz_strdup(ctx, key);
	node->value = value;
	node->left = node->right = &sentinel;
	node->level = 1;
	return node;
}
Beispiel #22
0
static void
xps_add_link_target(fz_context *ctx, xps_document *doc, char *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;
}
Beispiel #23
0
static fz_css_selector *fz_new_css_selector(fz_context *ctx, const char *name)
{
	fz_css_selector *sel = fz_malloc_struct(ctx, fz_css_selector);
	sel->name = name ? fz_strdup(ctx, name) : NULL;
	sel->combine = 0;
	sel->cond = NULL;
	sel->left = NULL;
	sel->right = NULL;
	sel->next = NULL;
	return sel;
}
static xps_link *
xps_new_link(char *target, fz_rect rect, int is_dest)
{
	xps_link *link = fz_malloc(sizeof(xps_link));

	link->target = fz_strdup(target);
	link->rect = rect;
	link->is_dest = is_dest;
	link->next = NULL;

	return link;
}
static xps_named_dest *
xps_new_named_dest(char *target, int page)
{
	xps_named_dest *dest = fz_malloc(sizeof(xps_named_dest));

	dest->target = fz_strdup(target);
	dest->page = page;
	dest->rect = fz_empty_rect; // to be updated
	dest->next = NULL;

	return dest;
}
Beispiel #26
0
static char *parse_attrib_value(struct lexbuf *buf)
{
	char *s;

	if (buf->lookahead == CSS_KEYWORD || buf->lookahead == CSS_STRING)
	{
		s = fz_strdup(buf->ctx, buf->string);
		next(buf);
		return s;
	}

	fz_css_error(buf, "expected attribute value");
}
Beispiel #27
0
xps_part *
xps_new_part(xps_context *ctx, char *name, int size)
{
	xps_part *part;

	part = fz_malloc(ctx->ctx, sizeof(xps_part));
	part->name = fz_strdup(ctx->ctx, name);
	part->size = size;
	part->data = fz_malloc(ctx->ctx, size + 1);
	part->data[size] = 0; /* null-terminate for xml parser */

	return part;
}
Beispiel #28
0
static void
xps_parse_metadata_imp(xps_context *ctx, xml_element *item)
{
	while (item)
	{
		xps_parse_metadata_imp(ctx, xml_down(item));

		if (!strcmp(xml_tag(item), "Relationship"))
		{
			char *target = xml_att(item, "Target");
			char *type = xml_att(item, "Type");
			if (target && type)
			{
				char tgtbuf[1024];
				xps_absolute_path(tgtbuf, ctx->base_uri, target, sizeof tgtbuf);
				if (!strcmp(type, REL_START_PART))
					ctx->start_part = fz_strdup(tgtbuf);
			}
		}

		if (!strcmp(xml_tag(item), "DocumentReference"))
		{
			char *source = xml_att(item, "Source");
			if (source)
			{
				char srcbuf[1024];
				xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
				xps_add_fixed_document(ctx, srcbuf);
			}
		}

		if (!strcmp(xml_tag(item), "PageContent"))
		{
			char *source = xml_att(item, "Source");
			char *width_att = xml_att(item, "Width");
			char *height_att = xml_att(item, "Height");
			int width = width_att ? atoi(width_att) : 0;
			int height = height_att ? atoi(height_att) : 0;
			if (source)
			{
				char srcbuf[1024];
				xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
				xps_add_fixed_page(ctx, srcbuf, width, height);
			}
		}

		item = xml_next(item);
	}
}
Beispiel #29
0
void fz_add_separation(fz_context *ctx, fz_separations *sep, uint32_t rgb, uint32_t cmyk, char *name)
{
	int n;

	if (!ctx || !sep)
		return;

	n = sep->num_separations;
	if (n == FZ_MAX_SEPARATIONS)
		fz_throw(ctx, FZ_ERROR_GENERIC, "Too many separations");

	sep->name[n] = fz_strdup(ctx, name);
	sep->equiv_rgb[n] = rgb;
	sep->equiv_cmyk[n] = cmyk;

	sep->num_separations++;
}
Beispiel #30
0
int
xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xml_element *root)
{
	xps_resource *head;
	xps_resource *entry;
	xml_element *node;
	char *source;
	char *key;
	int code;

	source = xml_att(root, "Source");
	if (source)
	{
		code = xps_parse_remote_resource_dictionary(ctx, dictp, base_uri, source);
		if (code)
			return fz_rethrow(code, "cannot parse remote resource dictionary");
		return fz_okay;
	}

	head = NULL;

	for (node = xml_down(root); node; node = xml_next(node))
	{
		key = xml_att(node, "x:Key");
		if (key)
		{
			entry = fz_malloc(sizeof(xps_resource));
			entry->name = key;
			entry->base_uri = NULL;
			entry->base_xml = NULL;
			entry->data = node;
			entry->next = head;
			entry->parent = NULL;
			head = entry;
		}
	}

	if (head)
	{
		head->base_uri = fz_strdup(base_uri);
	}

	*dictp = head;
	return fz_okay;
}