diff options
author | Robin Watts <robin.watts@artifex.com> | 2011-11-14 12:19:32 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2011-11-14 18:12:20 +0000 |
commit | 96ab69c8bcc1bcf3e366b494ed099dc5b46009fe (patch) | |
tree | 4aa5b3a2f2655f896c7a3aefd1272fc6f5ae7d77 /gs/base/gdevdrop.c | |
parent | 940b007282d74686a20aa5cf434d20353680344c (diff) |
Planar rop fixes; extensive changes throughout code.
The changes here are largely forced upon us by the rop source device,
the internal mechanism used within the gs lib to cope with performing
rop operations with drawing operations. The rop source device is
created and is given a 'source'. Any operations then done to that device
are then passed on to its target device rewritten into a form that will
cause the output to be ropped with the source.
This causes problems when the source is in planar format (such as when
the source is a pattern tile intended for use on a planar device). There
is no way to call strip_copy_rop with planar data currently, neither
can it easily be shoehorned through. We therefore add a new
'strip_copy_rop2' entrypoint that takes an additional 'planar_height'
parameter that gives the number of lines of data before the next
planes data starts.
We add implementations of this call throughout the code; some are
very simple (bbox, null, trace, clip, clip2, clip2, tile_clip etc).
Others 'common up' with the strip_copy_rop (gx_default,
mem_planar).
The underlying memory devices should never be called with strip_copy_rop2
as the planar data will always be rewritten to chunky format before
this happens. We are free to change this approach later if we want.
The gx_rop_source_t structure used by the rop source device is extended
to have a new planar_height field, and the rop source device itself
extended to pass this on. Various places that create this structure now
initialise that correctly.
The clist reader/writer is updated to send the extra planar_height
field through and call strip_cop_rop or strip_copy_rop2 as appropriate.
In a similar vein, we are forced to change the copy_plane entry point
to be copy_planes (as it is impossible (or very hard at least) for the
rop source device to implement copy_plane).
This incorporates changes from Michael to the new "fast threshold" image
halftoning code to make it use the new copy_planes operation.
Diffstat (limited to 'gs/base/gdevdrop.c')
-rw-r--r-- | gs/base/gdevdrop.c | 110 |
1 files changed, 94 insertions, 16 deletions
diff --git a/gs/base/gdevdrop.c b/gs/base/gdevdrop.c index ce782759c..05ff0d43f 100644 --- a/gs/base/gdevdrop.c +++ b/gs/base/gdevdrop.c @@ -24,6 +24,7 @@ #include "gxdevrop.h" #include "gxgetbit.h" #include "gdevmem.h" /* for mem_default_strip_copy_rop prototype */ +#include "gdevmpla.h" #include "gdevmrop.h" #include "gxdevsop.h" @@ -98,6 +99,24 @@ gx_default_strip_copy_rop(gx_device * dev, int phase_x, int phase_y, gs_logical_operation_t lop) { + return gx_default_strip_copy_rop2(dev, sdata, sourcex, sraster, id, + scolors, textures, tcolors, + x, y, width, height, + phase_x, phase_y, lop, 0); +} + +int +gx_default_strip_copy_rop2(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, + uint planar_height) +{ int depth = dev->color_info.depth; gs_memory_t *mem = dev->memory; const gx_device_memory *mdproto = gdev_mem_device_for_bits(depth); @@ -109,6 +128,7 @@ gx_default_strip_copy_rop(gx_device * dev, int block_height; int code; int py; + int is_planar = 0; #ifdef DEBUG if (gs_debug_c('b')) @@ -129,11 +149,33 @@ gx_default_strip_copy_rop(gx_device * dev, if (max_height == 0) max_height = 1; block_height = min(height, max_height); + if (planar_height > 0) + block_height = planar_height; gs_make_mem_device_with_copydevice(&pmdev, mdproto, mem, -1, dev); pmdev->width = width; pmdev->height = block_height; pmdev->bitmap_memory = mem; pmdev->color_info = dev->color_info; + if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0)) + { + gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS]; + int num_comp = dev->color_info.num_components; + int depth = dev->color_info.depth/num_comp; + int i; + for (i = 0; i < num_comp; i++) + { + planes[i].shift = depth * (num_comp - 1 - i); + planes[i].depth = depth; + planes[i].index = i; + } + /* RJW: This code, like most of ghostscripts planar support, + * will only work if every plane has the same depth. */ + draster = bitmap_raster(width * planes[0].depth); + code = gdev_mem_set_planar(pmdev, num_comp, planes); + if (code < 0) + return code; + is_planar = 1; + } code = (*dev_proc(pmdev, open_device))((gx_device *)pmdev); pmdev->is_open = true; /* not sure why we need this, but we do. */ if (code < 0) @@ -172,16 +214,36 @@ gx_default_strip_copy_rop(gx_device * dev, if (code < 0) return code; } - code = (*dev_proc(pmdev, strip_copy_rop)) - ((gx_device *)pmdev, - sdata + (py - y) * sraster, sourcex, sraster, - gx_no_bitmap_id, scolors, textures, tcolors, - 0, 0, width, block_height, phase_x + x, phase_y + py, lop); + if (planar_height == 0) { + code = (*dev_proc(pmdev, strip_copy_rop)) + ((gx_device *)pmdev, + sdata + (py - y) * sraster, sourcex, sraster, + gx_no_bitmap_id, scolors, textures, tcolors, + 0, 0, width, block_height, + phase_x + x, phase_y + py, + lop); + } else { + code = (*dev_proc(pmdev, strip_copy_rop2)) + ((gx_device *)pmdev, + sdata + (py - y) * sraster, sourcex, sraster, + gx_no_bitmap_id, scolors, textures, tcolors, + 0, 0, width, block_height, + phase_x + x, phase_y + py, + lop, planar_height); + } if (code < 0) break; - code = (*dev_proc(dev, copy_color)) - (dev, scan_line_base(pmdev, 0), 0, draster, gx_no_bitmap_id, - x, py, width, block_height); + if (is_planar) { + code = (*dev_proc(dev, copy_planes)) + (dev, scan_line_base(pmdev, 0), 0, + draster, gx_no_bitmap_id, + x, py, width, block_height, block_height); + } else { + code = (*dev_proc(dev, copy_color)) + (dev, scan_line_base(pmdev, 0), 0, + draster, gx_no_bitmap_id, + x, py, width, block_height); + } if (code < 0) break; } @@ -527,15 +589,31 @@ pack_planar_from_standard(gx_device_memory * dev, int y, int destx, * representation, and copy_color to write the pixels back. */ int +mem_default_strip_copy_rop2(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, + uint planar_height) +{ + dlprintf("mem_default_strip_copy_rop2 should never be called!\n"); + return gs_error_Fatal; +} + +int mem_default_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) + 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) { int depth = dev->color_info.depth; int rop_depth = (gx_device_has_color(dev) ? 24 : 8); |