summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-07-27 16:25:19 +0100
committerChris Liddell <chris.liddell@artifex.com>2011-07-28 08:10:13 +0100
commit12faa934ff19d95f08fc9db33d7a6b288ba67ee2 (patch)
tree9730b87cd310d6a5a401d5093eee8990198f6e9c
parent3639f0da216f0472658b37ee96726b80abdc7d56 (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.c11
-rw-r--r--gs/base/gxclip.c66
-rw-r--r--gs/base/gxclip.h3
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. */