From 5fc4bcb1f361a2b60e6841472afaf4a3cbd82ea8 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 28 Mar 2011 22:51:15 +0200 Subject: xps: More fixes and cleanups to parsing. --- xps/muxps.h | 29 +++---- xps/xpscolor.c | 6 +- xps/xpscommon.c | 32 ++++---- xps/xpsglyphs.c | 106 ++++++++----------------- xps/xpsgradient.c | 91 ++++++--------------- xps/xpsimage.c | 34 ++++---- xps/xpsopacity.c | 16 ++-- xps/xpspage.c | 43 ++++------ xps/xpspath.c | 70 ++++++---------- xps/xpstile.c | 233 +++++++++++++----------------------------------------- xps/xpstop.c | 19 +---- xps/xpsvisual.c | 20 +---- xps/xpsxml.c | 8 +- 13 files changed, 212 insertions(+), 495 deletions(-) diff --git a/xps/muxps.h b/xps/muxps.h index f2145d2f..256ea702 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -205,17 +205,17 @@ void xps_debug_resource_dictionary(xps_resource_t *dict); */ int xps_load_fixed_page(xps_context_t *ctx, xps_page_t *page); -int xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page); -int xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_linear_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_radial_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); - -int xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, int (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user); +void xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page); +void xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_linear_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_radial_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); + +void xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, void(*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user); void xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, fz_matrix *matrix); void xps_parse_render_transform(xps_context_t *ctx, char *text, fz_matrix *matrix); @@ -223,11 +223,11 @@ void xps_parse_rectangle(xps_context_t *ctx, char *text, fz_rect *rect); void xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom); void 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, fz_matrix ctm, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag); +void xps_begin_opacity(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag); void 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, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); -int xps_parse_element(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); +void xps_parse_element(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node); void xps_fill(xps_context_t *ctx, fz_matrix ctm); void xps_clip(xps_context_t *ctx, fz_matrix ctm); @@ -289,6 +289,7 @@ struct xps_context_s /* Current path being accumulated */ fz_path *path; + fz_text *text; /* ... or text, for clipping brushes */ /* Current color */ fz_colorspace *colorspace; diff --git a/xps/xpscolor.c b/xps/xpscolor.c index 2c701c4a..558bde7c 100644 --- a/xps/xpscolor.c +++ b/xps/xpscolor.c @@ -200,7 +200,7 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename) #endif } -int +void xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node) { char *opacity_att; @@ -219,13 +219,9 @@ xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, x if (color_att) xps_parse_color(ctx, base_uri, color_att, &colorspace, samples); - if (opacity_att) samples[0] = atof(opacity_att); xps_set_color(ctx, colorspace, samples); - xps_fill(ctx, ctm); - - return 0; } diff --git a/xps/xpscommon.c b/xps/xpscommon.c index 4ba38f7c..dd8762e8 100644 --- a/xps/xpscommon.c +++ b/xps/xpscommon.c @@ -1,33 +1,33 @@ #include "fitz.h" #include "muxps.h" -int +void xps_parse_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node) { if (!strcmp(xps_tag(node), "SolidColorBrush")) - return xps_parse_solid_color_brush(ctx, ctm, base_uri, dict, node); - if (!strcmp(xps_tag(node), "ImageBrush")) - return xps_parse_image_brush(ctx, ctm, base_uri, dict, node); - if (!strcmp(xps_tag(node), "VisualBrush")) - return xps_parse_visual_brush(ctx, ctm, base_uri, dict, node); - if (!strcmp(xps_tag(node), "LinearGradientBrush")) - return xps_parse_linear_gradient_brush(ctx, ctm, base_uri, dict, node); - if (!strcmp(xps_tag(node), "RadialGradientBrush")) - return xps_parse_radial_gradient_brush(ctx, ctm, base_uri, dict, node); - return fz_throw("unknown brush tag: %s", xps_tag(node)); + xps_parse_solid_color_brush(ctx, ctm, base_uri, dict, node); + else if (!strcmp(xps_tag(node), "ImageBrush")) + xps_parse_image_brush(ctx, ctm, base_uri, dict, node); + else if (!strcmp(xps_tag(node), "VisualBrush")) + xps_parse_visual_brush(ctx, ctm, base_uri, dict, node); + else if (!strcmp(xps_tag(node), "LinearGradientBrush")) + xps_parse_linear_gradient_brush(ctx, ctm, base_uri, dict, node); + else if (!strcmp(xps_tag(node), "RadialGradientBrush")) + xps_parse_radial_gradient_brush(ctx, ctm, base_uri, dict, node); + else + fz_warn("unknown brush tag: %s", xps_tag(node)); } -int +void xps_parse_element(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node) { if (!strcmp(xps_tag(node), "Path")) - return xps_parse_path(ctx, ctm, base_uri, dict, node); + xps_parse_path(ctx, ctm, base_uri, dict, node); if (!strcmp(xps_tag(node), "Glyphs")) - return xps_parse_glyphs(ctx, ctm, base_uri, dict, node); + xps_parse_glyphs(ctx, ctm, base_uri, dict, node); if (!strcmp(xps_tag(node), "Canvas")) - return xps_parse_canvas(ctx, ctm, base_uri, dict, node); + xps_parse_canvas(ctx, ctm, base_uri, dict, node); /* skip unknown tags (like Foo.Resources and similar) */ - return 0; } void diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c index 76da97b1..29ab1e02 100644 --- a/xps/xpsglyphs.c +++ b/xps/xpsglyphs.c @@ -101,7 +101,7 @@ xps_select_best_font_encoding(fz_font *font) * Call text drawing primitives. */ -static int +static void xps_flush_text_buffer(xps_context_t *ctx, fz_font *font, xps_text_buffer_t *buf, int is_charpath) { @@ -149,8 +149,6 @@ xps_flush_text_buffer(xps_context_t *ctx, fz_font *font, gs_text_release(textenum, "gslt font render"); #endif buf->count = 0; - - return 0; } /* @@ -239,7 +237,7 @@ xps_parse_glyph_metrics(char *s, float *advance, float *uofs, float *vofs) * Parse unicode and indices strings and encode glyphs. * Calculate metrics for positioning. */ -static int +static void xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size, float originx, float originy, int is_sideways, int bidi_level, char *indices, char *unicode, int is_charpath) @@ -251,12 +249,11 @@ xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size, char *us = unicode; char *is = indices; int un = 0; - int code; buf.count = 0; if (!unicode && !indices) - return fz_throw("no text in glyphs element"); + return; if (us) { @@ -300,8 +297,6 @@ xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size, if (us && un > 0) { int t = xps_utf8_to_ucs(&char_code, us, un); - if (t < 0) - return fz_rethrow(-1, "error decoding UTF-8 string"); us += t; un -= t; } code_count --; @@ -339,9 +334,7 @@ xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size, if (buf.count == XPS_TEXT_BUFFER_SIZE) { - code = xps_flush_text_buffer(ctx, font, &buf, is_charpath); - if (code) - return fz_rethrow(code, "cannot flush buffered text"); + xps_flush_text_buffer(ctx, font, &buf, is_charpath); } if (is_sideways) @@ -363,15 +356,11 @@ xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size, if (buf.count > 0) { - code = xps_flush_text_buffer(ctx, font, &buf, is_charpath); - if (code) - return fz_rethrow(code, "cannot flush buffered text"); + xps_flush_text_buffer(ctx, font, &buf, is_charpath); } - - return 0; } -int +void xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { @@ -410,7 +399,6 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, char partname[1024]; char *subfont; - fz_matrix matrix; float font_size = 10.0; int subfontid = 0; int is_sideways = 0; @@ -440,13 +428,10 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, { if (!strcmp(xps_tag(node), "Glyphs.RenderTransform")) transform_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Glyphs.OpacityMask")) opacity_mask_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Glyphs.Clip")) clip_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Glyphs.Fill")) fill_tag = xps_down(node); } @@ -463,11 +448,13 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, * Check that we have all the necessary information. */ - if (!font_size_att || !font_uri_att || !origin_x_att || !origin_y_att) - return fz_throw("missing attributes in glyphs element"); + if (!font_size_att || !font_uri_att || !origin_x_att || !origin_y_att) { + fz_warn("missing attributes in glyphs element"); + return; + } if (!indices_att && !unicode_att) - return 0; /* nothing to draw */ + return; /* nothing to draw */ if (is_sideways_att) is_sideways = !strcmp(is_sideways_att, "true"); @@ -491,8 +478,10 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, if (!font) { part = xps_read_part(ctx, partname); - if (!part) - return fz_throw("cannot find font resource part '%s'", partname); + if (!part) { + fz_warn("cannot find font resource part '%s'", partname); + return; + } /* deobfuscate if necessary */ if (strstr(part->name, ".odttf")) @@ -501,8 +490,11 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, xps_deobfuscate_font_resource(ctx, part); code = fz_newfontfrombuffer(&font, part->data, part->size, subfontid); - if (code) - return fz_rethrow(code, "cannot load font resource '%s'", partname); + if (code) { + fz_catch(code, "cannot load font resource '%s'", partname); + xps_free_part(ctx, part); + return; + } xps_select_best_font_encoding(font); @@ -515,19 +507,15 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, /* * Set up graphics state. */ -#if 0 - gs_gsave(ctx->pgs); if (transform_att || transform_tag) { fz_matrix transform; - if (transform_att) xps_parse_render_transform(ctx, transform_att, &transform); if (transform_tag) xps_parse_matrix_transform(ctx, transform_tag, &transform); - - gs_concat(ctx->pgs, &transform); + ctm = fz_concat(ctm, transform); } if (clip_att || clip_tag) @@ -537,26 +525,15 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, xps_parse_abbreviated_geometry(ctx, clip_att); if (clip_tag) xps_parse_path_geometry(ctx, dict, clip_tag, 0); - xps_clip(ctx); + xps_clip(ctx, ctm); } font_size = atof(font_size_att); - gs_setfont(ctx->pgs, font->font); - gs_make_scaling(font_size, -font_size, &matrix); if (is_sideways) - fz_matrix_rotate(&matrix, 90.0, &matrix); - - gs_setcharmatrix(ctx->pgs, &matrix); + fz_warn("sideways text not implemented!"); - fz_matrix_multiply(&matrix, &font->font->orig_FontMatrix, &font->font->FontMatrix); - - code = xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - if (code) - { - gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot create transparency group"); - } + xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); /* * If it's a solid color brush fill/stroke do a simple fill @@ -573,20 +550,16 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, { float samples[32]; fz_colorspace *colorspace; + 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); - code = xps_parse_glyphs_imp(ctx, font, font_size, + + xps_parse_glyphs_imp(ctx, font, font_size, atof(origin_x_att), atof(origin_y_att), is_sideways, bidi_level, indices_att, unicode_att, 0); - if (code) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse glyphs data"); - } } /* @@ -595,29 +568,18 @@ xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, if (fill_tag) { + fz_warn("glyphs filled with general brushes not implemented!"); +#if 0 ctx->fill_rule = 1; /* always use non-zero winding rule for char paths */ - code = xps_parse_glyphs_imp(ctx, font, font_size, + 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); - if (code) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse glyphs data"); - } - - code = xps_parse_brush(ctx, fill_uri, dict, fill_tag); - if (code) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse fill brush"); - } + xps_parse_brush(ctx, ctm, fill_uri, dict, fill_tag); +#endif } xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - gs_grestore(ctx->pgs); -#endif - return 0; + if (clip_att || clip_tag) + ctx->dev->popclip(ctx->dev->user); } diff --git a/xps/xpsgradient.c b/xps/xpsgradient.c index 3bb95824..8baf6805 100644 --- a/xps/xpsgradient.c +++ b/xps/xpsgradient.c @@ -186,7 +186,7 @@ xps_gradient_has_transparent_colors(struct stop *stops, int count) * mess with the transform to squash the circle into the right aspect. */ -static int +static void xps_draw_one_radial_gradient(xps_context_t *ctx, int extend, float x0, float y0, float r0, @@ -230,14 +230,13 @@ xps_draw_one_radial_gradient(xps_context_t *ctx, gs_free_object(mem, shading, "gs_shading_R"); #endif - return 0; } /* * Linear gradients map to Axial shadings. */ -static int +static void xps_draw_one_linear_gradient(xps_context_t *ctx, int extend, float x0, float y0, float x1, float y1) @@ -278,7 +277,6 @@ xps_draw_one_linear_gradient(xps_context_t *ctx, gs_free_object(mem, shading, "gs_shading_A"); #endif - return 0; } /* @@ -296,7 +294,7 @@ static inline float point_inside_circle(float px, float py, float x, float y, fl return (dx * dx + dy * dy) <= (r * r); } -static int +static void xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) { fz_rect bbox; @@ -306,7 +304,6 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) float yrad = 1; float invscale; float dx, dy; - int code; int i; int done; @@ -380,24 +377,12 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) // reverse = xps_reverse_function(ctx, func, fary, vary); - code = xps_draw_one_radial_gradient(ctx, reverse, 1, x1, y1, r1, x0, y0, r0); - if (code < 0) - { - xps_free(ctx, reverse); - gs_grestore(ctx->pgs); - return fz_rethrow(code, "could not draw radial gradient"); - } - + xps_draw_one_radial_gradient(ctx, reverse, 1, x1, y1, r1, x0, y0, r0); #endif } else { - code = xps_draw_one_radial_gradient(ctx, 1, x0, y0, r0, x1, y1, r1); - if (code < 0) - { -// gs_grestore(ctx->pgs); - return fz_rethrow(code, "could not draw radial gradient"); - } + xps_draw_one_radial_gradient(ctx, 1, x0, y0, r0, x1, y1, r1); } } else @@ -410,14 +395,9 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) printf("xps: we should reverse gradient here too\n"); if (spread == SPREAD_REFLECT && (i & 1)) - code = xps_draw_one_radial_gradient(ctx, 0, x1, y1, r1, x0, y0, r0); + xps_draw_one_radial_gradient(ctx, 0, x1, y1, r1, x0, y0, r0); else - code = xps_draw_one_radial_gradient(ctx, 0, x0, y0, r0, x1, y1, r1); - if (code < 0) - { -// gs_grestore(ctx->pgs); - return fz_rethrow(code, "could not draw axial gradient"); - } + xps_draw_one_radial_gradient(ctx, 0, x0, y0, r0, x1, y1, r1); /* Check if circle encompassed the entire bounding box (break loop if we do) */ @@ -440,10 +420,6 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) y1 += dy; } } - -// gs_grestore(ctx->pgs); - - return 0; } /* @@ -451,13 +427,12 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread) * the bounding box. */ -static int +static void xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread) { fz_rect bbox; float x0, y0, x1, y1; float dx, dy; - int code; int i; char *start_point_att = xps_att(root, "StartPoint"); @@ -480,9 +455,7 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread) if (spread == SPREAD_PAD) { - code = xps_draw_one_linear_gradient(ctx, 1, x0, y0, x1, y1); - if (code < 0) - return fz_rethrow(code, "could not draw axial gradient"); + xps_draw_one_linear_gradient(ctx, 1, x0, y0, x1, y1); } else { @@ -515,23 +488,15 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread) for (i = i0; i < i1; i++) { if (spread == SPREAD_REFLECT && (i & 1)) - { - code = xps_draw_one_linear_gradient(ctx, 0, + xps_draw_one_linear_gradient(ctx, 0, x1 + dx * i, y1 + dy * i, x0 + dx * i, y0 + dy * i); - } else - { - code = xps_draw_one_linear_gradient(ctx, 0, + xps_draw_one_linear_gradient(ctx, 0, x0 + dx * i, y0 + dy * i, x1 + dx * i, y1 + dy * i); - } - if (code < 0) - return fz_rethrow(code, "could not draw axial gradient"); } } - - return 0; } /* @@ -539,10 +504,10 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread) * function objects and call gradient drawing primitives. */ -static int +static void xps_parse_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, - int (*draw)(xps_context_t *, xps_item_t *, int)) + void (*draw)(xps_context_t *, xps_item_t *, int)) { xps_item_t *node; @@ -604,12 +569,16 @@ xps_parse_gradient_brush(xps_context_t *ctx, fz_matrix ctm, xps_parse_matrix_transform(ctx, transform_tag, &transform); ctm = fz_concat(ctm, transform); - if (!stop_tag) - return fz_throw("missing gradient stops tag"); + if (!stop_tag) { + fz_warn("missing gradient stops tag"); + return; + } stop_count = xps_parse_gradient_stops(ctx, base_uri, stop_tag, stop_list, MAX_STOPS); - if (stop_count == 0) - return fz_throw("no gradient stops found"); + if (stop_count == 0) { + fz_warn("no gradient stops found"); + return; + } /* color_func = xps_create_gradient_stop_function(ctx, stop_list, stop_count, 0); @@ -689,28 +658,18 @@ xps_parse_gradient_brush(xps_context_t *ctx, fz_matrix ctm, // xps_free_gradient_stop_function(ctx, opacity_func); // xps_free_gradient_stop_function(ctx, color_func); - - return 0; } -int +void xps_parse_linear_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { - int code; - code = xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_linear_gradient); - if (code < 0) - return fz_rethrow(code, "cannot parse linear gradient brush"); - return fz_okay; + xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_linear_gradient); } -int +void xps_parse_radial_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { - int code; - code = xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_radial_gradient); - if (code < 0) - return fz_rethrow(code, "cannot parse radial gradient brush"); - return fz_okay; + xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_radial_gradient); } diff --git a/xps/xpsimage.c b/xps/xpsimage.c index 15257594..5cd03418 100644 --- a/xps/xpsimage.c +++ b/xps/xpsimage.c @@ -43,7 +43,7 @@ xps_decode_image(xps_context_t *ctx, xps_part_t *part, xps_image_t *image) return fz_okay; } -static int +static void xps_paint_image_brush_imp(xps_context_t *ctx, fz_matrix ctm, xps_image_t *image) { fz_colorspace *colorspace; @@ -54,12 +54,10 @@ xps_paint_image_brush_imp(xps_context_t *ctx, fz_matrix ctm, xps_image_t *image) samples = image->samples; count = image->stride * image->height; - // xxx - - return 0; +printf("xps_paint_image_brush_imp!\n"); } -static int +static void xps_paint_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *vimage) { #if 0 @@ -124,7 +122,6 @@ xps_paint_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_res return fz_rethrow(code, "cannot draw image"); } #endif - return 0; } static int @@ -186,7 +183,7 @@ xps_find_image_brush_source_part(xps_context_t *ctx, char *base_uri, xps_item_t return 0; } -int +void xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { xps_part_t *part; @@ -198,18 +195,19 @@ xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_res profilename = NULL; code = xps_find_image_brush_source_part(ctx, base_uri, root, &part, &profilename); - if (code < 0) - return fz_rethrow(code, "cannot find image source"); + if (code < 0) { + fz_catch(code, "cannot find image source"); + return; + } image = xps_alloc(ctx, sizeof(xps_image_t)); - if (!image) - return fz_throw("out of memory: image struct"); - -return 0; code = xps_decode_image(ctx, part, image); - if (code < 0) - return fz_rethrow(-1, "cannot decode image resource"); + if (code < 0) { + fz_free(image); + fz_catch(-1, "cannot decode image resource"); + return; + } /* Override any embedded colorspace profiles if the external one matches. */ if (profilename) @@ -222,16 +220,12 @@ return 0; } } - code = xps_parse_tiling_brush(ctx, ctm, base_uri, dict, root, xps_paint_image_brush, image); - if (code < 0) - return fz_rethrow(-1, "cannot parse tiling brush"); + xps_parse_tiling_brush(ctx, ctm, base_uri, dict, root, xps_paint_image_brush, image); if (profilename) xps_free(ctx, profilename); xps_free_image(ctx, image); xps_free_part(ctx, part); - - return 0; } void diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c index e4923f14..8bab138e 100644 --- a/xps/xpsopacity.c +++ b/xps/xpsopacity.c @@ -21,17 +21,18 @@ xps_bounds_in_user_space(xps_context_t *ctx, fz_rect *ubox) #endif } -int +void xps_begin_opacity(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag) { fz_rect bbox; float opacity; int save; - int code; + +return; if (!opacity_att && !opacity_mask_tag) - return 0; + return; opacity = 1.0; if (opacity_att) @@ -47,19 +48,12 @@ xps_begin_opacity(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resourc ctx->opacity_only = 1; // begin mask - code = xps_parse_brush(ctx, ctm, base_uri, dict, opacity_mask_tag); - if (code) - { - ctx->opacity_only = save; - return fz_rethrow(code, "cannot parse opacity mask brush"); - } + xps_parse_brush(ctx, ctm, base_uri, dict, opacity_mask_tag); ctx->opacity_only = save; } // begin group - - return 0; } void diff --git a/xps/xpspage.c b/xps/xpspage.c index 858f327f..f27b4287 100644 --- a/xps/xpspage.c +++ b/xps/xpspage.c @@ -1,7 +1,7 @@ #include "fitz.h" #include "muxps.h" -int +void xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { xps_resource_t *new_dict = NULL; @@ -31,9 +31,12 @@ xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource { code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xps_down(node)); if (code) - return fz_rethrow(code, "cannot load Canvas.Resources"); - new_dict->parent = dict; - dict = new_dict; + fz_catch(code, "cannot load Canvas.Resources"); + else + { + new_dict->parent = dict; + dict = new_dict; + } } if (!strcmp(xps_tag(node), "Canvas.RenderTransform")) @@ -49,8 +52,6 @@ xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource 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); - transform = fz_identity; if (transform_att) xps_parse_render_transform(ctx, transform_att, &transform); @@ -68,35 +69,23 @@ xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource xps_clip(ctx, ctm); } - code = xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - if (code) - { -// gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot create transparency group"); - } + xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); for (node = xps_down(root); node; node = xps_next(node)) { - code = xps_parse_element(ctx, ctm, base_uri, dict, node); - if (code) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); -// gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse child of Canvas"); - } + xps_parse_element(ctx, ctm, base_uri, dict, node); } xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); -// gs_grestore(ctx->pgs); + if (clip_att || clip_tag) + ctx->dev->popclip(ctx->dev->user); if (new_dict) xps_free_resource_dictionary(ctx, new_dict); - - return 0; } -int +void xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page) { xps_item_t *node; @@ -118,19 +107,15 @@ xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page) { code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node)); if (code) - return fz_rethrow(code, "cannot load FixedPage.Resources"); + fz_catch(code, "cannot load FixedPage.Resources"); } - code = xps_parse_element(ctx, ctm, base_uri, dict, node); - if (code) - return fz_rethrow(code, "cannot parse child of FixedPage"); + xps_parse_element(ctx, ctm, base_uri, dict, node); } if (dict) { xps_free_resource_dictionary(ctx, dict); } - - return fz_okay; } int diff --git a/xps/xpspath.c b/xps/xpspath.c index 12377501..78925a8b 100644 --- a/xps/xpspath.c +++ b/xps/xpspath.c @@ -38,18 +38,22 @@ fz_currentpoint(fz_path *path) void xps_clip(xps_context_t *ctx, fz_matrix ctm) { -printf("xps_clip\n"); - assert(ctx->path); -// ctx->dev->clippath(ctx->dev, ctx->path, ctx->fill_rule == 0, ctm); - fz_freepath(ctx->path); - ctx->path = NULL; + if (ctx->path) + { + ctx->dev->clippath(ctx->dev->user, ctx->path, ctx->fill_rule == 0, ctm); + fz_freepath(ctx->path); + ctx->path = NULL; + } + else + { + printf("clip not a path! (maybe a glyph, or image?)\n"); + } } void xps_fill(xps_context_t *ctx, fz_matrix ctm) { -printf("xps_fill!\n"); - ctx->dev->fillpath(ctx->dev, ctx->path, ctx->fill_rule == 0, ctm, + ctx->dev->fillpath(ctx->dev->user, ctx->path, ctx->fill_rule == 0, ctm, ctx->colorspace, ctx->color, ctx->alpha); fz_freepath(ctx->path); ctx->path = NULL; @@ -58,7 +62,7 @@ printf("xps_fill!\n"); static void xps_stroke(xps_context_t *ctx, fz_matrix ctm, fz_strokestate *stroke) { - ctx->dev->strokepath(ctx->dev, ctx->path, stroke, ctm, + ctx->dev->strokepath(ctx->dev->user, ctx->path, stroke, ctm, ctx->colorspace, ctx->color, ctx->alpha); fz_freepath(ctx->path); ctx->path = NULL; @@ -67,7 +71,7 @@ xps_stroke(xps_context_t *ctx, fz_matrix ctm, fz_strokestate *stroke) static void xps_clipstroke(xps_context_t *ctx, fz_matrix ctm, fz_strokestate *stroke) { - ctx->dev->clipstrokepath(ctx->dev, ctx->path, stroke, ctm); + ctx->dev->clipstrokepath(ctx->dev->user, ctx->path, stroke, ctm); fz_freepath(ctx->path); ctx->path = NULL; } @@ -268,8 +272,6 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom) float smooth_x, smooth_y; /* saved cubic bezier control point for smooth curves */ int reset_smooth; -printf("xps_parse_abbreviated_geometry: %s\n", geom); - args = fz_calloc(strlen(geom) + 1, sizeof(char*)); pargs = args; @@ -747,6 +749,8 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro if (transform_tag) xps_parse_matrix_transform(ctx, transform_tag, &transform); // TODO: apply matrix + if (transform_att || transform_tag) + fz_warn("ignoring PathGeometry.Transform attribute"); if (figures_att) { @@ -783,11 +787,10 @@ xps_parse_line_cap(char *attr) * functions for drawing and/or clipping the child elements. */ -int +void xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { xps_item_t *node; - int code; char *fill_uri; char *stroke_uri; @@ -827,8 +830,6 @@ xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t ctx->fill_rule = 0; -printf("xps_parse_path\n"); - /* * Extract attributes and extended attributes. */ @@ -854,19 +855,14 @@ printf("xps_parse_path\n"); { if (!strcmp(xps_tag(node), "Path.RenderTransform")) transform_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Path.OpacityMask")) opacity_mask_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Path.Clip")) clip_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Path.Fill")) fill_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Path.Stroke")) stroke_tag = xps_down(node); - if (!strcmp(xps_tag(node), "Path.Data")) data_tag = xps_down(node); } @@ -956,16 +952,10 @@ printf("xps_parse_path\n"); xps_clip(ctx, ctm); } - code = xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); - if (code) - { -// fz_grestore(ctx->pgs); - return fz_rethrow(code, "cannot create transparency group"); - } + xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); if (fill_att) { -printf(" fill-att\n"); xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples); if (fill_opacity_att) samples[0] = atof(fill_opacity_att); @@ -982,25 +972,17 @@ printf(" fill-att\n"); if (fill_tag) { -printf(" fill-tag\n"); ctx->path = fz_newpath(); if (data_att) xps_parse_abbreviated_geometry(ctx, data_att); if (data_tag) xps_parse_path_geometry(ctx, dict, data_tag, 0); - code = xps_parse_brush(ctx, ctm, fill_uri, dict, fill_tag); - if (code < 0) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); -// fz_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse fill brush"); - } + xps_parse_brush(ctx, ctm, fill_uri, dict, fill_tag); } if (stroke_att) { -printf(" stroke_att\n"); xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples); if (stroke_opacity_att) samples[0] = atof(stroke_opacity_att); @@ -1017,7 +999,6 @@ printf(" stroke_att\n"); if (stroke_tag) { -printf(" stroke_tag\n"); ctx->path = fz_newpath(); if (data_att) xps_parse_abbreviated_geometry(ctx, data_att); @@ -1027,18 +1008,13 @@ printf(" stroke_tag\n"); ctx->fill_rule = 1; /* over-ride fill rule when converting outline to stroked */ xps_clipstroke(ctx, ctm, &stroke); - code = xps_parse_brush(ctx, ctm, stroke_uri, dict, stroke_tag); - if (code < 0) - { - xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); -// fz_grestore(ctx->pgs); - return fz_rethrow(code, "cannot parse stroke brush"); - } + xps_parse_brush(ctx, ctm, stroke_uri, dict, stroke_tag); - ctx->dev->popclip(ctx->dev); + ctx->dev->popclip(ctx->dev->user); } xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag); -// fz_grestore(ctx->pgs); - return 0; + + if (clip_att || clip_tag) + ctx->dev->popclip(ctx->dev->user); } diff --git a/xps/xpstile.c b/xps/xpstile.c index 4f2f57ec..2c91afa9 100644 --- a/xps/xpstile.c +++ b/xps/xpstile.c @@ -8,111 +8,67 @@ enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y }; -struct tile_closure_s +struct closure { - xps_context_t *ctx; char *base_uri; xps_resource_t *dict; - xps_item_t *tag; - fz_rect viewbox; - int tile_mode; + xps_item_t *root; void *user; - int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*); + void (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*); }; -static int -xps_paint_tiling_brush_clipped(struct tile_closure_s *c) +static void +xps_paint_tiling_brush_clipped(xps_context_t *ctx, fz_matrix ctm, fz_rect viewbox, struct closure *c) { - xps_context_t *ctx = c->ctx; - int code; + ctx->path = fz_newpath(); + fz_moveto(ctx->path, viewbox.x0, viewbox.y0); + fz_lineto(ctx->path, viewbox.x0, viewbox.y1); + fz_lineto(ctx->path, viewbox.x1, viewbox.y1); + fz_lineto(ctx->path, viewbox.x1, viewbox.y0); + fz_closepath(ctx->path); + xps_clip(ctx, ctm); -#if 0 - gs_moveto(ctx->pgs, c->viewbox.p.x, c->viewbox.p.y); - gs_lineto(ctx->pgs, c->viewbox.p.x, c->viewbox.q.y); - gs_lineto(ctx->pgs, c->viewbox.q.x, c->viewbox.q.y); - gs_lineto(ctx->pgs, c->viewbox.q.x, c->viewbox.p.y); - gs_closepath(ctx->pgs); - gs_clip(ctx->pgs); - gs_newpath(ctx->pgs); -#endif + c->func(ctx, ctm, c->base_uri, c->dict, c->root, c->user); - code = c->func(c->ctx, c->base_uri, c->dict, c->tag, c->user); - if (code < 0) - return fz_rethrow(code, "cannot draw clipped tile"); - - return 0; + ctx->dev->popclip(ctx->dev->user); } -#if 0 -static int -xps_paint_tiling_brush(const gs_client_color *pcc, gs_state *pgs) +static void +xps_paint_tiling_brush(xps_context_t *ctx, fz_matrix ctm, fz_rect viewbox, int tile_mode, struct closure *c) { - const gs_client_pattern *ppat = gs_getpattern(pcc); - struct tile_closure_s *c = ppat->client_data; - xps_context_t *ctx = c->ctx; - gs_state *saved_pgs; - int code; - - saved_pgs = ctx->pgs; - ctx->pgs = pgs; + fz_matrix ttm; - gs_gsave(ctx->pgs); - code = xps_paint_tiling_brush_clipped(c); - if (code) - goto cleanup; - gs_grestore(ctx->pgs); + xps_paint_tiling_brush_clipped(ctx, ctm, viewbox, c); - if (c->tile_mode == TILE_FLIP_X || c->tile_mode == TILE_FLIP_X_Y) + if (tile_mode == TILE_FLIP_X || tile_mode == TILE_FLIP_X_Y) { - gs_gsave(ctx->pgs); - gs_translate(ctx->pgs, c->viewbox.q.x * 2, 0.0); - gs_scale(ctx->pgs, -1.0, 1.0); - code = xps_paint_tiling_brush_clipped(c); - if (code) - goto cleanup; - gs_grestore(ctx->pgs); + ttm = fz_concat(ctm, fz_translate(viewbox.x1 * 2, 0)); + ttm = fz_concat(ttm, fz_scale(-1, 1)); + xps_paint_tiling_brush_clipped(ctx, ttm, viewbox, c); } - if (c->tile_mode == TILE_FLIP_Y || c->tile_mode == TILE_FLIP_X_Y) + if (tile_mode == TILE_FLIP_Y || tile_mode == TILE_FLIP_X_Y) { - gs_gsave(ctx->pgs); - gs_translate(ctx->pgs, 0.0, c->viewbox.q.y * 2); - gs_scale(ctx->pgs, 1.0, -1.0); - code = xps_paint_tiling_brush_clipped(c); - if (code) - goto cleanup; - gs_grestore(ctx->pgs); + ttm = fz_concat(ctm, fz_translate(0, viewbox.y1 * 2)); + ttm = fz_concat(ttm, fz_scale(1, -1)); + xps_paint_tiling_brush_clipped(ctx, ttm, viewbox, c); } - if (c->tile_mode == TILE_FLIP_X_Y) + if (tile_mode == TILE_FLIP_X_Y) { - gs_gsave(ctx->pgs); - gs_translate(ctx->pgs, c->viewbox.q.x * 2, c->viewbox.q.y * 2); - gs_scale(ctx->pgs, -1.0, -1.0); - code = xps_paint_tiling_brush_clipped(c); - if (code) - goto cleanup; - gs_grestore(ctx->pgs); + ttm = fz_concat(ctm, fz_translate(viewbox.x1 * 2, viewbox.y1 * 2)); + ttm = fz_concat(ttm, fz_scale(-1, -1)); + xps_paint_tiling_brush_clipped(ctx, ttm, viewbox, c); } - - ctx->pgs = saved_pgs; - - return 0; - -cleanup: - gs_grestore(ctx->pgs); - ctx->pgs = saved_pgs; - return fz_rethrow(code, "cannot draw tile"); } -#endif -int +void xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, - int (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user) + void (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user) { xps_item_t *node; - int code; + struct closure c; char *opacity_att; char *transform_att; @@ -138,6 +94,12 @@ xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, viewbox_units_att = xps_att(root, "ViewboxUnits"); viewport_units_att = xps_att(root, "ViewportUnits"); + c.base_uri = base_uri; + c.dict = dict; + c.root = root; + c.user = user; + c.func = func; + for (node = xps_down(root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "ImageBrush.Transform")) @@ -163,10 +125,10 @@ xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, xps_parse_rectangle(ctx, viewport_att, &viewport); /* some sanity checks on the viewport/viewbox size */ - if (fabs(viewport.x1 - viewport.x0) < 0.01) return 0; - if (fabs(viewport.y1 - viewport.y0) < 0.01) return 0; - if (fabs(viewbox.x1 - viewbox.x0) < 0.01) return 0; - if (fabs(viewbox.y1 - viewbox.y0) < 0.01) return 0; + if (fabs(viewport.x1 - viewport.x0) < 0.01) return; + if (fabs(viewport.y1 - viewport.y0) < 0.01) return; + if (fabs(viewbox.x1 - viewbox.x0) < 0.01) return; + if (fabs(viewbox.y1 - viewbox.y0) < 0.01) return; scalex = (viewport.x1 - viewport.x0) / (viewbox.x1 - viewbox.x0); scaley = (viewport.y1 - viewport.y0) / (viewbox.y1 - viewbox.y0); @@ -186,114 +148,27 @@ xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, tile_mode = TILE_FLIP_X_Y; } -// gs_gsave(ctx->pgs); + xps_clip(ctx, ctm); - code = xps_begin_opacity(ctx, ctm, base_uri, dict, opacity_att, NULL); - if (code) - { -// gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot create transparency group"); - } + xps_begin_opacity(ctx, ctm, base_uri, dict, opacity_att, NULL); - /* TODO(tor): check viewport and tiling to see if we can set it to TILE_NONE */ + ctm = fz_concat(ctm, transform); + ctm = fz_concat(ctm, fz_translate(viewport.x0, viewport.y0)); + ctm = fz_concat(ctm, fz_scale(scalex, scaley)); + ctm = fz_concat(ctm, fz_translate(-viewbox.x0, -viewbox.y0)); -#if 0 if (tile_mode != TILE_NONE) { - struct tile_closure_s closure; - - gs_client_pattern gspat; - gs_client_color gscolor; - fz_colorspace *cs; - - closure.ctx = ctx; - closure.base_uri = base_uri; - closure.dict = dict; - closure.tag = root; - closure.tile_mode = tile_mode; - closure.user = user; - closure.func = func; - - closure.viewbox.p.x = viewbox.p.x; - closure.viewbox.p.y = viewbox.p.y; - closure.viewbox.q.x = viewbox.q.x; - closure.viewbox.q.y = viewbox.q.y; - - gs_pattern1_init(&gspat); - uid_set_UniqueID(&gspat.uid, gs_next_ids(ctx->memory, 1)); - gspat.PaintType = 1; - gspat.TilingType = 1; - gspat.PaintProc = xps_remap_pattern; - gspat.client_data = &closure; - - gspat.XStep = viewbox.q.x - viewbox.p.x; - gspat.YStep = viewbox.q.y - viewbox.p.y; - gspat.BBox.p.x = viewbox.p.x; - gspat.BBox.p.y = viewbox.p.y; - gspat.BBox.q.x = viewbox.q.x; - gspat.BBox.q.y = viewbox.q.y; - - if (tile_mode == TILE_FLIP_X || tile_mode == TILE_FLIP_X_Y) - { - gspat.BBox.q.x += gspat.XStep; - gspat.XStep *= 2; - } - - if (tile_mode == TILE_FLIP_Y || tile_mode == TILE_FLIP_X_Y) - { - gspat.BBox.q.y += gspat.YStep; - gspat.YStep *= 2; - } - - fz_matrix_translate(&transform, viewport.p.x, viewport.p.y, &transform); - fz_matrix_scale(&transform, scalex, scaley, &transform); - fz_matrix_translate(&transform, -viewbox.p.x, -viewbox.p.y, &transform); - - cs = ctx->srgb; - gs_setcolorspace(ctx->pgs, cs); - gs_makepattern(&gscolor, &gspat, &transform, ctx->pgs, NULL); - gs_setpattern(ctx->pgs, &gscolor); - - xps_fill(ctx); - - /* gs_makepattern increments the pattern count stored in the color - * structure. We will discard the color struct (its on the stack) - * so we need to decrement the reference before we throw away - * the structure. - */ - gs_pattern_reference(&gscolor, -1); + /* TODO: loop in visible area */ + fz_warn("tiling brushes not implemented!"); + xps_paint_tiling_brush(ctx, ctm, viewbox, tile_mode, &c); } else { - xps_clip(ctx); - - gs_concat(ctx->pgs, &transform); - - gs_translate(ctx->pgs, viewport.p.x, viewport.p.y); - gs_scale(ctx->pgs, scalex, scaley); - gs_translate(ctx->pgs, -viewbox.p.x, -viewbox.p.y); - - gs_moveto(ctx->pgs, viewbox.p.x, viewbox.p.y); - gs_lineto(ctx->pgs, viewbox.p.x, viewbox.q.y); - gs_lineto(ctx->pgs, viewbox.q.x, viewbox.q.y); - gs_lineto(ctx->pgs, viewbox.q.x, viewbox.p.y); - gs_closepath(ctx->pgs); - gs_clip(ctx->pgs); - gs_newpath(ctx->pgs); - - code = func(ctx, base_uri, dict, root, user); - if (code < 0) - { - xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL); - gs_grestore(ctx->pgs); - return fz_rethrow(code, "cannot draw tile"); - } + xps_paint_tiling_brush(ctx, ctm, viewbox, tile_mode, &c); } -#endif xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL); -// gs_grestore(ctx->pgs); - - return 0; + ctx->dev->popclip(ctx->dev->user); } diff --git a/xps/xpstop.c b/xps/xpstop.c index afc64569..e1a2fe1e 100644 --- a/xps/xpstop.c +++ b/xps/xpstop.c @@ -82,25 +82,16 @@ static int isrange(char *s) return 1; } -static int +static void xps_run_page(xps_context_t *ctx, xps_page_t *page, fz_device *dev, fz_matrix ctm) { - int code; - ctx->dev = dev; - - code = xps_parse_fixed_page(ctx, ctm, page); - if (code) - return fz_rethrow(code, "cannot draw page part %s", page->name); - + xps_parse_fixed_page(ctx, ctm, page); ctx->dev = nil; - - return fz_okay; } static void drawpage(xps_context_t *ctx, int pagenum) { - fz_error error; xps_page_t *page; fz_displaylist *list; fz_device *dev; @@ -121,9 +112,7 @@ static void drawpage(xps_context_t *ctx, int pagenum) { list = fz_newdisplaylist(); dev = fz_newlistdevice(list); - error = xps_run_page(ctx, page, dev, fz_identity); - if (error) - die(fz_rethrow(error, "cannot draw page %d in file '%s'", pagenum, filename)); + xps_run_page(ctx, page, dev, fz_identity); fz_freedevice(dev); } @@ -174,7 +163,7 @@ static void drawpage(xps_context_t *ctx, int pagenum) zoom = resolution / 72; ctm = fz_translate(0, -page->height); - ctm = fz_concat(ctm, fz_scale(zoom, -zoom)); + ctm = fz_concat(ctm, fz_scale(zoom, zoom)); bbox = fz_roundrect(fz_transformrect(ctm, rect)); /* TODO: banded rendering and multi-page ppm */ diff --git a/xps/xpsvisual.c b/xps/xpsvisual.c index 0b6fb4da..d9aa5340 100644 --- a/xps/xpsvisual.c +++ b/xps/xpsvisual.c @@ -3,25 +3,17 @@ enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y }; -struct userdata -{ - xps_context_t *ctx; - xps_resource_t *dict; - xps_item_t *visual_tag; -}; - -static int +static void xps_paint_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *visual_tag) { - return xps_parse_element(ctx, ctm, base_uri, dict, (xps_item_t *)visual_tag); + xps_parse_element(ctx, ctm, base_uri, dict, (xps_item_t *)visual_tag); } -int +void xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root) { xps_item_t *node; - int code; char *visual_uri; char *visual_att; @@ -40,10 +32,6 @@ xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_re if (visual_tag) { - code = xps_parse_tiling_brush(ctx, ctm, visual_uri, dict, root, xps_paint_visual_brush, visual_tag); - if (code) - return fz_rethrow(code, "cannot parse tiling brush"); + xps_parse_tiling_brush(ctx, ctm, visual_uri, dict, root, xps_paint_visual_brush, visual_tag); } - - return 0; } diff --git a/xps/xpsxml.c b/xps/xpsxml.c index 2295e08c..94d1e351 100644 --- a/xps/xpsxml.c +++ b/xps/xpsxml.c @@ -44,7 +44,6 @@ static void on_open_tag(void *zp, char *ns_name, char **atts) { xps_parser_t *parser = zp; - xps_context_t *ctx = parser->ctx; xps_item_t *item; xps_item_t *tail; int namelen; @@ -93,7 +92,7 @@ on_open_tag(void *zp, char *ns_name, char **atts) textlen += strlen(atts[i]) + 1; } - item = xps_alloc(ctx, sizeof(xps_item_t) + attslen + namelen + textlen); + item = fz_malloc(sizeof(xps_item_t) + attslen + namelen + textlen); if (!item) { parser->error = "out of memory"; @@ -167,7 +166,6 @@ static void on_text(void *zp, char *buf, int len) { xps_parser_t *parser = zp; - xps_context_t *ctx = parser->ctx; char *atts[3]; int i; @@ -178,7 +176,7 @@ on_text(void *zp, char *buf, int len) { if (!is_xml_space(buf[i])) { - char *tmp = xps_alloc(ctx, len + 1); + char *tmp = fz_malloc(len + 1); if (!tmp) { parser->error = "out of memory"; @@ -193,7 +191,7 @@ on_text(void *zp, char *buf, int len) tmp[len] = 0; on_open_tag(zp, "", atts); on_close_tag(zp, ""); - xps_free(ctx, tmp); + fz_free(tmp); return; } } -- cgit v1.2.3