Пример #1
0
void
xps_parse_fixed_page(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, xps_page *page)
{
	fz_xml *root, *node;
	xps_resource *dict;
	char base_uri[1024];
	fz_rect area;
	char *s;
	fz_matrix scm;

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

	dict = NULL;

	doc->opacity_top = 0;
	doc->opacity[0] = 1;

	root = fz_xml_root(page->xml);
	if (!root)
		return;

	area = fz_unit_rect;
	fz_transform_rect(&area, fz_scale(&scm, page->fix->width, page->fix->height));

	fz_try(ctx)
	{
		for (node = fz_xml_down(root); node; node = fz_xml_next(node))
		{
			if (fz_xml_is_tag(node, "FixedPage.Resources") && fz_xml_down(node))
			{
				if (dict)
					fz_warn(ctx, "ignoring follow-up resource dictionaries");
				else
					dict = xps_parse_resource_dictionary(ctx, doc, base_uri, fz_xml_down(node));
			}
			xps_parse_element(ctx, doc, ctm, &area, base_uri, dict, node);
		}
	}
	fz_always(ctx)
		xps_drop_resource_dictionary(ctx, doc, dict);
	fz_catch(ctx)
		fz_rethrow(ctx);
}
Пример #2
0
void
xps_parse_element(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node)
{
	if (doc->cookie && doc->cookie->abort)
		return;
	if (!strcmp(xml_tag(node), "Path"))
		xps_parse_path(doc, ctm, base_uri, dict, node);
	if (!strcmp(xml_tag(node), "Glyphs"))
		xps_parse_glyphs(doc, ctm, base_uri, dict, node);
	if (!strcmp(xml_tag(node), "Canvas"))
		xps_parse_canvas(doc, ctm, area, base_uri, dict, node);
	if (!strcmp(xml_tag(node), "mc:AlternateContent"))
	{
		node = xps_lookup_alternate_content(node);
		if (node)
			xps_parse_element(doc, ctm, area, base_uri, dict, node);
	}
	/* skip unknown tags (like Foo.Resources and similar) */
}
Пример #3
0
void
xps_parse_element(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area, char *base_uri, xps_resource *dict, fz_xml *node)
{
	if (doc->cookie && doc->cookie->abort)
		return;
	if (fz_xml_is_tag(node, "Path"))
		xps_parse_path(ctx, doc, ctm, base_uri, dict, node);
	if (fz_xml_is_tag(node, "Glyphs"))
		xps_parse_glyphs(ctx, doc, ctm, base_uri, dict, node);
	if (fz_xml_is_tag(node, "Canvas"))
		xps_parse_canvas(ctx, doc, ctm, area, base_uri, dict, node);
	if (fz_xml_is_tag(node, "AlternateContent"))
	{
		node = xps_lookup_alternate_content(ctx, doc, node);
		if (node)
			xps_parse_element(ctx, doc, ctm, area, base_uri, dict, node);
	}
	/* skip unknown tags (like Foo.Resources and similar) */
}
Пример #4
0
void
xps_parse_fixed_page(xps_document *doc, const fz_matrix *ctm, xps_page *page)
{
	fz_xml *node;
	xps_resource *dict;
	char base_uri[1024];
	fz_rect area;
	char *s;
	fz_matrix scm;

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

	dict = NULL;

	doc->opacity_top = 0;
	doc->opacity[0] = 1;

	if (!page->root)
		return;

	area = fz_unit_rect;
	fz_transform_rect(&area, fz_scale(&scm, page->width, page->height));

	for (node = fz_xml_down(page->root); node; node = fz_xml_next(node))
	{
		if (!strcmp(fz_xml_tag(node), "FixedPage.Resources") && fz_xml_down(node))
		{
			if (dict)
				fz_warn(doc->ctx, "ignoring follow-up resource dictionaries");
			else
				dict = xps_parse_resource_dictionary(doc, base_uri, fz_xml_down(node));
		}
		xps_parse_element(doc, ctm, &area, base_uri, dict, node);
	}

	if (dict)
		xps_free_resource_dictionary(doc, dict);
}
Пример #5
0
void
xps_parse_fixed_page(xps_context *ctx, fz_matrix ctm, xps_page *page)
{
	xml_element *node;
	xps_resource *dict;
	char base_uri[1024];
	fz_rect area;
	char *s;
	int code;

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

	dict = NULL;

	ctx->opacity_top = 0;
	ctx->opacity[0] = 1;

	if (!page->root)
		return;

	area = fz_transform_rect(fz_scale(page->width, page->height), fz_unit_rect);

	for (node = xml_down(page->root); node; node = xml_next(node))
	{
		if (!strcmp(xml_tag(node), "FixedPage.Resources") && xml_down(node))
		{
			code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xml_down(node));
			if (code)
				fz_catch(code, "cannot load FixedPage.Resources");
		}
		xps_parse_element(ctx, ctm, area, base_uri, dict, node);
	}

	if (dict)
	{
		xps_free_resource_dictionary(ctx, dict);
	}
}
Пример #6
0
void
xps_parse_canvas(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area, char *base_uri, xps_resource *dict, fz_xml *root)
{
	fz_device *dev = doc->dev;
	xps_resource *new_dict = NULL;
	fz_xml *node;
	char *opacity_mask_uri;

	char *transform_att;
	char *clip_att;
	char *opacity_att;
	char *opacity_mask_att;
	char *navigate_uri_att;

	fz_xml *transform_tag = NULL;
	fz_xml *clip_tag = NULL;
	fz_xml *opacity_mask_tag = NULL;

	fz_matrix transform;

	transform_att = fz_xml_att(root, "RenderTransform");
	clip_att = fz_xml_att(root, "Clip");
	opacity_att = fz_xml_att(root, "Opacity");
	opacity_mask_att = fz_xml_att(root, "OpacityMask");
	navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri");

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		if (fz_xml_is_tag(node, "Canvas.Resources") && fz_xml_down(node))
		{
			if (new_dict)
			{
				fz_warn(ctx, "ignoring follow-up resource dictionaries");
			}
			else
			{
				new_dict = xps_parse_resource_dictionary(ctx, doc, base_uri, fz_xml_down(node));
				if (new_dict)
				{
					new_dict->parent = dict;
					dict = new_dict;
				}
			}
		}

		if (fz_xml_is_tag(node, "Canvas.RenderTransform"))
			transform_tag = fz_xml_down(node);
		if (fz_xml_is_tag(node, "Canvas.Clip"))
			clip_tag = fz_xml_down(node);
		if (fz_xml_is_tag(node, "Canvas.OpacityMask"))
			opacity_mask_tag = fz_xml_down(node);
	}

	opacity_mask_uri = base_uri;
	xps_resolve_resource_reference(ctx, doc, dict, &transform_att, &transform_tag, NULL);
	xps_resolve_resource_reference(ctx, doc, dict, &clip_att, &clip_tag, NULL);
	xps_resolve_resource_reference(ctx, doc, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);

	transform = fz_identity;
	if (transform_att)
		xps_parse_render_transform(ctx, doc, transform_att, &transform);
	if (transform_tag)
		xps_parse_matrix_transform(ctx, doc, transform_tag, &transform);
	fz_concat(&transform, &transform, ctm);

	if (navigate_uri_att)
		xps_add_link(ctx, doc, area, base_uri, navigate_uri_att);

	if (clip_att || clip_tag)
		xps_clip(ctx, doc, &transform, dict, clip_att, clip_tag);

	xps_begin_opacity(ctx, doc, &transform, area, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		xps_parse_element(ctx, doc, &transform, area, base_uri, dict, node);
	}

	xps_end_opacity(ctx, doc, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	if (clip_att || clip_tag)
		fz_pop_clip(ctx, dev);

	if (new_dict)
		xps_drop_resource_dictionary(ctx, doc, new_dict);
}
Пример #7
0
static void
xps_paint_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, void *visual_tag)
{
	xps_parse_element(ctx, doc, ctm, area, base_uri, dict, (fz_xml *)visual_tag);
}
Пример #8
0
void
xps_parse_canvas(xps_document *doc, const fz_matrix *ctm, const fz_rect *area, char *base_uri, xps_resource *dict, fz_xml *root)
{
	xps_resource *new_dict = NULL;
	fz_xml *node;
	char *opacity_mask_uri;

	char *transform_att;
	char *clip_att;
	char *opacity_att;
	char *opacity_mask_att;
	char *navigate_uri_att;

	fz_xml *transform_tag = NULL;
	fz_xml *clip_tag = NULL;
	fz_xml *opacity_mask_tag = NULL;

	fz_matrix transform;

	transform_att = fz_xml_att(root, "RenderTransform");
	clip_att = fz_xml_att(root, "Clip");
	opacity_att = fz_xml_att(root, "Opacity");
	opacity_mask_att = fz_xml_att(root, "OpacityMask");
	navigate_uri_att = fz_xml_att(root, "FixedPage.NavigateUri");

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		if (!strcmp(fz_xml_tag(node), "Canvas.Resources") && fz_xml_down(node))
		{
			if (new_dict)
			{
				fz_warn(doc->ctx, "ignoring follow-up resource dictionaries");
			}
			else
			{
				new_dict = xps_parse_resource_dictionary(doc, base_uri, fz_xml_down(node));
				if (new_dict)
				{
					new_dict->parent = dict;
					dict = new_dict;
				}
			}
		}

		if (!strcmp(fz_xml_tag(node), "Canvas.RenderTransform"))
			transform_tag = fz_xml_down(node);
		if (!strcmp(fz_xml_tag(node), "Canvas.Clip"))
			clip_tag = fz_xml_down(node);
		if (!strcmp(fz_xml_tag(node), "Canvas.OpacityMask"))
			opacity_mask_tag = fz_xml_down(node);
	}

	opacity_mask_uri = base_uri;
	xps_resolve_resource_reference(doc, dict, &transform_att, &transform_tag, NULL);
	xps_resolve_resource_reference(doc, dict, &clip_att, &clip_tag, NULL);
	xps_resolve_resource_reference(doc, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);

	transform = fz_identity;
	if (transform_att)
		xps_parse_render_transform(doc, transform_att, &transform);
	if (transform_tag)
		xps_parse_matrix_transform(doc, transform_tag, &transform);
	fz_concat(&transform, &transform, ctm);

	/* SumatraPDF: extended link support */
	xps_extract_anchor_info(doc, &fz_empty_rect, navigate_uri_att, NULL, 1);
	navigate_uri_att = NULL;

	if (navigate_uri_att)
		xps_add_link(doc, area, base_uri, navigate_uri_att);

	if (clip_att || clip_tag)
		xps_clip(doc, &transform, dict, clip_att, clip_tag);

	xps_begin_opacity(doc, &transform, area, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		xps_parse_element(doc, &transform, area, base_uri, dict, node);
	}

	xps_end_opacity(doc, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	/* SumatraPDF: extended link support */
	xps_extract_anchor_info(doc, area, NULL, fz_xml_att(root, "Name"), 2);

	if (clip_att || clip_tag)
		fz_pop_clip(doc->dev);

	if (new_dict)
		xps_free_resource_dictionary(doc, new_dict);
}
Пример #9
0
void
xps_parse_canvas(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root)
{
	xps_resource *new_dict = NULL;
	xml_element *node;
	char *opacity_mask_uri;
	int code;

	char *transform_att;
	char *clip_att;
	char *opacity_att;
	char *opacity_mask_att;

	xml_element *transform_tag = NULL;
	xml_element *clip_tag = NULL;
	xml_element *opacity_mask_tag = NULL;

	fz_matrix transform;

	transform_att = xml_att(root, "RenderTransform");
	clip_att = xml_att(root, "Clip");
	opacity_att = xml_att(root, "Opacity");
	opacity_mask_att = xml_att(root, "OpacityMask");

	for (node = xml_down(root); node; node = xml_next(node))
	{
		if (!strcmp(xml_tag(node), "Canvas.Resources") && xml_down(node))
		{
			code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xml_down(node));
			if (code)
				fz_catch(code, "cannot load Canvas.Resources");
			else
			{
				new_dict->parent = dict;
				dict = new_dict;
			}
		}

		if (!strcmp(xml_tag(node), "Canvas.RenderTransform"))
			transform_tag = xml_down(node);
		if (!strcmp(xml_tag(node), "Canvas.Clip"))
			clip_tag = xml_down(node);
		if (!strcmp(xml_tag(node), "Canvas.OpacityMask"))
			opacity_mask_tag = xml_down(node);
	}

	opacity_mask_uri = base_uri;
	xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
	xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag, NULL);
	xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);

	transform = fz_identity;
	if (transform_att)
		xps_parse_render_transform(ctx, transform_att, &transform);
	if (transform_tag)
		xps_parse_matrix_transform(ctx, transform_tag, &transform);
	ctm = fz_concat(transform, ctm);

	if (clip_att || clip_tag)
		xps_clip(ctx, ctm, dict, clip_att, clip_tag);

	xps_begin_opacity(ctx, ctm, area, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	for (node = xml_down(root); node; node = xml_next(node))
	{
		xps_parse_element(ctx, ctm, area, base_uri, dict, node);
	}

	xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

	if (clip_att || clip_tag)
		fz_pop_clip(ctx->dev);

	if (new_dict)
		xps_free_resource_dictionary(ctx, new_dict);
}
Пример #10
0
static void
xps_paint_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
	char *base_uri, xps_resource *dict, xml_element *root, void *visual_tag)
{
	xps_parse_element(ctx, ctm, area, base_uri, dict, (xml_element *)visual_tag);
}
Пример #11
0
int
xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
    xps_resource_t *new_dict = NULL;
    xps_item_t *node;
    char *opacity_mask_uri;
    int code;

    char *transform_att;
    char *clip_att;
    char *opacity_att;
    char *opacity_mask_att;

    xps_item_t *transform_tag = NULL;
    xps_item_t *clip_tag = NULL;
    xps_item_t *opacity_mask_tag = NULL;

    gs_matrix transform;

    transform_att = xps_att(root, "RenderTransform");
    clip_att = xps_att(root, "Clip");
    opacity_att = xps_att(root, "Opacity");
    opacity_mask_att = xps_att(root, "OpacityMask");

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "Canvas.Resources") && xps_down(node))
        {
            code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xps_down(node));
            if (code)
                return gs_rethrow(code, "cannot load Canvas.Resources");
            if (new_dict && new_dict != dict)
            {
                new_dict->parent = dict;
                dict = new_dict;
            }
        }

        if (!strcmp(xps_tag(node), "Canvas.RenderTransform"))
            transform_tag = xps_down(node);
        if (!strcmp(xps_tag(node), "Canvas.Clip"))
            clip_tag = xps_down(node);
        if (!strcmp(xps_tag(node), "Canvas.OpacityMask"))
            opacity_mask_tag = xps_down(node);
    }

    opacity_mask_uri = base_uri;
    xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
    xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag, NULL);
    xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);

    gs_gsave(ctx->pgs);

    gs_make_identity(&transform);
    if (transform_att)
        xps_parse_render_transform(ctx, transform_att, &transform);
    if (transform_tag)
        xps_parse_matrix_transform(ctx, transform_tag, &transform);
    gs_concat(ctx->pgs, &transform);

    if (clip_att || clip_tag)
    {
        if (clip_att)
            xps_parse_abbreviated_geometry(ctx, clip_att);
        if (clip_tag)
            xps_parse_path_geometry(ctx, dict, clip_tag, 0);
        xps_clip(ctx);
    }

    code = xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag, false, false);
    if (code)
    {
        gs_grestore(ctx->pgs);
        return gs_rethrow(code, "cannot create transparency group");
    }

    for (node = xps_down(root); node; node = xps_next(node))
    {
        code = xps_parse_element(ctx, base_uri, dict, node);
        if (code)
        {
            xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot parse child of Canvas");
        }
    }

    xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);

    gs_grestore(ctx->pgs);

    if (new_dict)
        xps_free_resource_dictionary(ctx, new_dict);

    return 0;
}
Пример #12
0
int
xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
{
    xps_item_t *root, *node;
    xps_resource_t *dict;
    char *width_att;
    char *height_att;
    char base_uri[1024];
    char *s;
    int code;

    if_debug1m('|', ctx->memory, "doc: parsing page %s\n", part->name);

    xps_strlcpy(base_uri, part->name, sizeof base_uri);
    s = strrchr(base_uri, '/');
    if (s)
        s[1] = 0;

    root = xps_parse_xml(ctx, part->data, part->size);
    if (!root)
        return gs_rethrow(-1, "cannot parse xml");

    if (strcmp(xps_tag(root), "FixedPage"))
        return gs_throw1(-1, "expected FixedPage element (found %s)", xps_tag(root));

    width_att = xps_att(root, "Width");
    height_att = xps_att(root, "Height");

    if (!width_att)
        return gs_throw(-1, "FixedPage missing required attribute: Width");
    if (!height_att)
        return gs_throw(-1, "FixedPage missing required attribute: Height");

    dict = NULL;

    /* Setup new page */
    {
        gs_memory_t *mem = ctx->memory;
        gs_state *pgs = ctx->pgs;
        gx_device *dev = gs_currentdevice(pgs);
        gs_param_float_array fa;
        float fv[2];
        gs_c_param_list list;

        gs_c_param_list_write(&list, mem);

        fv[0] = atoi(width_att) / 96.0 * 72.0;
        fv[1] = atoi(height_att) / 96.0 * 72.0;
        fa.persistent = false;
        fa.data = fv;
        fa.size = 2;

        code = param_write_float_array((gs_param_list *)&list, ".MediaSize", &fa);
        if ( code >= 0 )
        {
            gs_c_param_list_read(&list);
            code = gs_putdeviceparams(dev, (gs_param_list *)&list);
        }
        gs_c_param_list_release(&list);

        /* nb this is for the demo it is wrong and should be removed */
        gs_initgraphics(pgs);

        /* 96 dpi default - and put the origin at the top of the page */

        gs_initmatrix(pgs);

        code = gs_scale(pgs, 72.0/96.0, -72.0/96.0);
        if (code < 0)
            return gs_rethrow(code, "cannot set page transform");

        code = gs_translate(pgs, 0.0, -atoi(height_att));
        if (code < 0)
            return gs_rethrow(code, "cannot set page transform");

        code = gs_erasepage(pgs);
        if (code < 0)
            return gs_rethrow(code, "cannot clear page");
    }

    /* Pre-parse looking for transparency */

    ctx->has_transparency = 0;

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
            if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
                ctx->has_transparency = 1;
        if (xps_element_has_transparency(ctx, base_uri, node))
            ctx->has_transparency = 1;
    }

    /* save the state with the original device before we push */
    gs_gsave(ctx->pgs);

    if (ctx->use_transparency && ctx->has_transparency)
    {
        code = gs_push_pdf14trans_device(ctx->pgs, false);
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot install transparency device");
        }
    }

    /* Draw contents */

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
        {
            code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node));
            if (code)
            {
                gs_pop_pdf14trans_device(ctx->pgs, false);
                gs_grestore(ctx->pgs);
                return gs_rethrow(code, "cannot load FixedPage.Resources");
            }
        }
        code = xps_parse_element(ctx, base_uri, dict, node);
        if (code)
        {
            gs_pop_pdf14trans_device(ctx->pgs, false);
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot parse child of FixedPage");
        }
    }

    if (ctx->use_transparency && ctx->has_transparency)
    {
        code = gs_pop_pdf14trans_device(ctx->pgs, false);
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot uninstall transparency device");
        }
    }

    /* Flush page */
    {
        code = xps_show_page(ctx, 1, true); /* copies, flush */
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot flush page");
        }
    }

    /* restore the original device, discarding the pdf14 compositor */
    gs_grestore(ctx->pgs);

    if (dict)
    {
        xps_free_resource_dictionary(ctx, dict);
    }

    xps_free_item(ctx, root);

    return 0;
}