[gs-cvs] rev 7853 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Mon Apr 16 04:02:20 PDT 2007
Author: leonardo
Date: 2007-04-16 04:02:19 -0700 (Mon, 16 Apr 2007)
New Revision: 7853
Modified:
trunk/gs/src/gxcldev.h
trunk/gs/src/gxclist.c
trunk/gs/src/gxclist.h
trunk/gs/src/gxclmem.c
trunk/gs/src/gxclmem.h
trunk/gs/src/gxclread.c
trunk/gs/src/gxp1fill.c
trunk/gs/src/gxpcmap.c
trunk/gs/src/gxpcolor.h
trunk/gs/src/lib.mak
trunk/gs/src/zpcolor.c
Log:
Implementing high level patterns, step 4.
DETAILS :
This is a preparation for fixing the bug 688396, step 4.
This change is algorithmically equivalent :
the new behavior is temporarily disabled with
MAX_BITMAP_PATTERN_SIZE macro.
The patch implements patterns with clist.
The choice between the old and the new implementation
is being controlled with MAX_BITMAP_PATTERN_SIZE macro.
When the pattern tile size is bigger, it writes the pattern
command stream into a clist object, which then
is stored into the pattern cache.
The pattern instantiation is done with the clist playback.
This code needs improvements :
1. It does not perform the tiling. Just renders a single instance of the pattern cell.
2. The memory cleanup is not done when the pattern cache entry purges.
3. Uncolored patterns work as colored.
4. Need to optimize with releaseing the clist buffer when
the pattern clist writer completes.
5. Get rid of non_gc_memory in the pattern clist writer.
We commit this patch now because we need to merge
data structures with the "band_complexity_array patch" (see rev 7847).
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxcldev.h 2007-04-16 11:02:19 UTC (rev 7853)
@@ -736,4 +736,9 @@
stream *s, gx_device *target,
int x0, int y0, gs_memory_t *mem);
+/* Playback the band file, taking the indicated action w/ its contents. */
+int clist_playback_file_bands(clist_playback_action action,
+ gx_device_clist_reader *crdev,
+ gx_band_page_info_t *page_info, gx_device *target,
+ int band_first, int band_last, int x0, int y0);
#endif /* gxcldev_INCLUDED */
Modified: trunk/gs/src/gxclist.c
===================================================================
--- trunk/gs/src/gxclist.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxclist.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -42,9 +42,10 @@
cdev->writer.clip_path : 0));
case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
cdev->writer.color_space.space : 0));
+ case 2: return ENUM_OBJ(cdev->writer.pinst);
default:
return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
- sizeof(gs_imager_state), index - 2);
+ sizeof(gs_imager_state), index - 3);
}
}
else {
@@ -66,9 +67,10 @@
RELOC_PREFIX(st_device_forward);
if (CLIST_IS_WRITER(cdev)) {
if (cdev->writer.image_enum_id != gs_no_id) {
- RELOC_VAR(cdev->writer.clip_path);
- RELOC_VAR(cdev->writer.color_space.space);
+ RELOC_VAR(cdev->writer.clip_path);
+ RELOC_VAR(cdev->writer.color_space.space);
}
+ RELOC_VAR(cdev->writer.pinst);
RELOC_USING(st_imager_state, &cdev->writer.imager_state,
sizeof(gs_imager_state));
}
@@ -169,11 +171,9 @@
clist_init_io_procs(gx_device_clist *pclist_dev, bool in_memory)
{
if (in_memory || clist_io_procs_file_global == NULL)
- pclist_dev->common.page_info.io_procs = pclist_dev->reader.page_info.io_procs =
- pclist_dev->writer.page_info.io_procs = clist_io_procs_memory_global;
+ pclist_dev->common.page_info.io_procs = clist_io_procs_memory_global;
else
- pclist_dev->common.page_info.io_procs = pclist_dev->reader.page_info.io_procs =
- pclist_dev->writer.page_info.io_procs = clist_io_procs_file_global;
+ pclist_dev->common.page_info.io_procs = clist_io_procs_file_global;
}
/* ------ Define the command set and syntax ------ */
@@ -272,7 +272,14 @@
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
int nbands;
+ extern dev_proc_open_device(pattern_clist_open_device);
+ if (dev->procs.open_device == pattern_clist_open_device) {
+ /* We don't need bands really. */
+ cdev->page_band_height = dev->height;
+ cdev->nbands = 1;
+ return 0;
+ }
if (gdev_mem_data_size(bdev, band_width, band_height) > data_size)
return_error(gs_error_rangecheck);
cdev->page_band_height = band_height;
@@ -615,9 +622,14 @@
{
gx_device_clist_writer * const cdev =
&((gx_device_clist *)dev)->writer;
+ extern dev_proc_open_device(pattern_clist_open_device);
if (cdev->do_not_open_or_close_bandfiles)
return 0;
+ if (cdev->procs.open_device == pattern_clist_open_device) {
+ gs_free_object(cdev->bandlist_memory, cdev->data, "clist_close");
+ cdev->data = NULL;
+ }
return clist_close_output_file(dev);
}
Modified: trunk/gs/src/gxclist.h
===================================================================
--- trunk/gs/src/gxclist.h 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxclist.h 2007-04-16 11:02:19 UTC (rev 7853)
@@ -56,6 +56,11 @@
* questions is negative, we flush the buffer.
*/
+#ifndef gs_pattern1_instance_t_DEFINED
+# define gs_pattern1_instance_t_DEFINED
+typedef struct gs_pattern1_instance_s gs_pattern1_instance_t;
+#endif
+
/* ---------------- Public structures ---------------- */
/*
@@ -242,6 +247,7 @@
/* Following must be set before writing */
proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if nz, proc to free some bandlist memory */
int disable_mask; /* mask of routines to disable clist_disable_xxx */
+ gs_pattern1_instance_t *pinst; /* Used when it is a pattern clist. */
} gx_device_clist_writer;
/* Bits for gx_device_clist_writer.disable_mask. Bit set disables behavior */
@@ -264,13 +270,16 @@
gx_band_complexity_t *band_complexity_array; /* num_bands elements */
} gx_device_clist_reader;
-typedef union gx_device_clist_s {
+union gx_device_clist_s {
gx_device_clist_common common;
gx_device_clist_reader reader;
gx_device_clist_writer writer;
-} gx_device_clist;
+};
-#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
+#ifndef gx_device_clist_DEFINED
+#define gx_device_clist_DEFINED
+typedef union gx_device_clist_s gx_device_clist;
+#endif
extern_st(st_device_clist);
#define public_st_device_clist() /* in gxclist.c */\
@@ -278,8 +287,10 @@
"gx_device_clist", 0, device_clist_enum_ptrs, device_clist_reloc_ptrs,\
gx_device_finalize)
#define st_device_clist_max_ptrs\
- (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
+ (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 3)
+#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
+
/* setup before opening clist device */
#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable, pageusestransparency)\
BEGIN\
@@ -293,6 +304,7 @@
(xclist)->writer.free_up_bandlist_memory = (xfree_bandlist);\
(xclist)->writer.disable_mask = (xdisable);\
(xclist)->writer.page_uses_transparency = (pageusestransparency);\
+ (xclist)->writer.pinst = NULL;\
END
/* Determine whether this clist device is able to recover VMerrors */
@@ -358,8 +370,7 @@
clist_get_band_complexity(gx_device *dev, int y);
/* Free any band_complexity_array memory used by the clist reader device */
-void
-gx_clist_reader_free_band_complexity_array(gx_device_clist *cldev);
+void gx_clist_reader_free_band_complexity_array(gx_device_clist *cldev);
/* deep copy constructor if from != NULL
* default constructor if from == NULL
Modified: trunk/gs/src/gxclmem.c
===================================================================
--- trunk/gs/src/gxclmem.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxclmem.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -1142,6 +1142,6 @@
int
gs_gxclmem_init(gs_memory_t *mem)
{
- clist_io_procs_file_global = &clist_io_procs_memory;
+ clist_io_procs_memory_global = &clist_io_procs_memory;
return 0;
}
Modified: trunk/gs/src/gxclmem.h
===================================================================
--- trunk/gs/src/gxclmem.h 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxclmem.h 2007-04-16 11:02:19 UTC (rev 7853)
@@ -61,7 +61,7 @@
RAW_BUFFER *raw_block; /* or NULL */
} LOG_MEMFILE_BLK;
-typedef struct MEMFILE {
+struct MEMFILE_s {
gs_memory_t *memory; /* storage allocator */
gs_memory_t *data_memory; /* storage allocator for data */
bool ok_to_compress; /* if true, OK to compress this file */
@@ -102,7 +102,11 @@
bool compressor_initialized;
stream_state *compress_state;
stream_state *decompress_state;
-} MEMFILE;
+};
+#ifndef MEMFILE_DEFINED
+#define MEMFILE_DEFINED
+typedef struct MEMFILE_s MEMFILE;
+#endif
/*
* Only the MEMFILE and stream_state structures are GC-compatible, so we
Modified: trunk/gs/src/gxclread.c
===================================================================
--- trunk/gs/src/gxclread.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxclread.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -143,12 +143,6 @@
/* Forward references */
private int clist_render_init(gx_device_clist *);
-private int clist_playback_file_bands(clist_playback_action action,
- gx_device_clist_reader *crdev,
- gx_band_page_info_t *page_info,
- gx_device *target,
- int band_first, int band_last,
- int x0, int y0);
private int clist_rasterize_lines(gx_device *dev, int y, int lineCount,
gx_device *bdev,
const gx_render_plane_t *render_plane,
@@ -485,7 +479,7 @@
}
/* Playback the band file, taking the indicated action w/ its contents. */
-private int
+int
clist_playback_file_bands(clist_playback_action action,
gx_device_clist_reader *crdev,
gx_band_page_info_t *page_info, gx_device *target,
Modified: trunk/gs/src/gxp1fill.c
===================================================================
--- trunk/gs/src/gxp1fill.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxp1fill.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -26,6 +26,7 @@
#include "gxclip2.h"
#include "gxpcolor.h"
#include "gxp1impl.h"
+#include "gxcldev.h"
/* Define the state for tile filling. */
typedef struct tile_fill_state_s {
@@ -235,6 +236,16 @@
}
return code;
}
+
+private int
+clist_fopen_dummy(char fname[gp_file_name_sizeof], const char *fmode,
+ clist_file_ptr * pcf,
+ gs_memory_t * mem, gs_memory_t *data_mem,
+ bool ok_to_compress)
+{
+ return 0;
+}
+
int
gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y,
int w, int h, gx_device * dev,
@@ -252,6 +263,24 @@
return 0;
if (rop_source == NULL)
set_rop_no_source(rop_source, no_source, dev);
+ if (ptile->cdev != NULL) {
+ gs_memory_t *mem = dev->memory;
+ gx_device_clist *cdev = ptile->cdev;
+ gx_device_clist_reader *crdev = (gx_device_clist_reader *)cdev;
+ int x0 = 0, y0 = 0;
+ gx_device_buf_procs_t buf_procs = {0};
+
+ crdev->yplane.depth = 0; /* Don't know what to set here. */
+ crdev->yplane.shift = 0;
+ crdev->yplane.index = -1;
+ crdev->pages = NULL;
+ crdev->num_pages = 1;
+ crdev->page_info.io_procs->rewind(crdev->page_info.bfile, false, NULL);
+ crdev->page_info.io_procs->rewind(crdev->page_info.cfile, false, NULL);
+ code = clist_playback_file_bands(playback_action_render,
+ crdev, &crdev->page_info, dev, 0, 0, x0, y0);
+ return code;
+ }
bits = &ptile->tbits;
code = tile_fill_init(&state, pdevc, dev, false);
if (code < 0)
Modified: trunk/gs/src/gxpcmap.c
===================================================================
--- trunk/gs/src/gxpcmap.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxpcmap.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -28,6 +28,7 @@
#include "gxdevmem.h"
#include "gxpcolor.h"
#include "gxp1impl.h"
+#include "gxclist.h"
#include "gzstate.h"
/* Define the default size of the Pattern cache. */
@@ -137,25 +138,153 @@
0, 0, 0, 0 /* bitmap_memory, bits, mask, instance */
};
+
+private int
+dummy_free_up_bandlist_memory(gx_device *cldev, bool b)
+{
+ return 0;
+}
+
+int
+pattern_clist_open_device(gx_device *dev)
+{
+ /* This function is defiled only for clist_init_bands. */
+ return gs_clist_device_procs.open_device(dev);
+}
+
+private dev_proc_create_buf_device(dummy_create_buf_device)
+{
+ gx_device_memory *mdev = (gx_device_memory *)*pbdev;
+
+ gs_make_mem_device(mdev, gdev_mem_device_for_bits(target->color_info.depth),
+ mem, 0, target);
+ return 0;
+}
+private dev_proc_size_buf_device(dummy_size_buf_device)
+{
+ return 0;
+}
+private dev_proc_setup_buf_device(dummy_setup_buf_device)
+{
+ return 0;
+}
+private dev_proc_destroy_buf_device(dummy_destroy_buf_device)
+{
+}
+
+#define MAX_BITMAP_PATTERN_SIZE max_long
+
/* Allocate a pattern accumulator, with an initial refct of 0. */
-gx_device_pattern_accum *
-gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * stoarge_memory,
+gx_device_forward *
+gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * storage_memory,
gs_pattern1_instance_t *pinst, client_name_t cname)
{
- gx_device_pattern_accum *adev =
- gs_alloc_struct(mem, gx_device_pattern_accum,
+ gx_device *tdev = pinst->saved->device;
+ int depth = (pinst->template.PaintType == 1 ? 1 : tdev->color_info.depth);
+ int raster = (pinst->size.x * depth + 7) / 8;
+ int64_t size = (int64_t)raster * pinst->size.y;
+ gx_device_forward *fdev;
+
+ if (size < MAX_BITMAP_PATTERN_SIZE) {
+ gx_device_pattern_accum *adev = gs_alloc_struct(mem, gx_device_pattern_accum,
&st_device_pattern_accum, cname);
- if (adev == 0)
- return 0;
- gx_device_init((gx_device *)adev,
- (const gx_device *)&gs_pattern_accum_device,
- mem, true);
- check_device_separable((gx_device *)adev);
- gx_device_forward_fill_in_procs((gx_device_forward *)adev);
- adev->instance = pinst;
- adev->bitmap_memory = stoarge_memory;
- return adev;
+ if (adev == 0)
+ return 0;
+ gx_device_init((gx_device *)adev,
+ (const gx_device *)&gs_pattern_accum_device,
+ mem, true);
+ adev->instance = pinst;
+ adev->bitmap_memory = storage_memory;
+ fdev = (gx_device_forward *)adev;
+ } else {
+ int code;
+ int save_height = tdev->height;
+ gx_device_buf_procs_t buf_procs = {dummy_create_buf_device,
+ dummy_size_buf_device, dummy_setup_buf_device, dummy_destroy_buf_device};
+ gx_device_clist *cdev = gs_alloc_struct(mem, gx_device_clist,
+ &st_device_clist, cname);
+ gx_device_clist_writer *cwdev = (gx_device_clist_writer *)cdev;
+ const int data_size = 1024*32;
+ byte *data;
+
+ if (cdev == 0)
+ return 0;
+ /* We're not shure how big area do we need here.
+ Definitely we need 1 state in 'states'.
+ Not sure whether we need to create tile_cache, etc..
+ Note it is allocated in non-gc memory,
+ because the garbager descriptor for
+ gx_device_clist do not enumerate 'data'
+ and its subfields, assuming they do not relocate.
+ We place command list files to non-gc memory
+ due to same reason.
+ */
+ data = gs_alloc_bytes(storage_memory->non_gc_memory, data_size, cname);
+ if (data == NULL) {
+ gs_free_object(mem, cdev, cname);
+ return 0;
+ }
+ memset(cdev, 0, sizeof(*cdev));
+ cwdev->params_size = sizeof(gx_device_clist);
+ cwdev->static_procs = NULL;
+ cwdev->dname = "pattern-clist";
+ cwdev->memory = mem;
+ cwdev->stype = &st_device_clist;
+ cwdev->stype_is_dynamic = false;
+ cwdev->finalize = NULL;
+ rc_init(cwdev, mem, 1);
+ cwdev->retained = true;
+ cwdev->is_open = false;
+ cwdev->max_fill_band = 0;
+ cwdev->color_info = tdev->color_info;
+ cwdev->cached_colors = tdev->cached_colors;
+ cwdev->width = pinst->size.x;
+ cwdev->height = pinst->size.y;
+ cwdev->LeadingEdge = tdev->LeadingEdge;
+ /* Fields left zeroed :
+ float MediaSize[2];
+ float ImagingBBox[4];
+ bool ImagingBBox_set;
+ */
+ cwdev->HWResolution[0] = tdev->HWResolution[0];
+ cwdev->HWResolution[1] = tdev->HWResolution[1];
+ /* Fields left zeroed :
+ float MarginsHWResolution[2];
+ float Margins[2];
+ float HWMargins[4];
+ long PageCount;
+ long ShowpageCount;
+ int NumCopies;
+ bool NumCopies_set;
+ bool IgnoreNumCopies;
+ */
+ cwdev->UseCIEColor = tdev->UseCIEColor;
+ cwdev->LockSafetyParams = true;
+ /* gx_page_device_procs page_procs; */
+ cwdev->procs = gs_clist_device_procs;
+ cwdev->procs.open_device = pattern_clist_open_device;
+ gx_device_copy_color_params((gx_device *)cwdev, tdev);
+ cwdev->target = tdev;
+ clist_init_io_procs(cdev, true);
+ cwdev->data = data;
+ cwdev->data_size = data_size;
+ cwdev->buf_procs = buf_procs ;
+ cwdev->band_params.page_uses_transparency = false;
+ cwdev->band_params.BandWidth = pinst->size.x;
+ cwdev->band_params.BandHeight = pinst->size.x;
+ cwdev->band_params.BandBufferSpace = max_long;
+ cwdev->do_not_open_or_close_bandfiles = false;
+ cwdev->bandlist_memory = storage_memory->non_gc_memory;
+ cwdev->free_up_bandlist_memory = dummy_free_up_bandlist_memory;
+ cwdev->disable_mask = 0;
+ cwdev->page_uses_transparency = false;
+ cwdev->pinst = pinst;
+ fdev = (gx_device_forward *)cdev;
+ }
+ check_device_separable((gx_device *)fdev);
+ gx_device_forward_fill_in_procs(fdev);
+ return fdev;
}
/*
@@ -408,6 +537,7 @@
tiles->tbits.data = 0;
tiles->tmask.data = 0;
tiles->index = i;
+ tiles->cdev = NULL;
}
return pcache;
}
@@ -485,46 +615,66 @@
private void make_bitmap(gx_strip_bitmap *, const gx_device_memory *, gx_bitmap_id);
int
gx_pattern_cache_add_entry(gs_imager_state * pis,
- gx_device_pattern_accum * padev, gx_color_tile ** pctile)
+ gx_device_forward * fdev, gx_color_tile ** pctile)
{
- gx_device_memory *mbits = padev->bits;
- gx_device_memory *mmask = padev->mask;
- const gs_pattern1_instance_t *pinst = padev->instance;
gx_pattern_cache *pcache;
+ const gs_pattern1_instance_t *pinst;
ulong used = 0;
- gx_bitmap_id id = pinst->id;
+ gx_bitmap_id id;
gx_color_tile *ctile;
int code = ensure_pattern_cache(pis);
+ extern dev_proc_open_device(pattern_clist_open_device);
if (code < 0)
return code;
pcache = pis->pattern_cache;
- /*
- * Check whether the pattern completely fills its box.
- * If so, we can avoid the expensive masking operations
- * when using the pattern.
- */
- if (mmask != 0) {
- int y;
+ if (fdev->procs.open_device != pattern_clist_open_device) {
+ gx_device_pattern_accum *padev = (gx_device_pattern_accum *)fdev;
+ gx_device_memory *mbits = padev->bits;
+ gx_device_memory *mmask = padev->mask;
- for (y = 0; y < mmask->height; y++) {
- const byte *row = scan_line_base(mmask, y);
- int w;
+ pinst = padev->instance;
+ /*
+ * Check whether the pattern completely fills its box.
+ * If so, we can avoid the expensive masking operations
+ * when using the pattern.
+ */
+ if (mmask != 0) {
+ int y;
- for (w = mmask->width; w > 8; w -= 8)
- if (*row++ != 0xff)
+ for (y = 0; y < mmask->height; y++) {
+ const byte *row = scan_line_base(mmask, y);
+ int w;
+
+ for (w = mmask->width; w > 8; w -= 8)
+ if (*row++ != 0xff)
+ goto keep;
+ if ((*row | (0xff >> w)) != 0xff)
goto keep;
- if ((*row | (0xff >> w)) != 0xff)
- goto keep;
+ }
+ /* We don't need a mask. */
+ mmask = 0;
+ keep:;
}
- /* We don't need a mask. */
- mmask = 0;
- keep:;
+ if (mbits != 0)
+ used += gdev_mem_bitmap_size(mbits);
+ if (mmask != 0)
+ used += gdev_mem_bitmap_size(mmask);
+ } else {
+ gx_device_clist *cdev = (gx_device_clist *)fdev;
+ gx_device_clist_writer * cldev = (gx_device_clist_writer *)cdev;
+
+ code = clist_end_page(cldev);
+ if (code < 0)
+ return code;
+ pinst = cdev->writer.pinst;
+ /* HACK: we would like to copy the pattern clist stream into the
+ tile cache memory and properly account its size,
+ but we have no time for this development now.
+ Therefore the stream is stored outside the cache. */
+ used = 0;
}
- if (mbits != 0)
- used += gdev_mem_bitmap_size(mbits);
- if (mmask != 0)
- used += gdev_mem_bitmap_size(mmask);
+ id = pinst->id;
ctile = &pcache->tiles[id % pcache->num_tiles];
gx_pattern_cache_free_entry(pcache, ctile);
while (pcache->bits_used + used > pcache->max_bits &&
@@ -534,24 +684,44 @@
gx_pattern_cache_free_entry(pcache, &pcache->tiles[pcache->next]);
}
ctile->id = id;
- ctile->depth = padev->color_info.depth;
+ ctile->depth = fdev->color_info.depth;
ctile->uid = pinst->template.uid;
ctile->tiling_type = pinst->template.TilingType;
ctile->step_matrix = pinst->step_matrix;
ctile->bbox = pinst->bbox;
ctile->is_simple = pinst->is_simple;
ctile->is_dummy = false;
- if (mbits != 0) {
- make_bitmap(&ctile->tbits, mbits, gs_next_ids(pis->memory, 1));
- mbits->bitmap_memory = 0; /* don't free the bits */
- } else
+ if (fdev->procs.open_device != pattern_clist_open_device) {
+ gx_device_pattern_accum *padev = (gx_device_pattern_accum *)fdev;
+ gx_device_memory *mbits = padev->bits;
+ gx_device_memory *mmask = padev->mask;
+
+ if (mbits != 0) {
+ make_bitmap(&ctile->tbits, mbits, gs_next_ids(pis->memory, 1));
+ mbits->bitmap_memory = 0; /* don't free the bits */
+ } else
+ ctile->tbits.data = 0;
+ if (mmask != 0) {
+ make_bitmap(&ctile->tmask, mmask, id);
+ mmask->bitmap_memory = 0; /* don't free the bits */
+ } else
+ ctile->tmask.data = 0;
+ ctile->cdev = NULL;
+ pcache->bits_used += used;
+ } else {
+ gx_device_clist *cdev = (gx_device_clist *)fdev;
+ gx_device_clist_writer *cwdev = (gx_device_clist_writer *)fdev;
+
ctile->tbits.data = 0;
- if (mmask != 0) {
- make_bitmap(&ctile->tmask, mmask, id);
- mmask->bitmap_memory = 0; /* don't free the bits */
- } else
+ ctile->tbits.size.x = 0;
+ ctile->tbits.size.y = 0;
ctile->tmask.data = 0;
- pcache->bits_used += used;
+ ctile->tmask.size.x = 0;
+ ctile->tmask.size.y = 0;
+ ctile->cdev = cdev;
+ /* Prevent freeing files on pattern_paint_cleanup : */
+ cwdev->do_not_open_or_close_bandfiles = true;
+ }
pcache->tiles_used++;
*pctile = ctile;
return 0;
@@ -585,6 +755,7 @@
ctile->tbits.size = pinst->size;
ctile->tbits.id = gs_no_bitmap_id;
memset(&ctile->tmask, 0 , sizeof(ctile->tmask));
+ ctile->cdev = NULL;
pcache->tiles_used++;
return 0;
}
@@ -623,7 +794,7 @@
gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis,
gx_device * dev, gs_color_select_t select)
{
- gx_device_pattern_accum *adev;
+ gx_device_forward *adev;
gs_pattern1_instance_t *pinst =
(gs_pattern1_instance_t *)pdc->ccolor.pattern;
gs_state *saved;
@@ -641,7 +812,7 @@
* Note that adev is an internal device, so it will be freed when the
* last reference to it from a graphics state is deleted.
*/
- adev = gx_pattern_accum_alloc(mem, mem, pinst, "gx_pattern_load");
+ adev = gx_pattern_accum_alloc(mem, pis->pattern_cache->memory, pinst, "gx_pattern_load");
if (adev == 0)
return_error(gs_error_VMerror);
gx_device_set_target((gx_device_forward *)adev, dev);
@@ -664,7 +835,8 @@
return code;
}
/* We REALLY don't like the following cast.... */
- code = gx_pattern_cache_add_entry((gs_imager_state *)pis, adev, &ctile);
+ code = gx_pattern_cache_add_entry((gs_imager_state *)pis,
+ adev, &ctile);
if (code >= 0) {
if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
lprintf("Pattern cache lookup failed after insertion!\n");
@@ -672,14 +844,16 @@
}
}
#ifdef DEBUG
- if (gs_debug_c('B')) {
- if (adev->mask)
- debug_dump_bitmap(adev->mask->base, adev->mask->raster,
- adev->mask->height, "[B]Pattern mask");
- if (adev->bits)
- debug_dump_bitmap(((gx_device_memory *) adev->target)->base,
- ((gx_device_memory *) adev->target)->raster,
- adev->target->height, "[B]Pattern bits");
+ if (gs_debug_c('B') && adev->procs.open_device == pattern_accum_open) {
+ gx_device_pattern_accum *pdev = (gx_device_pattern_accum *)adev;
+
+ if (pdev->mask)
+ debug_dump_bitmap(pdev->mask->base, pdev->mask->raster,
+ pdev->mask->height, "[B]Pattern mask");
+ if (pdev->bits)
+ debug_dump_bitmap(((gx_device_memory *) pdev->target)->base,
+ ((gx_device_memory *) pdev->target)->raster,
+ pdev->target->height, "[B]Pattern bits");
}
#endif
/* Free the bookkeeping structures, except for the bits and mask */
@@ -689,6 +863,12 @@
gs_state_free_chain(saved);
return code;
fail:
+ if (adev->procs.open_device == pattern_clist_open_device) {
+ gx_device_clist *pdev = (gx_device_clist *)adev;
+
+ gs_free_object(mem, pdev->common.data, "gx_pattern_load");
+ pdev->common.data = 0;
+ }
gs_free_object(mem, adev, "gx_pattern_load");
return code;
}
Modified: trunk/gs/src/gxpcolor.h
===================================================================
--- trunk/gs/src/gxpcolor.h 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/gxpcolor.h 2007-04-16 11:02:19 UTC (rev 7853)
@@ -24,6 +24,11 @@
#include "gxdevmem.h"
#include "gxpcache.h"
+#ifndef gx_device_clist_DEFINED
+#define gx_device_clist_DEFINED
+typedef union gx_device_clist_s gx_device_clist;
+#endif
+
/*
* Define the type of a Pattern, also used with Pattern instances.
*/
@@ -162,17 +167,19 @@
gx_strip_bitmap tbits; /* data = 0 if uncolored */
gx_strip_bitmap tmask; /* data = 0 if no mask */
/* (i.e., the mask is all 1's) */
- bool is_simple; /* true if xstep/ystep = tile size */
- bool is_dummy; /* if true, the device manages the pattern,
+ gx_device_clist *cdev; /* not NULL if the graphics is a command list. */
+ byte is_simple; /* true if xstep/ystep = tile size */
+ byte is_dummy; /* if true, the device manages the pattern,
and the content of the tile is empty. */
+ byte pad[2]; /* structure members alignment. */
/* The following is neither key nor value. */
uint index; /* the index of the tile within */
/* the cache (for GC) */
};
#define private_st_color_tile() /* in gxpcmap.c */\
- gs_private_st_ptrs2(st_color_tile, gx_color_tile, "gx_color_tile",\
- color_tile_enum_ptrs, color_tile_reloc_ptrs, tbits.data, tmask.data)
+ gs_private_st_ptrs3(st_color_tile, gx_color_tile, "gx_color_tile",\
+ color_tile_enum_ptrs, color_tile_reloc_ptrs, tbits.data, tmask.data, cdev)
#define private_st_color_tile_element() /* in gxpcmap.c */\
gs_private_st_element(st_color_tile_element, gx_color_tile,\
"gx_color_tile[]", color_tile_elt_enum_ptrs, color_tile_elt_reloc_ptrs,\
@@ -215,7 +222,7 @@
instance, bits, mask)
/* Allocate a pattern accumulator. */
-gx_device_pattern_accum * gx_pattern_accum_alloc(gs_memory_t * mem,
+gx_device_forward * gx_pattern_accum_alloc(gs_memory_t * mem,
gs_memory_t * stoarge_memory,
gs_pattern1_instance_t *pinst, client_name_t cname);
@@ -223,7 +230,7 @@
/* Note that this does not free any of the data in the accumulator */
/* device, but it may zero out the bitmap_memory pointers to prevent */
/* the accumulated bitmaps from being freed when the device is closed. */
-int gx_pattern_cache_add_entry(gs_imager_state *, gx_device_pattern_accum *,
+int gx_pattern_cache_add_entry(gs_imager_state *, gx_device_forward *,
gx_color_tile **);
/* Add a dummy Pattern cache entry. Stubs a pattern tile for interpreter when
device handles high level patterns. */
Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/lib.mak 2007-04-16 11:02:19 UTC (rev 7853)
@@ -2064,13 +2064,13 @@
$(GLOBJ)gxp1fill.$(OBJ) : $(GLSRC)gxp1fill.c $(GXERR) $(math__h)\
$(gsrop_h) $(gsmatrix_h)\
$(gxcolor2_h) $(gxclip2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevcli_h)\
- $(gxdevmem_h) $(gxp1impl_h) $(gxpcolor_h)
+ $(gxdevmem_h) $(gxpcolor_h) $(gxp1impl_h) $(gxcldev_h)
$(GLCC) $(GLO_)gxp1fill.$(OBJ) $(C_) $(GLSRC)gxp1fill.c
$(GLOBJ)gxpcmap.$(OBJ) : $(GLSRC)gxpcmap.c $(GXERR) $(math__h) $(memory__h)\
$(gsstruct_h) $(gsutil_h)\
$(gxcolor2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h)\
- $(gxfixed_h) $(gxmatrix_h) $(gxpcolor_h)\
+ $(gxfixed_h) $(gxmatrix_h) $(gxpcolor_h) $(gxclist_h)\
$(gzstate_h)
$(GLCC) $(GLO_)gxpcmap.$(OBJ) $(C_) $(GLSRC)gxpcmap.c
Modified: trunk/gs/src/zpcolor.c
===================================================================
--- trunk/gs/src/zpcolor.c 2007-04-16 02:50:57 UTC (rev 7852)
+++ trunk/gs/src/zpcolor.c 2007-04-16 11:02:19 UTC (rev 7853)
@@ -235,7 +235,7 @@
gs_pattern1_instance_t *pinst =
(gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
ref *pdict = &((int_pattern *) pinst->template.client_data)->dict;
- gx_device_pattern_accum *pdev = NULL;
+ gx_device_forward *pdev = NULL;
gx_device *cdev = gs_currentdevice_inline(igs);
int code;
ref *ppp;
@@ -316,7 +316,7 @@
pattern_paint_finish(i_ctx_t *i_ctx_p)
{
int o_stack_adjust = ref_stack_count(&o_stack) - esp->value.intval;
- gx_device_pattern_accum *pdev = r_ptr(esp - 1, gx_device_pattern_accum);
+ gx_device_forward *pdev = r_ptr(esp - 1, gx_device_forward);
if (pdev != NULL) {
gx_color_tile *ctile;
More information about the gs-cvs
mailing list