summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-06-24 18:46:51 +0100
committerRobin Watts <Robin.Watts@artifex.com>2011-06-24 18:58:31 +0100
commit7af1ebacdb9947ea5197523bcda7764431769e8f (patch)
treebb9a30611ce7fddf422edab4ef5fdde77fd0f51d
parent0c927bb3e177b5b34ebb1b1f7fa2d9669614fbaf (diff)
downloadghostpdl-7af1ebacdb9947ea5197523bcda7764431769e8f.tar.gz
Add copy_plane to rop source device.
This uses 'creative engineering' (aka a blatant hack) to allow copy_color to be implemented in the "rop source" device. We implement a copy_plane entrypoint for the rop source device, that does exactly the same as copy_color, except that it abuses the lop value passed to the gx_device_color_fill_rectangle by setting a new bit (lop_planar) and pickling the plane number into the high bits. This is detected in mem_planar_strip_copy_rop and unpicked to a call to the appropriate plane. Care must be taken when doing rops on the planar device, as processing any rop on the device that involves 'D' calls get_bit_rectangle which can cause a call to convert from planar to chunky if mishandled. The solution is to ensure that we always remove our get_bits_rectangle implementation when passing on a ropping call.
-rw-r--r--gs/base/gdevmpla.c60
-rw-r--r--gs/base/gdevrops.c25
-rw-r--r--gs/base/gsropt.h9
3 files changed, 86 insertions, 8 deletions
diff --git a/gs/base/gdevmpla.c b/gs/base/gdevmpla.c
index b4adcc82b..6b379a576 100644
--- a/gs/base/gdevmpla.c
+++ b/gs/base/gdevmpla.c
@@ -30,6 +30,7 @@ static dev_proc_copy_color(mem_planar_copy_color_24to8);
static dev_proc_copy_color(mem_planar_copy_color_4to1);
static dev_proc_copy_plane(mem_planar_copy_plane);
static dev_proc_strip_tile_rectangle(mem_planar_strip_tile_rectangle);
+static dev_proc_strip_copy_rop(mem_planar_strip_copy_rop);
static dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle);
static int
@@ -93,6 +94,7 @@ gdev_mem_set_planar(gx_device_memory * mdev, int num_planes,
set_dev_proc(mdev, copy_color, dev_proc(mdproto, copy_color));
set_dev_proc(mdev, copy_alpha, dev_proc(mdproto, copy_alpha));
set_dev_proc(mdev, strip_tile_rectangle, dev_proc(mdproto, strip_tile_rectangle));
+ set_dev_proc(mdev, strip_copy_rop, dev_proc(mdproto, strip_copy_rop));
set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle));
} else {
set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle);
@@ -115,10 +117,10 @@ gdev_mem_set_planar(gx_device_memory * mdev, int num_planes,
set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha);
set_dev_proc(mdev, copy_plane, mem_planar_copy_plane);
set_dev_proc(mdev, strip_tile_rectangle, mem_planar_strip_tile_rectangle);
+ set_dev_proc(mdev, strip_copy_rop, mem_planar_strip_copy_rop);
set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle);
set_dev_proc(mdev, dev_spec_op, mem_planar_dev_spec_op);
}
- set_dev_proc(mdev, strip_copy_rop, dev_proc(mdproto, strip_copy_rop));
return 0;
}
@@ -583,6 +585,7 @@ mem_planar_copy_plane(gx_device * dev, const byte * base, int sourcex,
int plane_depth;
mem_save_params_t save;
const gx_device_memory *mdproto;
+ int code;
if ((plane < 0) || (plane >= mdev->num_planes))
return gs_error_rangecheck;
@@ -591,14 +594,15 @@ mem_planar_copy_plane(gx_device * dev, const byte * base, int sourcex,
plane_depth = mdev->planes[plane].depth;
mdproto = gdev_mem_device_for_bits(plane_depth);
if (plane_depth == 1)
- dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id,
- x, y, w, h,
- (gx_color_index)0, (gx_color_index)1);
+ code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id,
+ x, y, w, h,
+ (gx_color_index)0,
+ (gx_color_index)1);
else
- dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster,
- id, x, y, w, h);
+ code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster,
+ id, x, y, w, h);
MEM_RESTORE_PARAMS(mdev, save);
- return 0;
+ return code;
}
static int
@@ -648,6 +652,48 @@ mem_planar_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
return 0;
}
+static int
+mem_planar_strip_copy_rop(gx_device * dev,
+ const byte * sdata, int sourcex, uint sraster,
+ gx_bitmap_id id, const gx_color_index * scolors,
+ const gx_strip_bitmap * textures,
+ const gx_color_index * tcolors,
+ int x, int y, int width, int height,
+ int phase_x, int phase_y,
+ gs_logical_operation_t lop)
+{
+ gx_device_memory * const mdev = (gx_device_memory *)dev;
+ mem_save_params_t save;
+ int plane, code;
+ const gx_device_memory *mdproto;
+
+ if ((lop & lop_planar) == 0) {
+ mdproto = gdev_mem_device_for_bits(mdev->color_info.depth);
+ return dev_proc(mdproto, strip_copy_rop)(dev, sdata, sourcex, sraster,
+ id, scolors, textures, tcolors,
+ x, y, width, height,
+ phase_x, phase_y, lop);
+ }
+ /* Extract the plane, and sanitise the lop */
+ plane = lop>>lop_planar_shift;
+ lop &= ~((plane<<lop_planar_shift) | lop_planar);
+ if ((plane < 0) || (plane >= mdev->num_planes))
+ return gs_error_rangecheck;
+ MEM_SAVE_PARAMS(mdev, save);
+ mdev->line_ptrs += mdev->height * plane;
+ mdproto = gdev_mem_device_for_bits(mdev->planes[plane].depth);
+ /* strip_copy_rop might end up calling get_bits_rectangle, so ensure we
+ * have the right one in there. */
+ set_dev_proc(mdev, get_bits_rectangle, dev_proc(mdproto, get_bits_rectangle));
+ code = dev_proc(mdproto, strip_copy_rop)(dev, sdata, sourcex, sraster,
+ id, scolors, textures, tcolors,
+ x, y, width, height,
+ phase_x, phase_y, lop);
+ set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle);
+ MEM_RESTORE_PARAMS(mdev, save);
+ return code;
+}
+
/*
* Repack planar into chunky format. This is an internal procedure that
* implements the straightforward chunky case of get_bits_rectangle, and
diff --git a/gs/base/gdevrops.c b/gs/base/gdevrops.c
index b58885d56..01934d3f2 100644
--- a/gs/base/gdevrops.c
+++ b/gs/base/gdevrops.c
@@ -41,6 +41,7 @@ static RELOC_PTRS_BEGIN(device_rop_texture_reloc_ptrs) {
static dev_proc_fill_rectangle(rop_texture_fill_rectangle);
static dev_proc_copy_mono(rop_texture_copy_mono);
static dev_proc_copy_color(rop_texture_copy_color);
+static dev_proc_copy_plane(rop_texture_copy_plane);
/* The device descriptor. */
static const gx_device_rop_texture gs_rop_texture_device = {
@@ -112,7 +113,7 @@ static const gx_device_rop_texture gs_rop_texture_device = {
NULL, /* pop_transparency_state */
NULL, /* put_image */
gx_forward_dev_spec_op,
- NULL, /* copy plane */
+ rop_texture_copy_plane, /* copy plane */
gx_forward_get_profile
},
0, /* target */
@@ -213,3 +214,25 @@ rop_texture_copy_color(gx_device * dev,
x, y, w, h, rtdev->target,
rtdev->log_op, &source);
}
+
+/* Copy a color rectangle */
+static int
+rop_texture_copy_plane(gx_device * dev,
+ const byte * data, int sourcex, int raster, gx_bitmap_id id,
+ int x, int y, int w, int h, int plane)
+{
+ gx_device_rop_texture *const rtdev = (gx_device_rop_texture *)dev;
+ gx_rop_source_t source;
+
+ source.sdata = data;
+ source.sourcex = sourcex;
+ source.sraster = raster;
+ source.id = id;
+ source.scolors[0] = source.scolors[1] = gx_no_color_index;
+ source.use_scolors = false;
+ return gx_device_color_fill_rectangle(&rtdev->texture,
+ x, y, w, h, rtdev->target,
+ (rtdev->log_op | lop_planar |
+ (plane<<lop_planar_shift)),
+ &source);
+}
diff --git a/gs/base/gsropt.h b/gs/base/gsropt.h
index c9c217892..095b51ab8 100644
--- a/gs/base/gsropt.h
+++ b/gs/base/gsropt.h
@@ -209,6 +209,15 @@ typedef enum {
#define lop_S_transparent 0x100
#define lop_T_transparent 0x200
#define lop_pdf14 0x400
+
+/* Also, we abuse the lop even further, by allowing it to specify a specific
+ * plane for an operation to work on (in a planar device context). To specify
+ * a particularp plane, set lop_planar, and then or in the plane number
+ * shifted up by lop_planar_shift.
+ */
+#define lop_planar 0x800
+#define lop_planar_shift 12
+
typedef uint gs_logical_operation_t;
#define lop_default\