summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xps/ghostxps.h48
-rw-r--r--xps/xpsanalyze.c70
-rw-r--r--xps/xpscolor.c17
-rw-r--r--xps/xpscommon.c20
-rw-r--r--xps/xpsdoc.c57
-rw-r--r--xps/xpsglyphs.c42
-rw-r--r--xps/xpsgradient.c24
-rw-r--r--xps/xpsimage.c27
-rw-r--r--xps/xpsmem.c6
-rw-r--r--xps/xpsopacity.c8
-rw-r--r--xps/xpspage.c33
-rw-r--r--xps/xpspath.c38
-rw-r--r--xps/xpsresource.c63
-rw-r--r--xps/xpstile.c18
-rw-r--r--xps/xpstop.c7
-rw-r--r--xps/xpsvisual.c12
-rw-r--r--xps/xpsxml.c1
17 files changed, 286 insertions, 205 deletions
diff --git a/xps/ghostxps.h b/xps/ghostxps.h
index 3283ec6e3..2e105e73e 100644
--- a/xps/ghostxps.h
+++ b/xps/ghostxps.h
@@ -122,7 +122,7 @@ size_t xps_strlcat(char *destination, const char *source, size_t size);
int xps_strcasecmp(char *a, char *b);
char *xps_strdup_imp(xps_context_t *ctx, const char *str, const char *function);
char *xps_clean_path(char *name);
-void xps_absolute_path(char *output, char *pwd, char *path);
+void xps_absolute_path(char *output, char *base_uri, char *path);
/* end of page device callback foo */
int xps_show_page(xps_context_t *ctx, int num_copies, int flush);
@@ -179,6 +179,7 @@ struct xps_context_s
gs_memory_t *memory;
gs_state *pgs;
gs_font_dir *fontdir;
+ FILE *file;
gs_color_space *gray;
gs_color_space *srgb;
@@ -211,7 +212,7 @@ struct xps_context_s
z_stream zip_stream;
char zip_file_name[2048];
- char pwd[1024]; /* directory name of xml part being processed */
+ char *base_uri; /* base uri for parsing metadata and scanning parts for resources */
char *state; /* temporary state for various processing */
int use_transparency; /* global toggle for transparency */
@@ -361,19 +362,19 @@ char * xps_tag(xps_item_t *item);
char * xps_att(xps_item_t *item, const char *att);
int xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part);
-int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_solid_color_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_visual_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_linear_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_radial_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_glyphs(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_solid_color_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_linear_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_radial_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
void xps_free_image(xps_context_t *ctx, xps_image_t *image);
-int xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root,
- int (*func)(xps_context_t*, xps_resource_t*, xps_item_t*, void*), void *user);
+int xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
+ int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user);
void xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, gs_matrix *matrix);
void xps_parse_render_transform(xps_context_t *ctx, char *text, gs_matrix *matrix);
@@ -381,24 +382,24 @@ void xps_parse_rectangle(xps_context_t *ctx, char *text, gs_rect *rect);
int xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom);
int xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root, int stroking);
-int xps_begin_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
-int xps_end_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
+int xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
+int xps_end_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
-int xps_parse_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_element(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
int xps_clip(xps_context_t *ctx, gs_rect *saved_bounds);
int xps_unclip(xps_context_t *ctx, gs_rect *saved_bounds);
int xps_fill(xps_context_t *ctx);
void xps_bounds_in_user_space(xps_context_t *ctx, gs_rect *user);
-int xps_parse_color(xps_context_t *ctx, char *hexstring, gs_color_space **csp, float *samples);
+int xps_parse_color(xps_context_t *ctx, char *base_uri, char *hexstring, gs_color_space **csp, float *samples);
int xps_set_color(xps_context_t *ctx, gs_color_space *colorspace, float *samples);
int xps_parse_icc_profile(xps_context_t *ctx, gs_color_space **csp, byte *data, int length, int ncomp);
-int xps_element_has_transparency(xps_context_t *ctx, xps_item_t *node);
-int xps_resource_dictionary_has_transparency(xps_context_t *ctx, xps_item_t *node);
-int xps_image_brush_has_transparency(xps_context_t *ctx, xps_item_t *root);
+int xps_element_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *node);
+int xps_resource_dictionary_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *node);
+int xps_image_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root);
/*
@@ -408,13 +409,14 @@ int xps_image_brush_has_transparency(xps_context_t *ctx, xps_item_t *root);
struct xps_resource_s
{
char *name;
+ char *base_uri; /* only used in the head nodes */
xps_item_t *data;
xps_resource_t *next;
xps_resource_t *parent; /* up to the previous dict in the stack */
};
-xps_resource_t *xps_parse_remote_resource_dictionary(xps_context_t *ctx, char *name);
-xps_resource_t *xps_parse_resource_dictionary(xps_context_t *ctx, xps_item_t *root);
+xps_resource_t *xps_parse_remote_resource_dictionary(xps_context_t *ctx, char *base_uri, char *name);
+xps_resource_t *xps_parse_resource_dictionary(xps_context_t *ctx, char *base_uri, xps_item_t *root);
void xps_free_resource_dictionary(xps_context_t *ctx, xps_resource_t *dict);
-int xps_resolve_resource_reference(xps_context_t *ctx, xps_resource_t *dict, char **attp, xps_item_t **tagp);
+int xps_resolve_resource_reference(xps_context_t *ctx, xps_resource_t *dict, char **attp, xps_item_t **tagp, char **urip);
diff --git a/xps/xpsanalyze.c b/xps/xpsanalyze.c
index d3bdd1e44..7f0d3f0a9 100644
--- a/xps/xpsanalyze.c
+++ b/xps/xpsanalyze.c
@@ -18,22 +18,22 @@
#include "ghostxps.h"
-int
-xps_remote_resource_dictionary_has_transparency(xps_context_t *ctx, char *source_att)
+static int
+xps_remote_resource_dictionary_has_transparency(xps_context_t *ctx, char *base_uri, char *source_att)
{
//dputs("page has transparency: uses a remote resource; not parsed; being conservative\n");
return 1;
}
int
-xps_resource_dictionary_has_transparency(xps_context_t *ctx, xps_item_t *root)
+xps_resource_dictionary_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
char *source;
xps_item_t *node;
source = xps_att(root, "Source");
if (source)
- return xps_remote_resource_dictionary_has_transparency(ctx, source);
+ return xps_remote_resource_dictionary_has_transparency(ctx, base_uri, source);
for (node = xps_down(root); node; node = xps_next(node))
{
@@ -43,8 +43,8 @@ xps_resource_dictionary_has_transparency(xps_context_t *ctx, xps_item_t *root)
return 1;
}
-int
-xps_gradient_stops_have_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_gradient_stops_have_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
gs_color_space *colorspace;
@@ -58,7 +58,7 @@ xps_gradient_stops_have_transparency(xps_context_t *ctx, xps_item_t *root)
color_att = xps_att(node, "Color");
if (color_att)
{
- xps_parse_color(ctx, color_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
if (samples[0] < 1.0)
{
//dputs("page has transparency: GradientStop has alpha\n");
@@ -71,8 +71,8 @@ xps_gradient_stops_have_transparency(xps_context_t *ctx, xps_item_t *root)
return 0;
}
-int
-xps_gradient_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_gradient_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
char *opacity_att;
@@ -91,12 +91,12 @@ xps_gradient_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
{
if (!strcmp(xps_tag(node), "RadialGradientBrush.GradientStops"))
{
- if (xps_gradient_stops_have_transparency(ctx, node))
+ if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
return 1;
}
if (!strcmp(xps_tag(node), "LinearGradientBrush.GradientStops"))
{
- if (xps_gradient_stops_have_transparency(ctx, node))
+ if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
return 1;
}
}
@@ -104,8 +104,8 @@ xps_gradient_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
return 0;
}
-int
-xps_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
char *opacity_att;
char *color_att;
@@ -129,7 +129,7 @@ xps_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
color_att = xps_att(root, "Color");
if (color_att)
{
- xps_parse_color(ctx, color_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
if (samples[0] < 1.0)
{
//dputs("page has transparency: SolidColorBrush Color has alpha\n");
@@ -154,7 +154,7 @@ xps_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
{
if (!strcmp(xps_tag(node), "VisualBrush.Visual"))
{
- if (xps_element_has_transparency(ctx, xps_down(node)))
+ if (xps_element_has_transparency(ctx, base_uri, xps_down(node)))
return 1;
}
}
@@ -163,27 +163,27 @@ xps_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
if (!strcmp(xps_tag(root), "ImageBrush"))
{
- if (xps_image_brush_has_transparency(ctx, root))
+ if (xps_image_brush_has_transparency(ctx, base_uri, root))
return 1;
}
if (!strcmp(xps_tag(root), "LinearGradientBrush"))
{
- if (xps_gradient_brush_has_transparency(ctx, root))
+ if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
return 1;
}
if (!strcmp(xps_tag(root), "RadialGradientBrush"))
{
- if (xps_gradient_brush_has_transparency(ctx, root))
+ if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
return 1;
}
return 0;
}
-int
-xps_path_has_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_path_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
@@ -197,13 +197,13 @@ xps_path_has_transparency(xps_context_t *ctx, xps_item_t *root)
if (!strcmp(xps_tag(node), "Path.Stroke"))
{
- if (xps_brush_has_transparency(ctx, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
return 1;
}
if (!strcmp(xps_tag(node), "Path.Fill"))
{
- if (xps_brush_has_transparency(ctx, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
return 1;
}
}
@@ -211,8 +211,8 @@ xps_path_has_transparency(xps_context_t *ctx, xps_item_t *root)
return 0;
}
-int
-xps_glyphs_has_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_glyphs_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
@@ -226,7 +226,7 @@ xps_glyphs_has_transparency(xps_context_t *ctx, xps_item_t *root)
if (!strcmp(xps_tag(node), "Glyphs.Fill"))
{
- if (xps_brush_has_transparency(ctx, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
return 1;
}
}
@@ -234,8 +234,8 @@ xps_glyphs_has_transparency(xps_context_t *ctx, xps_item_t *root)
return 0;
}
-int
-xps_canvas_has_transparency(xps_context_t *ctx, xps_item_t *root)
+static int
+xps_canvas_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
@@ -243,7 +243,7 @@ xps_canvas_has_transparency(xps_context_t *ctx, xps_item_t *root)
{
if (!strcmp(xps_tag(node), "Canvas.Resources"))
{
- if (xps_resource_dictionary_has_transparency(ctx, xps_down(node)))
+ if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
return 1;
}
@@ -253,7 +253,7 @@ xps_canvas_has_transparency(xps_context_t *ctx, xps_item_t *root)
return 1;
}
- if (xps_element_has_transparency(ctx, node))
+ if (xps_element_has_transparency(ctx, base_uri, node))
return 1;
}
@@ -261,7 +261,7 @@ xps_canvas_has_transparency(xps_context_t *ctx, xps_item_t *root)
}
int
-xps_element_has_transparency(xps_context_t *ctx, xps_item_t *node)
+xps_element_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *node)
{
char *opacity_att;
char *stroke_att;
@@ -273,7 +273,7 @@ xps_element_has_transparency(xps_context_t *ctx, xps_item_t *node)
stroke_att = xps_att(node, "Stroke");
if (stroke_att)
{
- xps_parse_color(ctx, stroke_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples);
if (samples[0] < 1.0)
{
//dprintf1("page has transparency: Stroke alpha=%g\n", samples[0]);
@@ -284,7 +284,7 @@ xps_element_has_transparency(xps_context_t *ctx, xps_item_t *node)
fill_att = xps_att(node, "Fill");
if (fill_att)
{
- xps_parse_color(ctx, fill_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
if (samples[0] < 1.0)
{
//dprintf1("page has transparency: Fill alpha=%g\n", samples[0]);
@@ -309,13 +309,13 @@ xps_element_has_transparency(xps_context_t *ctx, xps_item_t *node)
}
if (!strcmp(xps_tag(node), "Path"))
- if (xps_path_has_transparency(ctx, node))
+ if (xps_path_has_transparency(ctx, base_uri, node))
return 1;
if (!strcmp(xps_tag(node), "Glyphs"))
- if (xps_glyphs_has_transparency(ctx, node))
+ if (xps_glyphs_has_transparency(ctx, base_uri, node))
return 1;
if (!strcmp(xps_tag(node), "Canvas"))
- if (xps_canvas_has_transparency(ctx, node))
+ if (xps_canvas_has_transparency(ctx, base_uri, node))
return 1;
return 0;
diff --git a/xps/xpscolor.c b/xps/xpscolor.c
index eb214760e..201e0afa4 100644
--- a/xps/xpscolor.c
+++ b/xps/xpscolor.c
@@ -62,7 +62,7 @@ static int count_commas(char *s)
}
int
-xps_parse_color(xps_context_t *ctx, char *string, gs_color_space **csp, float *samples)
+xps_parse_color(xps_context_t *ctx, char *base_uri, char *string, gs_color_space **csp, float *samples)
{
xps_part_t *part;
char *profile, *p;
@@ -151,15 +151,15 @@ xps_parse_color(xps_context_t *ctx, char *string, gs_color_space **csp, float *s
if (n == 5) /* alpha + CMYK */
*csp = ctx->cmyk;
-#if 0 /* disable ICC profiles for beta */
-
/* Find ICC colorspace part */
- xps_absolute_path(partname, ctx->pwd, profile);
+ xps_absolute_path(partname, base_uri, profile);
part = xps_find_part(ctx, partname);
if (!part)
return gs_throw1(-1, "cannot find icc profile part '%s'", partname);
+#if 0 /* disable ICC profiles for beta */
+
if (!part->icc)
{
code = xps_parse_icc_profile(ctx, &part->icc, (byte*)part->data, part->size, n - 1);
@@ -175,11 +175,11 @@ xps_parse_color(xps_context_t *ctx, char *string, gs_color_space **csp, float *s
else
{
- return gs_throw1(-1, "cannot parse color (%s)\n", string);
+ return gs_throw1(-1, "cannot parse color (%s)", string);
}
}
-stream *
+static stream *
xps_stream_from_buffer(xps_context_t *ctx, byte *data, int length)
{
stream *stm;
@@ -233,8 +233,7 @@ xps_parse_icc_profile(xps_context_t *ctx, gs_color_space **csp, byte *data, int
}
int
-xps_parse_solid_color_brush(xps_context_t *ctx,
- xps_resource_t *dict, xps_item_t *node)
+xps_parse_solid_color_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
char *opacity_att;
char *color_att;
@@ -251,7 +250,7 @@ xps_parse_solid_color_brush(xps_context_t *ctx,
samples[3] = 0.0;
if (color_att)
- xps_parse_color(ctx, color_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
if (opacity_att)
samples[0] = atof(opacity_att);
diff --git a/xps/xpscommon.c b/xps/xpscommon.c
index afe42be7c..075a58095 100644
--- a/xps/xpscommon.c
+++ b/xps/xpscommon.c
@@ -16,30 +16,30 @@
#include "ghostxps.h"
int
-xps_parse_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node)
+xps_parse_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
if (!strcmp(xps_tag(node), "SolidColorBrush"))
- return xps_parse_solid_color_brush(ctx, dict, node);
+ return xps_parse_solid_color_brush(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "ImageBrush"))
- return xps_parse_image_brush(ctx, dict, node);
+ return xps_parse_image_brush(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "VisualBrush"))
- return xps_parse_visual_brush(ctx, dict, node);
+ return xps_parse_visual_brush(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "LinearGradientBrush"))
- return xps_parse_linear_gradient_brush(ctx, dict, node);
+ return xps_parse_linear_gradient_brush(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "RadialGradientBrush"))
- return xps_parse_radial_gradient_brush(ctx, dict, node);
+ return xps_parse_radial_gradient_brush(ctx, base_uri, dict, node);
return gs_throw1(-1, "unknown brush tag: %s", xps_tag(node));
}
int
-xps_parse_element(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *node)
+xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
if (!strcmp(xps_tag(node), "Path"))
- return xps_parse_path(ctx, dict, node);
+ return xps_parse_path(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "Glyphs"))
- return xps_parse_glyphs(ctx, dict, node);
+ return xps_parse_glyphs(ctx, base_uri, dict, node);
if (!strcmp(xps_tag(node), "Canvas"))
- return xps_parse_canvas(ctx, dict, node);
+ return xps_parse_canvas(ctx, base_uri, dict, node);
/* skip unknown tags (like Foo.Resources and similar) */
return 0;
}
diff --git a/xps/xpsdoc.c b/xps/xpsdoc.c
index 2c4c967ba..0f6c22a3d 100644
--- a/xps/xpsdoc.c
+++ b/xps/xpsdoc.c
@@ -259,7 +259,7 @@ void xps_debug_fixdocseq(xps_context_t *ctx)
}
}
-int
+static int
xps_add_fixed_document(xps_context_t *ctx, char *name)
{
xps_document_t *fixdoc;
@@ -314,7 +314,7 @@ xps_free_fixed_documents(xps_context_t *ctx)
ctx->last_fixdoc = NULL;
}
-int
+static int
xps_add_fixed_page(xps_context_t *ctx, char *name, int width, int height)
{
xps_page_t *page;
@@ -383,10 +383,10 @@ xps_free_fixed_pages(xps_context_t *ctx)
* not be drawn more than once.
*/
-void
+static void
xps_free_used_parts(xps_context_t *ctx)
{
- /* TODO: actually do what we should. for now we just free cached resources. */
+ /* Free parsed resources that were used on the last page */
xps_part_t *part = ctx->first_part;
while (part)
{
@@ -394,6 +394,10 @@ xps_free_used_parts(xps_context_t *ctx)
xps_free_part_caches(ctx, part);
part = next;
}
+
+ /* TODO: Free the data for page parts we have rendered */
+ /* TODO: Free the data for parts we don't recognize */
+ /* TODO: Parse DiscardControl parts to free stuff */
}
/*
@@ -434,8 +438,6 @@ xps_handle_metadata(void *zp, char *name, char **atts)
xps_context_t *ctx = zp;
int i;
-#ifdef XPS_LOAD_TYPE_MAPS
-
if (!strcmp(name, "Default"))
{
char *extension = NULL;
@@ -470,8 +472,6 @@ xps_handle_metadata(void *zp, char *name, char **atts)
xps_add_override(ctx, partname, type);
}
-#endif
-
if (!strcmp(name, "Relationship"))
{
char srcbuf[1024];
@@ -517,7 +517,7 @@ xps_handle_metadata(void *zp, char *name, char **atts)
if (source)
{
- xps_absolute_path(srcbuf, ctx->pwd, source);
+ xps_absolute_path(srcbuf, ctx->base_uri, source);
xps_add_fixed_document(ctx, srcbuf);
}
}
@@ -541,7 +541,7 @@ xps_handle_metadata(void *zp, char *name, char **atts)
if (source)
{
- xps_absolute_path(srcbuf, ctx->pwd, source);
+ xps_absolute_path(srcbuf, ctx->base_uri, source);
xps_add_fixed_page(ctx, srcbuf, width, height);
}
}
@@ -551,14 +551,17 @@ static int
xps_process_metadata(xps_context_t *ctx, xps_part_t *part)
{
XML_Parser xp;
+ char buf[1024];
char *s;
/* Save directory name part */
- strcpy(ctx->pwd, part->name);
- s = strrchr(ctx->pwd, '/');
+ strcpy(buf, part->name);
+ s = strrchr(buf, '/');
if (s)
s[1] = 0;
+ ctx->base_uri = buf;
+
xp = XML_ParserCreate(NULL);
if (!xp)
return -1;
@@ -571,6 +574,8 @@ xps_process_metadata(xps_context_t *ctx, xps_part_t *part)
XML_ParserFree(xp);
+ ctx->base_uri = NULL;
+
return 0;
}
@@ -608,7 +613,7 @@ xps_parse_color_relation(xps_context_t *ctx, char *string)
if (ep)
{
*ep = 0;
- xps_absolute_path(path, ctx->pwd, sp);
+ xps_absolute_path(path, ctx->base_uri, sp);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE);
}
@@ -635,7 +640,7 @@ xps_parse_image_relation(xps_context_t *ctx, char *string)
if (ep)
{
*ep = 0;
- xps_absolute_path(path, ctx->pwd, sp);
+ xps_absolute_path(path, ctx->base_uri, sp);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE);
@@ -644,7 +649,7 @@ xps_parse_image_relation(xps_context_t *ctx, char *string)
if (ep)
{
*ep = 0;
- xps_absolute_path(path, ctx->pwd, sp);
+ xps_absolute_path(path, ctx->base_uri, sp);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE);
}
@@ -653,7 +658,7 @@ xps_parse_image_relation(xps_context_t *ctx, char *string)
}
else
{
- xps_absolute_path(path, ctx->pwd, string);
+ xps_absolute_path(path, ctx->base_uri, string);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE);
}
@@ -679,7 +684,7 @@ xps_parse_content_relations_imp(void *zp, char *ns_name, char **atts)
{
if (!strcmp(atts[i], "FontUri"))
{
- xps_absolute_path(path, ctx->pwd, atts[i+1]);
+ xps_absolute_path(path, ctx->base_uri, atts[i+1]);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE);
}
@@ -699,7 +704,7 @@ xps_parse_content_relations_imp(void *zp, char *ns_name, char **atts)
{
if (!strcmp(atts[i], "Source"))
{
- xps_absolute_path(path, ctx->pwd, atts[i+1]);
+ xps_absolute_path(path, ctx->base_uri, atts[i+1]);
xps_trim_url(path);
xps_add_relation(ctx, ctx->state, path, REL_REQUIRED_RESOURCE_RECURSIVE);
}
@@ -725,8 +730,17 @@ int
xps_parse_content_relations(xps_context_t *ctx, xps_part_t *part)
{
XML_Parser xp;
+ char buf[1024];
+ char *s;
+
+ /* Set current directory for resolving relative path names */
+ strcpy(buf, part->name);
+ s = strrchr(buf, '/');
+ if (s)
+ s[1] = 0;
ctx->state = part->name;
+ ctx->base_uri = buf;
if (xps_doc_trace)
dprintf1("doc: parsing relations from content (%s)\n", part->name);
@@ -751,6 +765,7 @@ xps_parse_content_relations(xps_context_t *ctx, xps_part_t *part)
}
ctx->state = NULL;
+ ctx->base_uri = NULL;
return 0;
}
@@ -905,12 +920,6 @@ xps_process_part(xps_context_t *ctx, xps_part_t *part)
int have_resources;
char *s;
- /* Set current directory for resolving relative path names */
- strcpy(ctx->pwd, pagepart->name);
- s = strrchr(ctx->pwd, '/');
- if (s)
- s[1] = 0;
-
if (!pagepart->relations_complete)
{
xps_parse_content_relations(ctx, pagepart);
diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c
index dfeba886e..541f5b56a 100644
--- a/xps/xpsglyphs.c
+++ b/xps/xpsglyphs.c
@@ -78,7 +78,7 @@ void xps_debug_path(xps_context_t *ctx)
* Some fonts in XPS are obfuscated by XOR:ing the first 32 bytes of the
* data with the GUID in the fontname.
*/
-int
+static int
xps_deobfuscate_font_resource(xps_context_t *ctx, xps_part_t *part)
{
byte buf[33];
@@ -124,7 +124,7 @@ xps_deobfuscate_font_resource(xps_context_t *ctx, xps_part_t *part)
return 0;
}
-int
+static int
xps_select_best_font_encoding(xps_font_t *font)
{
static struct { int pid, eid; } xps_cmap_list[] =
@@ -164,7 +164,8 @@ xps_select_best_font_encoding(xps_font_t *font)
* Call text drawing primitives.
*/
-int xps_flush_text_buffer(xps_context_t *ctx, xps_font_t *font,
+static int
+xps_flush_text_buffer(xps_context_t *ctx, xps_font_t *font,
xps_text_buffer_t *buf, int is_charpath)
{
gs_text_params_t params;
@@ -325,7 +326,7 @@ xps_parse_glyph_metrics(char *s, float *advance, float *uofs, float *vofs)
return s;
}
-int
+static int
xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
float originx, float originy, int is_sideways, int bidi_level,
char *indices, char *unicode, int is_charpath)
@@ -461,10 +462,14 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
}
int
-xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_glyphs(xps_context_t *ctx,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
+ char *fill_uri;
+ char *opacity_mask_uri;
+
char *bidi_level_att;
char *caret_stops_att;
char *fill_att;
@@ -538,10 +543,13 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
fill_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
- xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag);
- xps_resolve_resource_reference(ctx, dict, &fill_att, &fill_tag);
- xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag);
+ fill_uri = base_uri;
+ 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, &fill_att, &fill_tag, &fill_uri);
+ xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);
/*
* Check that we have all the necessary information.
@@ -563,9 +571,7 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
* Find and load the font resource
*/
- // TODO: get subfont index from # part of uri
-
- xps_absolute_path(partname, ctx->pwd, font_uri_att);
+ xps_absolute_path(partname, base_uri, font_uri_att);
subfont = strrchr(partname, '#');
if (subfont)
{
@@ -579,13 +585,9 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
/* deobfuscate if necessary */
if (!part->deobfuscated)
{
-#ifdef XPS_LOAD_TYPE_MAPS
parttype = xps_get_content_type(ctx, part->name);
if (parttype && !strcmp(parttype, "application/vnd.ms-package.obfuscated-opentype"))
xps_deobfuscate_font_resource(ctx, part);
-#else
- parttype = NULL;
-#endif
/* stupid XPS files with content-types after the parts */
if (!parttype && strstr(part->name, ".odttf"))
@@ -647,7 +649,7 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
gs_matrix_multiply(&matrix, &font->font->orig_FontMatrix,
&font->font->FontMatrix);
- xps_begin_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
/*
* If it's a solid color brush fill/stroke do a simple fill
@@ -664,7 +666,7 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
{
float samples[32];
gs_color_space *colorspace;
- xps_parse_color(ctx, fill_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
if (fill_opacity_att)
samples[0] = atof(fill_opacity_att);
xps_set_color(ctx, colorspace, samples);
@@ -684,10 +686,10 @@ xps_parse_glyphs(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
xps_parse_glyphs_imp(ctx, font, font_size,
atof(origin_x_att), atof(origin_y_att),
is_sideways, bidi_level, indices_att, unicode_att, 1);
- xps_parse_brush(ctx, dict, fill_tag);
+ xps_parse_brush(ctx, fill_uri, dict, fill_tag);
}
- xps_end_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
diff --git a/xps/xpsgradient.c b/xps/xpsgradient.c
index 0fc3810ca..6cfcb78ec 100644
--- a/xps/xpsgradient.c
+++ b/xps/xpsgradient.c
@@ -28,7 +28,7 @@ enum { SPREAD_PAD, SPREAD_REPEAT, SPREAD_REFLECT };
*/
static int
-xps_parse_gradient_stops(xps_context_t *ctx, xps_item_t *node,
+xps_parse_gradient_stops(xps_context_t *ctx, char *base_uri, xps_item_t *node,
float *offsets, float *colors, int maxcount)
{
int count = 0;
@@ -46,7 +46,7 @@ xps_parse_gradient_stops(xps_context_t *ctx, xps_item_t *node,
{
offsets[count] = atof(offset);
- xps_parse_color(ctx, color, &colorspace, sample);
+ xps_parse_color(ctx, base_uri, color, &colorspace, sample);
/* Convert color to sRGB by calling ICClib directly */
@@ -56,7 +56,7 @@ xps_parse_gradient_stops(xps_context_t *ctx, xps_item_t *node,
double xyz[3];
int i;
- struct _icc *icc = colorspace->params.icc.picc_info->picc;
+ // struct _icc *icc = colorspace->params.icc.picc_info->picc;
struct _icmLuBase *lu = colorspace->params.icc.picc_info->plu;
for (i = 0; i < cs_num_components(colorspace); i++)
@@ -675,7 +675,7 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
*/
static int
-xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root,
+xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
int (*draw)(xps_context_t *, xps_item_t *, int, gs_function_t *))
{
xps_item_t *node;
@@ -720,7 +720,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *r
stop_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
+ xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
spread_method = SPREAD_PAD;
if (spread_att)
@@ -742,7 +742,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *r
if (!stop_tag)
return gs_throw(-1, "missing gradient stops tag");
- stop_count = xps_parse_gradient_stops(ctx, stop_tag, stop_offsets, stop_colors, MAX_STOPS);
+ stop_count = xps_parse_gradient_stops(ctx, base_uri, stop_tag, stop_offsets, stop_colors, MAX_STOPS);
if (stop_count == 0)
return gs_throw(-1, "no gradient stops found");
@@ -764,7 +764,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *r
xps_bounds_in_user_space(ctx, &bbox);
- xps_begin_opacity(ctx, dict, opacity_att, NULL);
+ xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL);
if (ctx->opacity_only)
{
@@ -793,7 +793,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *r
}
}
- xps_end_opacity(ctx, dict, opacity_att, NULL);
+ xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
gs_grestore(ctx->pgs);
@@ -806,20 +806,20 @@ xps_parse_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *r
}
int
-xps_parse_linear_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_linear_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
int code;
- code = xps_parse_gradient_brush(ctx, dict, root, xps_draw_linear_gradient);
+ code = xps_parse_gradient_brush(ctx, base_uri, dict, root, xps_draw_linear_gradient);
if (code < 0)
return gs_rethrow(code, "cannot parse linear gradient brush");
return gs_okay;
}
int
-xps_parse_radial_gradient_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_radial_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
int code;
- code = xps_parse_gradient_brush(ctx, dict, root, xps_draw_radial_gradient);
+ code = xps_parse_gradient_brush(ctx, base_uri, dict, root, xps_draw_radial_gradient);
if (code < 0)
return gs_rethrow(code, "cannot parse radial gradient brush");
return gs_okay;
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index 2adf2e833..c49dadb6e 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -25,8 +25,8 @@ xps_convert_16_to_8(xps_context_t *ctx, xps_image_t *image)
{
int n = image->comps;
int y, x, k;
- unsigned short *sp = image->samples;
- unsigned char *dp = image->samples;
+ unsigned short *sp = (unsigned short *) image->samples;
+ unsigned char *dp = (unsigned char *) image->samples;
for (y = 0; y < image->height; y++)
for (x = 0; x < image->width; x++)
@@ -234,10 +234,9 @@ xps_paint_image_brush_imp(xps_context_t *ctx, xps_image_t *image, int alpha)
}
static int
-xps_paint_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root, void *vimage)
+xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *vimage)
{
xps_image_t *image = vimage;
- int code;
if (ctx->opacity_only)
{
@@ -270,12 +269,11 @@ xps_paint_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root
{
xps_paint_image_brush_imp(ctx, image, 0);
}
-
- return 0;
+return 0;
}
static int
-xps_find_image_brush_source_part(xps_context_t *ctx, xps_item_t *root, xps_part_t **partp)
+xps_find_image_brush_source_part(xps_context_t *ctx, char *base_uri, xps_item_t *root, xps_part_t **partp)
{
xps_part_t *part;
char *image_source_att;
@@ -284,7 +282,6 @@ xps_find_image_brush_source_part(xps_context_t *ctx, xps_item_t *root, xps_part_
char *image_name;
char *profile_name;
char *p;
- int code;
image_source_att = xps_att(root, "ImageSource");
if (!image_source_att)
@@ -325,7 +322,7 @@ xps_find_image_brush_source_part(xps_context_t *ctx, xps_item_t *root, xps_part_
dprintf2("warning: ignoring color profile '%s' associated with image '%s'\n",
profile_name, image_name);
- xps_absolute_path(partname, ctx->pwd, image_name);
+ xps_absolute_path(partname, base_uri, image_name);
part = xps_find_part(ctx, partname);
if (!part)
return gs_throw1(-1, "cannot find image resource part '%s'", partname);
@@ -335,12 +332,12 @@ xps_find_image_brush_source_part(xps_context_t *ctx, xps_item_t *root, xps_part_
}
int
-xps_parse_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_part_t *part;
int code;
- code = xps_find_image_brush_source_part(ctx, root, &part);
+ code = xps_find_image_brush_source_part(ctx, base_uri, root, &part);
if (code < 0)
return gs_rethrow(code, "cannot find image source");
@@ -355,7 +352,7 @@ xps_parse_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root
return gs_rethrow(-1, "cannot decode image resource");
}
- xps_parse_tiling_brush(ctx, dict, root, xps_paint_image_brush, part->image);
+ xps_parse_tiling_brush(ctx, base_uri, dict, root, xps_paint_image_brush, part->image);
/* TODO: free the image data here if the image is only used once on the page */
@@ -363,12 +360,12 @@ xps_parse_image_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root
}
int
-xps_image_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
+xps_image_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_part_t *part;
int code;
- code = xps_find_image_brush_source_part(ctx, root, &part);
+ code = xps_find_image_brush_source_part(ctx, base_uri, root, &part);
if (code < 0)
return gs_rethrow(code, "cannot find image source");
@@ -385,7 +382,7 @@ xps_image_brush_has_transparency(xps_context_t *ctx, xps_item_t *root)
return gs_rethrow(-1, "cannot decode image resource");
}
- return part->image->alpha;
+ return part->image->alpha != NULL;
}
void
diff --git a/xps/xpsmem.c b/xps/xpsmem.c
index 465b3f445..03ec70a64 100644
--- a/xps/xpsmem.c
+++ b/xps/xpsmem.c
@@ -30,7 +30,7 @@ xps_strcasecmp(char *a, char *b)
{
if (*a++ == 0)
return 0;
- *b++;
+ b++;
}
return xps_tolower(*a) - xps_tolower(*b);
}
@@ -104,7 +104,7 @@ xps_clean_path(char *name)
}
void
-xps_absolute_path(char *output, char *pwd, char *path)
+xps_absolute_path(char *output, char *base_uri, char *path)
{
if (path[0] == '/')
{
@@ -112,7 +112,7 @@ xps_absolute_path(char *output, char *pwd, char *path)
}
else
{
- strcpy(output, pwd);
+ strcpy(output, base_uri);
strcat(output, "/");
strcat(output, path);
}
diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c
index e8a1ad834..6390a034b 100644
--- a/xps/xpsopacity.c
+++ b/xps/xpsopacity.c
@@ -16,7 +16,8 @@
#include "ghostxps.h"
int
-xps_begin_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag)
+xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
+ char *opacity_att, xps_item_t *opacity_mask_tag)
{
gs_transparency_group_params_t tgp;
gs_transparency_mask_params_t tmp;
@@ -56,7 +57,7 @@ xps_begin_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, x
save = ctx->opacity_only;
ctx->opacity_only = 1;
- xps_parse_brush(ctx, dict, opacity_mask_tag);
+ xps_parse_brush(ctx, base_uri, dict, opacity_mask_tag);
gs_grestore(ctx->pgs);
@@ -73,7 +74,8 @@ xps_begin_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, x
}
int
-xps_end_opacity(xps_context_t *ctx, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag)
+xps_end_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
+ char *opacity_att, xps_item_t *opacity_mask_tag)
{
if (!opacity_att && !opacity_mask_tag)
return 0;
diff --git a/xps/xpspage.c b/xps/xpspage.c
index 15d4aed39..2b7d3cce8 100644
--- a/xps/xpspage.c
+++ b/xps/xpspage.c
@@ -15,10 +15,11 @@
#include "ghostxps.h"
-int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+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;
char *transform_att;
char *clip_att;
@@ -42,7 +43,7 @@ int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
{
if (!strcmp(xps_tag(node), "Canvas.Resources"))
{
- new_dict = xps_parse_resource_dictionary(ctx, xps_down(node));
+ new_dict = xps_parse_resource_dictionary(ctx, base_uri, xps_down(node));
if (new_dict)
{
new_dict->parent = dict;
@@ -58,9 +59,10 @@ int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
opacity_mask_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
- xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag);
- xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag);
+ 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);
@@ -80,11 +82,11 @@ int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
xps_clip(ctx, &saved_bounds);
}
- xps_begin_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
for (node = xps_down(root); node; node = xps_next(node))
{
- xps_parse_element(ctx, dict, node);
+ xps_parse_element(ctx, base_uri, dict, node);
}
if (clip_att || clip_tag)
@@ -92,7 +94,7 @@ int xps_parse_canvas(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
xps_unclip(ctx, &saved_bounds);
}
- xps_end_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
@@ -116,9 +118,16 @@ xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
gs_point pt0, pt1;
gs_rect rc;
int has_transparency;
+ char base_uri[1024];
+ char *s;
/* dprintf1("xps: page %s\n", part->name); */
+ strcpy(base_uri, part->name);
+ 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");
@@ -196,9 +205,9 @@ xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
for (node = xps_down(root); node; node = xps_next(node))
{
if (!strcmp(xps_tag(node), "FixedPage.Resources"))
- if (xps_resource_dictionary_has_transparency(ctx, xps_down(node)))
+ if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
has_transparency = 1;
- if (xps_element_has_transparency(ctx, node))
+ if (xps_element_has_transparency(ctx, base_uri, node))
has_transparency = 1;
}
@@ -222,8 +231,8 @@ xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
for (node = xps_down(root); node; node = xps_next(node))
{
if (!strcmp(xps_tag(node), "FixedPage.Resources"))
- dict = xps_parse_resource_dictionary(ctx, xps_down(node));
- xps_parse_element(ctx, dict, node);
+ dict = xps_parse_resource_dictionary(ctx, base_uri, xps_down(node));
+ xps_parse_element(ctx, base_uri, dict, node);
}
if (ctx->use_transparency && has_transparency)
diff --git a/xps/xpspath.c b/xps/xpspath.c
index 4f6169307..3af47e64a 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -852,8 +852,8 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro
transform_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
- xps_resolve_resource_reference(ctx, dict, &figures_att, &figures_tag);
+ xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
+ xps_resolve_resource_reference(ctx, dict, &figures_att, &figures_tag, NULL);
if (fill_rule_att)
{
@@ -902,11 +902,15 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro
*/
int
-xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
int code;
+ char *fill_uri;
+ char *stroke_uri;
+ char *opacity_mask_uri;
+
char *transform_att;
char *clip_att;
char *data_att;
@@ -987,12 +991,16 @@ xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
data_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &data_att, &data_tag);
- xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag);
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
- xps_resolve_resource_reference(ctx, dict, &fill_att, &fill_tag);
- xps_resolve_resource_reference(ctx, dict, &stroke_att, &stroke_tag);
- xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag);
+ fill_uri = base_uri;
+ stroke_uri = base_uri;
+ opacity_mask_uri = base_uri;
+
+ xps_resolve_resource_reference(ctx, dict, &data_att, &data_tag, NULL);
+ xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag, NULL);
+ xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
+ xps_resolve_resource_reference(ctx, dict, &fill_att, &fill_tag, &fill_uri);
+ xps_resolve_resource_reference(ctx, dict, &stroke_att, &stroke_tag, &stroke_uri);
+ xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);
/*
* Act on the information we have gathered:
@@ -1092,11 +1100,11 @@ xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
xps_clip(ctx, &saved_bounds);
}
- xps_begin_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
if (fill_att)
{
- xps_parse_color(ctx, fill_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
if (fill_opacity_att)
samples[0] = atof(fill_opacity_att);
xps_set_color(ctx, colorspace, samples);
@@ -1116,14 +1124,14 @@ xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
if (data_tag)
xps_parse_path_geometry(ctx, dict, data_tag, 0);
- code = xps_parse_brush(ctx, dict, fill_tag);
+ code = xps_parse_brush(ctx, fill_uri, dict, fill_tag);
if (code < 0)
gs_catch(code, "cannot parse fill brush. ignoring error.");
}
if (stroke_att)
{
- xps_parse_color(ctx, stroke_att, &colorspace, samples);
+ xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples);
if (stroke_opacity_att)
samples[0] = atof(stroke_opacity_att);
xps_set_color(ctx, colorspace, samples);
@@ -1146,7 +1154,7 @@ xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
ctx->fill_rule = 1; /* over-ride fill rule when converting outline to stroked */
gs_strokepath(ctx->pgs);
- code = xps_parse_brush(ctx, dict, stroke_tag);
+ code = xps_parse_brush(ctx, stroke_uri, dict, stroke_tag);
if (code < 0)
gs_catch(code, "cannot parse stroke brush. ignoring error.");
}
@@ -1156,7 +1164,7 @@ xps_parse_path(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
xps_unclip(ctx, &saved_bounds);
}
- xps_end_opacity(ctx, dict, opacity_att, opacity_mask_tag);
+ xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
diff --git a/xps/xpsresource.c b/xps/xpsresource.c
index 865e20a57..4dd3a665c 100644
--- a/xps/xpsresource.c
+++ b/xps/xpsresource.c
@@ -16,18 +16,26 @@
#include "ghostxps.h"
static xps_item_t *
-xps_find_resource(xps_context_t *ctx, xps_resource_t *dict, char *name)
+xps_find_resource(xps_context_t *ctx, xps_resource_t *dict, char *name, char **urip)
{
xps_resource_t *head, *node;
for (head = dict; head; head = head->parent)
+ {
for (node = head; node; node = node->next)
+ {
if (!strcmp(node->name, name))
+ {
+ if (urip && head->base_uri)
+ *urip = head->base_uri;
return node->data;
+ }
+ }
+ }
return NULL;
}
static xps_item_t *
-xps_parse_resource_reference(xps_context_t *ctx, xps_resource_t *dict, char *att)
+xps_parse_resource_reference(xps_context_t *ctx, xps_resource_t *dict, char *att, char **urip)
{
char name[1024];
char *s;
@@ -40,16 +48,16 @@ xps_parse_resource_reference(xps_context_t *ctx, xps_resource_t *dict, char *att
if (s)
*s = 0;
- return xps_find_resource(ctx, dict, name);
+ return xps_find_resource(ctx, dict, name, urip);
}
int
xps_resolve_resource_reference(xps_context_t *ctx, xps_resource_t *dict,
- char **attp, xps_item_t **tagp)
+ char **attp, xps_item_t **tagp, char **urip)
{
if (*attp)
{
- xps_item_t *rsrc = xps_parse_resource_reference(ctx, dict, *attp);
+ xps_item_t *rsrc = xps_parse_resource_reference(ctx, dict, *attp, urip);
if (rsrc)
{
*attp = NULL;
@@ -60,12 +68,15 @@ xps_resolve_resource_reference(xps_context_t *ctx, xps_resource_t *dict,
}
xps_resource_t *
-xps_parse_remote_resource_dictionary(xps_context_t *ctx, char *source_att)
+xps_parse_remote_resource_dictionary(xps_context_t *ctx, char *base_uri, char *source_att)
{
char part_name[1024];
+ char part_uri[1024];
xps_part_t *part;
+ char *s;
- xps_absolute_path(part_name, ctx->pwd, source_att);
+ /* External resource dictionaries MUST NOT reference other resource dictionaries */
+ xps_absolute_path(part_name, base_uri, source_att);
part = xps_find_part(ctx, part_name);
if (!part)
{
@@ -89,11 +100,16 @@ xps_parse_remote_resource_dictionary(xps_context_t *ctx, char *source_att)
return NULL;
}
- return xps_parse_resource_dictionary(ctx, part->xml);
+ strcpy(part_uri, part_name);
+ s = strrchr(part_uri, '/');
+ if (s)
+ s[1] = 0;
+
+ return xps_parse_resource_dictionary(ctx, part_uri, part->xml);
}
xps_resource_t *
-xps_parse_resource_dictionary(xps_context_t *ctx, xps_item_t *root)
+xps_parse_resource_dictionary(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_resource_t *head;
xps_resource_t *entry;
@@ -103,7 +119,7 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_item_t *root)
source = xps_att(root, "Source");
if (source)
- return xps_parse_remote_resource_dictionary(ctx, source);
+ return xps_parse_remote_resource_dictionary(ctx, base_uri, source);
head = NULL;
@@ -120,6 +136,7 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_item_t *root)
return head;
}
entry->name = key;
+ entry->base_uri = NULL;
entry->data = node;
entry->next = head;
entry->parent = NULL;
@@ -127,17 +144,41 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_item_t *root)
}
}
+ head->base_uri = xps_alloc(ctx, strlen(base_uri) + 1);
+ strcpy(head->base_uri, base_uri);
+
return head;
}
-void xps_free_resource_dictionary(xps_context_t *ctx, xps_resource_t *dict)
+void
+xps_free_resource_dictionary(xps_context_t *ctx, xps_resource_t *dict)
{
xps_resource_t *next;
while (dict)
{
next = dict->next;
+ if (dict->base_uri)
+ xps_free(ctx, dict->base_uri);
xps_free(ctx, dict);
dict = next;
}
}
+void
+xps_debug_resource_dictionary(xps_resource_t *dict)
+{
+ while (dict)
+ {
+ if (dict->base_uri)
+ dprintf1("URI = '%s'\n", dict->base_uri);
+ dprintf2("KEY = '%s' VAL = %p\n", dict->name, dict->data);
+ if (dict->parent)
+ {
+ dputs("PARENT = {\n");
+ xps_debug_resource_dictionary(dict->parent);
+ dputs("}\n");
+ }
+ dict = dict->next;
+ }
+}
+
diff --git a/xps/xpstile.c b/xps/xpstile.c
index daac00ecd..b4e9f5895 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -25,12 +25,13 @@ enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y };
struct tile_closure_s
{
xps_context_t *ctx;
+ char *base_uri;
xps_resource_t *dict;
xps_item_t *tag;
gs_rect viewbox;
int tile_mode;
void *user;
- int (*func)(xps_context_t*, xps_resource_t*, xps_item_t*, void*);
+ int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*);
};
static int
@@ -59,7 +60,7 @@ xps_paint_tiling_brush_clipped(struct tile_closure_s *c)
ctx->bounds = c->viewbox; // transform?
- code = c->func(c->ctx, c->dict, c->tag, c->user);
+ code = c->func(c->ctx, c->base_uri, c->dict, c->tag, c->user);
ctx->bounds = saved_bounds;
@@ -114,8 +115,8 @@ xps_paint_tiling_brush(const gs_client_color *pcc, gs_state *pgs)
}
int
-xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root,
- int (*func)(xps_context_t*, xps_resource_t*, xps_item_t*, void*), void *user)
+xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
+ int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user)
{
xps_item_t *node;
@@ -151,7 +152,7 @@ xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *roo
transform_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag);
+ xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
gs_make_identity(&transform);
if (transform_att)
@@ -195,7 +196,7 @@ xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *roo
gs_gsave(ctx->pgs);
- xps_begin_opacity(ctx, dict, opacity_att, NULL);
+ xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL);
if (tile_mode != TILE_NONE)
{
@@ -206,6 +207,7 @@ xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *roo
gs_color_space *cs;
closure.ctx = ctx;
+ closure.base_uri = base_uri;
closure.dict = dict;
closure.tag = root;
closure.tile_mode = tile_mode;
@@ -280,12 +282,12 @@ xps_parse_tiling_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *roo
gs_clip(ctx->pgs);
gs_newpath(ctx->pgs);
- func(ctx, dict, root, user);
+ func(ctx, base_uri, dict, root, user);
xps_unclip(ctx, &saved_bounds);
}
- xps_end_opacity(ctx, dict, opacity_att, NULL);
+ xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
gs_grestore(ctx->pgs);
diff --git a/xps/xpstop.c b/xps/xpstop.c
index 5a4aded80..55cee16ac 100644
--- a/xps/xpstop.c
+++ b/xps/xpstop.c
@@ -110,6 +110,7 @@ xps_imp_allocate_interp_instance(pl_interp_instance_t **ppinstance,
ctx->memory = pmem;
ctx->pgs = pgs;
ctx->fontdir = NULL;
+ ctx->file = NULL;
/* TODO: load some builtin ICC profiles here */
ctx->gray = gs_cspace_new_DeviceGray(ctx->memory); /* profile for gray images */
@@ -347,6 +348,12 @@ xps_imp_dnit_job(pl_interp_instance_t *pinstance)
ctx->defaults = NULL;
}
+ if (ctx->file)
+ {
+ fclose(ctx->file);
+ ctx->file = NULL;
+ }
+
return 0;
}
diff --git a/xps/xpsvisual.c b/xps/xpsvisual.c
index 45f245138..5f73628eb 100644
--- a/xps/xpsvisual.c
+++ b/xps/xpsvisual.c
@@ -25,16 +25,17 @@ struct userdata
};
static int
-xps_paint_visual_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root, void *visual_tag)
+xps_paint_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *visual_tag)
{
- return xps_parse_element(ctx, dict, (xps_item_t *)visual_tag);
+ return xps_parse_element(ctx, base_uri, dict, (xps_item_t *)visual_tag);
}
int
-xps_parse_visual_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root)
+xps_parse_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
+ char *visual_uri;
char *visual_att;
xps_item_t *visual_tag = NULL;
@@ -46,11 +47,12 @@ xps_parse_visual_brush(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *roo
visual_tag = xps_down(node);
}
- xps_resolve_resource_reference(ctx, dict, &visual_att, &visual_tag);
+ visual_uri = base_uri;
+ xps_resolve_resource_reference(ctx, dict, &visual_att, &visual_tag, &visual_uri);
if (visual_tag)
{
- xps_parse_tiling_brush(ctx, dict, root, xps_paint_visual_brush, visual_tag);
+ xps_parse_tiling_brush(ctx, visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
}
return 0;
diff --git a/xps/xpsxml.c b/xps/xpsxml.c
index d71fbee74..09f04dd6e 100644
--- a/xps/xpsxml.c
+++ b/xps/xpsxml.c
@@ -31,6 +31,7 @@ struct xps_parser_s
xps_item_t *head;
const char *error;
int compat;
+ char *base; /* base of relative URIs */
};
struct xps_item_s