diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2011-06-24 18:46:51 +0100 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2011-06-24 18:58:31 +0100 |
commit | 7af1ebacdb9947ea5197523bcda7764431769e8f (patch) | |
tree | bb9a30611ce7fddf422edab4ef5fdde77fd0f51d | |
parent | 0c927bb3e177b5b34ebb1b1f7fa2d9669614fbaf (diff) | |
download | ghostpdl-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.c | 60 | ||||
-rw-r--r-- | gs/base/gdevrops.c | 25 | ||||
-rw-r--r-- | gs/base/gsropt.h | 9 |
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\ |