diff options
-rw-r--r-- | xps/ghostxps.h | 48 | ||||
-rw-r--r-- | xps/xpsanalyze.c | 70 | ||||
-rw-r--r-- | xps/xpscolor.c | 17 | ||||
-rw-r--r-- | xps/xpscommon.c | 20 | ||||
-rw-r--r-- | xps/xpsdoc.c | 57 | ||||
-rw-r--r-- | xps/xpsglyphs.c | 42 | ||||
-rw-r--r-- | xps/xpsgradient.c | 24 | ||||
-rw-r--r-- | xps/xpsimage.c | 27 | ||||
-rw-r--r-- | xps/xpsmem.c | 6 | ||||
-rw-r--r-- | xps/xpsopacity.c | 8 | ||||
-rw-r--r-- | xps/xpspage.c | 33 | ||||
-rw-r--r-- | xps/xpspath.c | 38 | ||||
-rw-r--r-- | xps/xpsresource.c | 63 | ||||
-rw-r--r-- | xps/xpstile.c | 18 | ||||
-rw-r--r-- | xps/xpstop.c | 7 | ||||
-rw-r--r-- | xps/xpsvisual.c | 12 | ||||
-rw-r--r-- | xps/xpsxml.c | 1 |
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 |