diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2011-07-27 16:25:19 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2011-07-28 08:10:13 +0100 |
commit | 12faa934ff19d95f08fc9db33d7a6b288ba67ee2 (patch) | |
tree | 9730b87cd310d6a5a401d5093eee8990198f6e9c | |
parent | 3639f0da216f0472658b37ee96726b80abdc7d56 (diff) |
Fix Bug 692368; SEGV with clist transparency pattern in clist rendering.
The invocation/file given in the bug uses banded rendering (clist).
While drawing a band, it uses a pattern with transparency, that is
itself rendered by a clist (using the new pattern clist code).
A fill rectangle is being done that tries to call the pattern clist
tiling code without the fill_trans_buffer having been setup, and
this causes a SEGV.
The reason for this appears to be that the device used by the
banded isn't a pdf14 device - instead it's a clipper device wrapping
the pdf14 device. The clipper device does not call gx_forward_fill_path,
but instead calls gx_default_fill_path, meaning that the special
pdf14 handling done to setup the fill_trans_buffer isn't done.
Making the commit call onwards to gx_forward_fill_path doesn't solve the
problem either, as that results in no actual clipping being done.
The fix, therefore appears to be to implement a clipping version of
fill_path.
No cluster differences expected.
-rw-r--r-- | gs/base/gdevp14.c | 11 | ||||
-rw-r--r-- | gs/base/gxclip.c | 66 | ||||
-rw-r--r-- | gs/base/gxclip.h | 3 |
3 files changed, 74 insertions, 6 deletions
diff --git a/gs/base/gdevp14.c b/gs/base/gdevp14.c index 672b1ece6..13ca28eb4 100644 --- a/gs/base/gdevp14.c +++ b/gs/base/gdevp14.c @@ -2249,11 +2249,12 @@ pdf14_fill_mask(gx_device * orig_dev, } if (has_pattern_trans) { code = dev_proc(dev, get_profile)(dev, &dev_profile); - code = pdf14_pop_transparency_group(NULL, p14dev->ctx, - p14dev->blend_procs, - p14dev->color_info.num_components, - dev_profile->device_profile[0], - orig_dev); + if (code >= 0) + code = pdf14_pop_transparency_group(NULL, p14dev->ctx, + p14dev->blend_procs, + p14dev->color_info.num_components, + dev_profile->device_profile[0], + orig_dev); gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer, "pdf14_fill_mask"); ptile->ttrans->fill_trans_buffer = NULL; /* Avoid GC issues */ diff --git a/gs/base/gxclip.c b/gs/base/gxclip.c index b032ee65b..7984e5659 100644 --- a/gs/base/gxclip.c +++ b/gs/base/gxclip.c @@ -18,6 +18,7 @@ #include "gxclip.h" #include "gxpath.h" #include "gxcpath.h" +#include "gzcpath.h" /* Define whether to look for vertical clipping regions. */ #define CHECK_VERTICAL_CLIPPING @@ -38,6 +39,7 @@ static dev_proc_strip_tile_rectangle(clip_strip_tile_rectangle); static dev_proc_strip_copy_rop(clip_strip_copy_rop); static dev_proc_get_clipping_box(clip_get_clipping_box); static dev_proc_get_bits_rectangle(clip_get_bits_rectangle); +static dev_proc_fill_path(clip_fill_path); /* The device descriptor. */ static const gx_device_clip gs_clip_device = @@ -67,7 +69,7 @@ static const gx_device_clip gs_clip_device = clip_copy_alpha, gx_forward_get_band, gx_default_copy_rop, - gx_default_fill_path, + clip_fill_path, gx_default_stroke_path, clip_fill_mask, gx_default_fill_trapezoid, @@ -657,3 +659,65 @@ clip_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, } return code; } + +static int +clip_call_fill_path(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) +{ + gx_device *tdev = pccd->tdev; + dev_proc_fill_path((*proc)); + int code; + gx_clip_path cpath_intersection; + gx_clip_path *pcpath = pccd->pcpath; + + if (pcpath != NULL) { + gx_path rect_path; + code = gx_cpath_init_local_shared(&cpath_intersection, pcpath, pccd->ppath->memory); + if (code < 0) + return code; + gx_path_init_local(&rect_path, pccd->ppath->memory); + gx_path_add_rectangle(&rect_path, int2fixed(xc), int2fixed(yc), int2fixed(xec), int2fixed(yec)); + code = gx_cpath_intersect(&cpath_intersection, &rect_path, + gx_rule_winding_number, pccd->pis); + gx_path_free(&rect_path, "clip_call_fill_path"); + } else { + gs_fixed_rect clip_box; + clip_box.p.x = int2fixed(xc); + clip_box.p.y = int2fixed(yc); + clip_box.q.x = int2fixed(xec); + clip_box.q.y = int2fixed(yec); + gx_cpath_init_local(&cpath_intersection, pccd->ppath->memory); + code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box); + } + if (code < 0) + return code; + proc = dev_proc(tdev, fill_path); + if (proc == NULL) + proc = gx_default_fill_path; + code = (*proc)(pccd->tdev, pccd->pis, pccd->ppath, pccd->params, + pccd->pdcolor, &cpath_intersection); + gx_cpath_free(&cpath_intersection, "clip_call_fill_path"); + return code; +} +static int +clip_fill_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_fill_params * params, + const gx_drawing_color * pdcolor, + const gx_clip_path * pcpath) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + clip_callback_data_t ccdata; + gs_fixed_rect box; + + ccdata.pis = pis; + ccdata.ppath = ppath; + ccdata.params = params; + ccdata.pdcolor = pdcolor; + ccdata.pcpath = pcpath; + clip_get_clipping_box(dev, &box); + return clip_enumerate(rdev, + fixed2int(box.p.x), + fixed2int(box.p.y), + fixed2int(box.q.x - box.p.x), + fixed2int(box.q.y - box.p.y), + clip_call_fill_path, &ccdata); +} diff --git a/gs/base/gxclip.h b/gs/base/gxclip.h index 24d665afe..5712471a9 100644 --- a/gs/base/gxclip.h +++ b/gs/base/gxclip.h @@ -46,6 +46,9 @@ typedef struct clip_callback_data_s { const gx_strip_bitmap *textures; /* ibid. */ const gx_color_index *tcolors; /* ibid. */ int plane; /* copy_plane */ + const gs_imager_state * pis; /* fill_path */ + gx_path * ppath; /* fill_path */ + const gx_fill_params * params; /* fill_path */ } clip_callback_data_t; /* Declare the callback procedures. */ |