static void
xps_parse_poly_line_segment(fz_context *doc, fz_path *path, fz_xml *root, int stroking, int *skipped_stroke)
{
	char *points_att = fz_xml_att(root, "Points");
	char *is_stroked_att = fz_xml_att(root, "IsStroked");
	int is_stroked;
	float x, y;
	char *s;

	if (!points_att)
	{
		fz_warn(doc, "PolyLineSegment element has no points");
		return;
	}

	is_stroked = 1;
	if (is_stroked_att && !strcmp(is_stroked_att, "false"))
			is_stroked = 0;
	if (!is_stroked)
		*skipped_stroke = 1;

	s = points_att;
	while (*s != 0)
	{
		while (*s == ' ') s++;
		s = xps_parse_point(s, &x, &y);
		if (stroking && !is_stroked)
			fz_moveto(doc, path, x, y);
		else
			fz_lineto(doc, path, x, y);
	}
}
Beispiel #2
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);
		}
	}
}
Beispiel #3
0
static void
svg_run_ellipse(fz_context *ctx, fz_device *dev, svg_document *doc, fz_xml *node, const svg_state *inherit_state)
{
	svg_state local_state = *inherit_state;

	char *cx_att = fz_xml_att(node, "cx");
	char *cy_att = fz_xml_att(node, "cy");
	char *rx_att = fz_xml_att(node, "rx");
	char *ry_att = fz_xml_att(node, "ry");

	float cx = 0;
	float cy = 0;
	float rx = 0;
	float ry = 0;

	fz_path *path;

	svg_parse_common(ctx, doc, node, &local_state);

	if (cx_att) cx = svg_parse_length(cx_att, local_state.viewbox_w, local_state.fontsize);
	if (cy_att) cy = svg_parse_length(cy_att, local_state.viewbox_h, local_state.fontsize);
	if (rx_att) rx = svg_parse_length(rx_att, local_state.viewbox_w, local_state.fontsize);
	if (ry_att) ry = svg_parse_length(ry_att, local_state.viewbox_h, local_state.fontsize);

	if (rx <= 0 || ry <= 0)
		return;

	path = fz_new_path(ctx);
	approx_circle(ctx, path, cx, cy, rx, ry);
	svg_draw_path(ctx, dev, doc, path, &local_state);
	fz_drop_path(ctx, path);
}
Beispiel #4
0
static void
svg_run_line(fz_context *ctx, fz_device *dev, svg_document *doc, fz_xml *node, const svg_state *inherit_state)
{
	svg_state local_state = *inherit_state;

	char *x1_att = fz_xml_att(node, "x1");
	char *y1_att = fz_xml_att(node, "y1");
	char *x2_att = fz_xml_att(node, "x2");
	char *y2_att = fz_xml_att(node, "y2");

	float x1 = 0;
	float y1 = 0;
	float x2 = 0;
	float y2 = 0;

	svg_parse_common(ctx, doc, node, &local_state);

	if (x1_att) x1 = svg_parse_length(x1_att, local_state.viewbox_w, local_state.fontsize);
	if (y1_att) y1 = svg_parse_length(y1_att, local_state.viewbox_h, local_state.fontsize);
	if (x2_att) x2 = svg_parse_length(x2_att, local_state.viewbox_w, local_state.fontsize);
	if (y2_att) y2 = svg_parse_length(y2_att, local_state.viewbox_h, local_state.fontsize);

	if (local_state.stroke_is_set)
	{
		fz_path *path = fz_new_path(ctx);
		fz_moveto(ctx, path, x1, y1);
		fz_lineto(ctx, path, x2, y2);
		svg_stroke(ctx, dev, doc, path, &local_state);
		fz_drop_path(ctx, path);
	}
}
Beispiel #5
0
/* svg, symbol, image, foreignObject establish new viewports */
void
svg_parse_viewport(fz_context *ctx, svg_document *doc, fz_xml *node, svg_state *state)
{
	//fz_matrix *transform = &state->transform;

	char *x_att = fz_xml_att(node, "x");
	char *y_att = fz_xml_att(node, "y");
	char *w_att = fz_xml_att(node, "width");
	char *h_att = fz_xml_att(node, "height");

	float x = 0;
	float y = 0;
	float w = state->viewport_w;
	float h = state->viewport_h;

	if (x_att) x = svg_parse_length(x_att, state->viewbox_w, state->fontsize);
	if (y_att) y = svg_parse_length(y_att, state->viewbox_h, state->fontsize);
	if (w_att) w = svg_parse_length(w_att, state->viewbox_w, state->fontsize);
	if (h_att) h = svg_parse_length(h_att, state->viewbox_h, state->fontsize);

	/* TODO: new transform */
	fz_warn(ctx, "push viewport: %g %g %g %g", x, y, w, h);

	state->viewport_w = w;
	state->viewport_h = h;
}
Beispiel #6
0
static void
svg_run_use(fz_context *ctx, fz_device *dev, svg_document *doc, fz_xml *root, const svg_state *inherit_state)
{
	svg_state local_state = *inherit_state;

	char *xlink_href_att = fz_xml_att(root, "xlink:href");
	char *x_att = fz_xml_att(root, "x");
	char *y_att = fz_xml_att(root, "y");

	float x = 0;
	float y = 0;

	svg_parse_common(ctx, doc, root, &local_state);
	if (x_att) x = svg_parse_length(x_att, local_state.viewbox_w, local_state.fontsize);
	if (y_att) y = svg_parse_length(y_att, local_state.viewbox_h, local_state.fontsize);

	fz_pre_translate(&local_state.transform, x, y);

	if (xlink_href_att && xlink_href_att[0] == '#')
	{
		fz_xml *linked = fz_tree_lookup(ctx, doc->idmap, xlink_href_att + 1);
		if (linked)
		{
			if (!strcmp(fz_xml_tag(linked), "symbol"))
				svg_run_use_symbol(ctx, dev, doc, root, linked, &local_state);
			else
				svg_run_element(ctx, dev, doc, linked, &local_state);
			return;
		}
	}

	fz_warn(ctx, "svg: cannot find linked symbol");
}
Beispiel #7
0
static void
xps_draw_linear_gradient(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area,
	struct stop *stops, int count,
	fz_xml *root, int spread)
{
	float x0, y0, x1, y1;
	int i, mi, ma;
	float dx, dy, x, y, k;
	fz_point p1, p2;
	fz_matrix inv;
	fz_rect local_area = *area;

	char *start_point_att = fz_xml_att(root, "StartPoint");
	char *end_point_att = fz_xml_att(root, "EndPoint");

	x0 = y0 = 0;
	x1 = y1 = 1;

	if (start_point_att)
		xps_parse_point(ctx, doc, start_point_att, &x0, &y0);
	if (end_point_att)
		xps_parse_point(ctx, doc, end_point_att, &x1, &y1);

	p1.x = x0; p1.y = y0; p2.x = x1; p2.y = y1;
	fz_transform_rect(&local_area, fz_invert_matrix(&inv, ctm));
	x = p2.x - p1.x; y = p2.y - p1.y;
	k = ((local_area.x0 - p1.x) * x + (local_area.y0 - p1.y) * y) / (x * x + y * y);
	mi = floorf(k); ma = ceilf(k);
	k = ((local_area.x1 - p1.x) * x + (local_area.y0 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	k = ((local_area.x0 - p1.x) * x + (local_area.y1 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	k = ((local_area.x1 - p1.x) * x + (local_area.y1 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	dx = x1 - x0; dy = y1 - y0;

	if (spread == SPREAD_REPEAT)
	{
		for (i = mi; i < ma; i++)
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + i * dx, y0 + i * dy, x1 + i * dx, y1 + i * dy);
	}
	else if (spread == SPREAD_REFLECT)
	{
		if ((mi % 2) != 0)
			mi--;
		for (i = mi; i < ma; i += 2)
		{
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + i * dx, y0 + i * dy, x1 + i * dx, y1 + i * dy);
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + (i + 2) * dx, y0 + (i + 2) * dy, x1 + i * dx, y1 + i * dy);
		}
	}
	else
	{
		xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 1, x0, y0, x1, y1);
	}
}
static void
xps_parse_path_figure(fz_context *doc, fz_path *path, fz_xml *root, int stroking)
{
	fz_xml *node;

	char *is_closed_att;
	char *start_point_att;
	char *is_filled_att;

	int is_closed = 0;
	int is_filled = 1;
	float start_x = 0;
	float start_y = 0;

	int skipped_stroke = 0;

	is_closed_att = fz_xml_att(root, "IsClosed");
	start_point_att = fz_xml_att(root, "StartPoint");
	is_filled_att = fz_xml_att(root, "IsFilled");

	if (is_closed_att)
		is_closed = !strcmp(is_closed_att, "true");
	if (is_filled_att)
		is_filled = !strcmp(is_filled_att, "true");
	if (start_point_att)
		xps_parse_point(start_point_att, &start_x, &start_y);

	if (!stroking && !is_filled) /* not filled, when filling */
		return;

	fz_moveto(doc, path, start_x, start_y);

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		if (!strcmp(fz_xml_tag(node), "ArcSegment"))
			xps_parse_arc_segment(doc, path, node, stroking, &skipped_stroke);
		if (!strcmp(fz_xml_tag(node), "PolyBezierSegment"))
			xps_parse_poly_bezier_segment(doc, path, node, stroking, &skipped_stroke);
		if (!strcmp(fz_xml_tag(node), "PolyLineSegment"))
			xps_parse_poly_line_segment(doc, path, node, stroking, &skipped_stroke);
		if (!strcmp(fz_xml_tag(node), "PolyQuadraticBezierSegment"))
			xps_parse_poly_quadratic_bezier_segment(doc, path, node, stroking, &skipped_stroke);
	}

	if (is_closed)
	{
		if (stroking && skipped_stroke)
			fz_lineto(doc, path, start_x, start_y); /* we've skipped using fz_moveto... */
		else
			fz_closepath(doc, path); /* no skipped segments, safe to closepath properly */
	}
}
Beispiel #9
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);
	}
}
static void
xps_parse_poly_quadratic_bezier_segment(fz_context *doc, fz_path *path, fz_xml *root, int stroking, int *skipped_stroke)
{
	char *points_att = fz_xml_att(root, "Points");
	char *is_stroked_att = fz_xml_att(root, "IsStroked");
	float x[2], y[2];
	int is_stroked;
	fz_point pt;
	char *s;
	int n;

	if (!points_att)
	{
		fz_warn(doc, "PolyQuadraticBezierSegment element has no points");
		return;
	}

	is_stroked = 1;
	if (is_stroked_att && !strcmp(is_stroked_att, "false"))
			is_stroked = 0;
	if (!is_stroked)
		*skipped_stroke = 1;

	s = points_att;
	n = 0;
	while (*s != 0)
	{
		while (*s == ' ') s++;
		s = xps_parse_point(s, &x[n], &y[n]);
		n ++;
		if (n == 2)
		{
			if (stroking && !is_stroked)
			{
				fz_moveto(doc, path, x[1], y[1]);
			}
			else
			{
				pt = fz_currentpoint(doc, path);
				fz_curveto(doc, path,
						(pt.x + 2 * x[0]) / 3, (pt.y + 2 * y[0]) / 3,
						(x[1] + 2 * x[0]) / 3, (y[1] + 2 * y[0]) / 3,
						x[1], y[1]);
			}
			n = 0;
		}
	}
}
Beispiel #11
0
void
xps_parse_visual_brush(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area,
	char *base_uri, xps_resource *dict, fz_xml *root)
{
	fz_xml *node;

	char *visual_uri;
	char *visual_att;
	fz_xml *visual_tag = NULL;

	visual_att = fz_xml_att(root, "Visual");

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		if (fz_xml_is_tag(node, "VisualBrush.Visual"))
			visual_tag = fz_xml_down(node);
	}

	visual_uri = base_uri;
	xps_resolve_resource_reference(ctx, doc, dict, &visual_att, &visual_tag, &visual_uri);

	if (visual_tag)
	{
		xps_parse_tiling_brush(ctx, doc, ctm, area,
			visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
	}
}
Beispiel #12
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 #13
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;
}
Beispiel #14
0
static int
match_id_condition(fz_xml *node, const char *p)
{
	const char *s = fz_xml_att(node, "id");
	if (s && !strcmp(s, p))
		return 1;
	return 0;
}
Beispiel #15
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 *node;
	fz_buffer *buf;
	char path[2048];

	for (node = root; node; node = fz_xml_next(node))
	{
		const char *tag = fz_xml_tag(node);
		if (tag && !strcmp(tag, "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_cleanname(path);

						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_drop_buffer(ctx, buf);
					}
				}
			}
		}
		if (tag && !strcmp(tag, "style"))
		{
			char *s = concat_text(ctx, node);
			css = fz_parse_css(ctx, css, s, "<style>");
			fz_free(ctx, s);
		}
		if (fz_xml_down(node))
			css = html_load_css(ctx, zip, base_uri, css, fz_xml_down(node));
	}
	return css;
}
Beispiel #16
0
void
xps_begin_opacity(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area,
	char *base_uri, xps_resource *dict,
	char *opacity_att, fz_xml *opacity_mask_tag)
{
	fz_device *dev = doc->dev;
	float opacity;

	if (!opacity_att && !opacity_mask_tag)
		return;

	opacity = 1;
	if (opacity_att)
		opacity = fz_atof(opacity_att);

	if (opacity_mask_tag && !strcmp(fz_xml_tag(opacity_mask_tag), "SolidColorBrush"))
	{
		char *scb_opacity_att = fz_xml_att(opacity_mask_tag, "Opacity");
		char *scb_color_att = fz_xml_att(opacity_mask_tag, "Color");
		if (scb_opacity_att)
			opacity = opacity * fz_atof(scb_opacity_att);
		if (scb_color_att)
		{
			fz_colorspace *colorspace;
			float samples[FZ_MAX_COLORS];
			xps_parse_color(ctx, doc, base_uri, scb_color_att, &colorspace, samples);
			opacity = opacity * samples[0];
		}
		opacity_mask_tag = NULL;
	}

	if (doc->opacity_top + 1 < nelem(doc->opacity))
	{
		doc->opacity[doc->opacity_top + 1] = doc->opacity[doc->opacity_top] * opacity;
		doc->opacity_top++;
	}

	if (opacity_mask_tag)
	{
		fz_begin_mask(ctx, dev, area, 0, NULL, NULL);
		xps_parse_brush(ctx, doc, ctm, area, base_uri, dict, opacity_mask_tag);
		fz_end_mask(ctx, dev);
	}
}
Beispiel #17
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);
                    }
                }
            }
Beispiel #18
0
void
svg_parse_document_bounds(fz_context *ctx, svg_document *doc, fz_xml *root)
{
	char *version_att;
	char *w_att;
	char *h_att;
	char *viewbox_att;
	int version;

	if (!fz_xml_is_tag(root, "svg"))
		fz_throw(ctx, FZ_ERROR_GENERIC, "expected svg element (found %s)", fz_xml_tag(root));

	version_att = fz_xml_att(root, "version");
	w_att = fz_xml_att(root, "width");
	h_att = fz_xml_att(root, "height");
	viewbox_att = fz_xml_att(root, "viewBox");

	version = 10;
	if (version_att)
		version = fz_atof(version_att) * 10;

	if (version > 12)
		fz_warn(ctx, "svg document version is newer than we support");

	/* If no width or height attributes, then guess from the viewbox */
	if (w_att == NULL && h_att == NULL && viewbox_att != NULL)
	{
		float min_x, min_y, box_w, box_h;
		sscanf(viewbox_att, "%g %g %g %g", &min_x, &min_y, &box_w, &box_h);
		doc->width = box_w;
		doc->height = box_h;
	}
	else
	{
		doc->width = DEF_WIDTH;
		if (w_att)
			doc->width = svg_parse_length(w_att, doc->width, DEF_FONTSIZE);

		doc->height = DEF_HEIGHT;
		if (h_att)
			doc->height = svg_parse_length(h_att, doc->height, DEF_FONTSIZE);
	}
}
Beispiel #19
0
fz_xml *
xps_lookup_alternate_content(fz_context *ctx, xps_document *doc, fz_xml *node)
{
	for (node = fz_xml_down(node); node; node = fz_xml_next(node))
	{
		if (fz_xml_is_tag(node, "Choice") && fz_xml_att(node, "Requires"))
		{
			char list[64];
			char *next = list, *item;
			fz_strlcpy(list, fz_xml_att(node, "Requires"), sizeof(list));
			while ((item = fz_strsep(&next, " \t\r\n")) != NULL && (!*item || !strcmp(item, "xps")));
			if (!item)
				return fz_xml_down(node);
		}
		else if (fz_xml_is_tag(node, "Fallback"))
			return fz_xml_down(node);
	}
	return NULL;
}
Beispiel #20
0
static void
svg_build_id_map(fz_context *ctx, svg_document *doc, fz_xml *root)
{
	fz_xml *node;

	char *id_att = fz_xml_att(root, "id");
	if (id_att)
		doc->idmap = fz_tree_insert(ctx, doc->idmap, id_att, root);

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
		svg_build_id_map(ctx, doc, node);
}
static void
xps_parse_poly_bezier_segment(fz_context *doc, fz_path *path, fz_xml *root, int stroking, int *skipped_stroke)
{
	char *points_att = fz_xml_att(root, "Points");
	char *is_stroked_att = fz_xml_att(root, "IsStroked");
	float x[3], y[3];
	int is_stroked;
	char *s;
	int n;

	if (!points_att)
	{
		fz_warn(doc, "PolyBezierSegment element has no points");
		return;
	}

	is_stroked = 1;
	if (is_stroked_att && !strcmp(is_stroked_att, "false"))
			is_stroked = 0;
	if (!is_stroked)
		*skipped_stroke = 1;

	s = points_att;
	n = 0;
	while (*s != 0)
	{
		while (*s == ' ') s++;
		s = xps_parse_point(s, &x[n], &y[n]);
		n ++;
		if (n == 3)
		{
			if (stroking && !is_stroked)
				fz_moveto(doc, path, x[2], y[2]);
			else
				fz_curveto(doc, path, x[0], y[0], x[1], y[1], x[2], y[2]);
			n = 0;
		}
	}
}
Beispiel #22
0
void
xps_parse_matrix_transform(xps_document *doc, fz_xml *root, fz_matrix *matrix)
{
    char *transform;

    *matrix = fz_identity;

    if (!strcmp(fz_xml_tag(root), "MatrixTransform"))
    {
        transform = fz_xml_att(root, "Matrix");
        if (transform)
            xps_parse_render_transform(doc, transform, matrix);
    }
}
Beispiel #23
0
static void
xps_parse_matrix_transform(fz_context *ctx, xps_document *doc, fz_xml *root, fz_matrix *matrix)
{
	char *transform;

	*matrix = fz_identity;

	if (fz_xml_is_tag(root, "MatrixTransform"))
	{
		transform = fz_xml_att(root, "Matrix");
		if (transform)
			xps_parse_render_transform(ctx, doc, transform, matrix);
	}
}
Beispiel #24
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);
}
Beispiel #25
0
xps_resource *
xps_parse_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, fz_xml *root)
{
	xps_resource *head;
	xps_resource *entry;
	fz_xml *node;
	char *source;
	char *key;

	source = fz_xml_att(root, "Source");
	if (source)
		return xps_parse_remote_resource_dictionary(ctx, doc, base_uri, source);

	head = NULL;

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		key = fz_xml_att(node, "x:Key");
		if (key)
		{
			entry = fz_malloc_struct(ctx, 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(ctx, base_uri);

	return head;
}
Beispiel #26
0
static int
match_class_condition(fz_xml *node, const char *p)
{
	const char *s = fz_xml_att(node, "class");
	char buf[1024];
	if (s) {
		strcpy(buf, s);
		s = strtok(buf, " ");
		while (s) {
			if (!strcmp(s, p))
				return 1;
			s = strtok(NULL, " ");
		}
	}
	return 0;
}
Beispiel #27
0
void
fz_match_css(fz_context *ctx, fz_css_match *match, fz_css_rule *css, fz_xml *node)
{
	fz_css_rule *rule;
	fz_css_selector *sel;
	fz_css_property *prop, *head, *tail;
	const char *s;

	for (rule = css; rule; rule = rule->next)
	{
		sel = rule->selector;
		while (sel)
		{
			if (match_selector(sel, node))
			{
				for (prop = rule->declaration; prop; prop = prop->next)
					add_property(match, prop->name, prop->value, selector_specificity(sel, prop->important));
				break;
			}
			sel = sel->next;
		}
	}

	s = fz_xml_att(node, "style");
	if (s)
	{
		fz_try(ctx)
		{
			head = tail = prop = fz_parse_css_properties(ctx, s);
			while (prop)
			{
				add_property(match, prop->name, prop->value, INLINE_SPECIFICITY);
				tail = prop;
				prop = prop->next;
			}
			if (tail)
				tail->next = css->garbage;
			css->garbage = head;
		}
		fz_catch(ctx)
		{
			fz_warn(ctx, "ignoring style attribute");
		}
	}

	sort_properties(match); /* speed up subsequent value_from_raw_property lookups */
}
Beispiel #28
0
static fz_path *
svg_parse_polygon_imp(fz_context *ctx, svg_document *doc, fz_xml *node, int doclose)
{
	fz_path *path;

	const char *str = fz_xml_att(node, "points");
	float number;
	float args[2];
	int nargs;
	int isfirst;

	if (!str)
		return NULL;

	isfirst = 1;
	nargs = 0;

	path = fz_new_path(ctx);

	while (*str)
	{
		while (svg_is_whitespace_or_comma(*str))
			str ++;

		if (svg_is_digit(*str))
		{
			str = svg_lex_number(&number, str);
			args[nargs++] = number;
		}

		if (nargs == 2)
		{
			if (isfirst)
			{
				fz_moveto(ctx, path, args[0], args[1]);
				isfirst = 0;
			}
			else
			{
				fz_lineto(ctx, path, args[0], args[1]);
			}
			nargs = 0;
		}
	}

	return path;
}
Beispiel #29
0
/* svg, symbol, image, foreignObject plus marker, pattern, view can use viewBox to set the transform */
void
svg_parse_viewbox(fz_context *ctx, svg_document *doc, fz_xml *node, svg_state *state)
{
	//fz_matrix *transform = &state->transform;
	//float port_w = state->viewport_w;
	//float port_h = state->viewport_h;
	float min_x, min_y, box_w, box_h;

	char *viewbox_att = fz_xml_att(node, "viewBox");
	if (viewbox_att)
	{
		sscanf(viewbox_att, "%g %g %g %g", &min_x, &min_y, &box_w, &box_h);

		/* scale and translate to fit [x y w h] to [0 0 viewport.w viewport.h] */
		fz_warn(ctx, "push viewbox: %g %g %g %g", min_x, min_y, box_w, box_h);
	}
}
Beispiel #30
0
static void
svg_run_path(fz_context *ctx, fz_device *dev, svg_document *doc, fz_xml *node, const svg_state *inherit_state)
{
	svg_state local_state = *inherit_state;

	const char *d_att = fz_xml_att(node, "d");
	/* unused: char *path_length_att = fz_xml_att(node, "pathLength"); */

	svg_parse_common(ctx, doc, node, &local_state);

	if (d_att)
	{
		fz_path *path = svg_parse_path_data(ctx, doc, d_att);
		svg_draw_path(ctx, dev, doc, path, &local_state);
		fz_drop_path(ctx, path);
	}
}