A preliminary patch for high level patterns

"Igor V. Melichev" <[email protected]> Sat, 14 Apr 2007 02:20:11 +0400
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
This is a multi-part message in MIME format.

------=_NextPart_000_002D_01C77E3B.6DBC5DA0
Content-Type: text/plain; format=flowed; charset="koi8-r"; reply-type=original
Content-Transfer-Encoding: 7bit

This is a preparation for fixing the bug 688396, step 4.
This patch is not ready for commitment.
I publicize it just to account useful ideas from reviewers.

The patch implements patterns with clist.
The choice between the old and the new implementation
is being controlled with MAX_BITMAP_PATTERN_SIZE macro.
It's value is chosen temporary for debug purpose only.
When the 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 is not complete :
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.

However it paints something with a simple test (attached).
I'd like to get ideas from reviewers at this state.
Particularly I don't like 2 things :
1. my clist device initialization code;
2. what happens with non_gc_memory .
Thanks.

Igor.

------=_NextPart_000_002D_01C77E3B.6DBC5DA0
Content-Type: text/plain; format=flowed; name="patch1.txt"; reply-type=original
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="patch1.txt"

*** F:\SVN-GS\HEAD\gs\src\gxcldev.h	Fri Apr  6 09:52:30 2007
--- files\gs\src\gxcldev.h	Sat Apr 14 00:37:24 2007
***************
*** 737,739 ****
--- 737,747 ----
  			int x0, int y0, gs_memory_t *mem);
 =20
+ /* 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);
+=20
  #endif /* gxcldev_INCLUDED */
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxclist.c	Tue Apr 10 10:54:58 2007
--- files\gs\src\gxclist.c	Sat Apr 14 00:24:50 2007
***************
*** 45,51 ****
      case 1: return ENUM_OBJ((cdev->writer.image_enum_id !=3D gs_no_id =
?
  			     cdev->writer.color_space.space : 0));
      default:
  	return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
! 			  sizeof(gs_imager_state), index - 2);
      }
  ENUM_PTRS_END
--- 45,52 ----
      case 1: return ENUM_OBJ((cdev->writer.image_enum_id !=3D 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 - 3);
      }
  ENUM_PTRS_END
***************
*** 60,63 ****
--- 61,65 ----
  	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));
***************
*** 153,161 ****
  {  =20
      if (in_memory || clist_io_procs_file_global =3D=3D NULL)
! 	pclist_dev->common.page_info.io_procs =3D =
pclist_dev->reader.page_info.io_procs =3D=20
! 		pclist_dev->writer.page_info.io_procs =3D =
clist_io_procs_memory_global;
      else
! 	pclist_dev->common.page_info.io_procs =3D =
pclist_dev->reader.page_info.io_procs =3D=20
! 		pclist_dev->writer.page_info.io_procs =3D =
clist_io_procs_file_global;
  }
 =20
--- 155,161 ----
  {  =20
      if (in_memory || clist_io_procs_file_global =3D=3D NULL)
! 	pclist_dev->common.page_info.io_procs =3D =
clist_io_procs_memory_global;
      else
! 	pclist_dev->common.page_info.io_procs =3D clist_io_procs_file_global;
  }
 =20
***************
*** 256,260 ****
--- 256,267 ----
  	&((gx_device_clist *)dev)->writer;
      int nbands;
+     extern dev_proc_open_device(pattern_clist_open_device);
 =20
+     if (dev->procs.open_device =3D=3D pattern_clist_open_device) {
+ 	/* We don't need bands really. */
+ 	cdev->page_band_height =3D dev->height;
+ 	cdev->nbands =3D 1;
+ 	return 0;
+     }
      if (gdev_mem_data_size(bdev, band_width, band_height) > data_size)
  	return_error(gs_error_rangecheck);
***************
*** 599,605 ****
--- 606,617 ----
      gx_device_clist_writer * const cdev =3D
  	&((gx_device_clist *)dev)->writer;
+     extern dev_proc_open_device(pattern_clist_open_device);
 =20
      if (cdev->do_not_open_or_close_bandfiles)
  	return 0;
+     if (cdev->procs.open_device =3D=3D pattern_clist_open_device) {
+ 	gs_free_object(cdev->bandlist_memory, cdev->data, "clist_close");
+ 	cdev->data =3D NULL;
+     }
      return clist_close_output_file(dev);
  }
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxclist.h	Mon Apr  9 12:55:03 2007
--- files\gs\src\gxclist.h	Sat Apr 14 00:37:24 2007
***************
*** 57,60 ****
--- 57,65 ----
   */
 =20
+ #ifndef gs_pattern1_instance_t_DEFINED
+ #  define gs_pattern1_instance_t_DEFINED
+ typedef struct gs_pattern1_instance_s gs_pattern1_instance_t;
+ #endif
+=20
  /* ---------------- Public structures ---------------- */
 =20
***************
*** 243,246 ****
--- 248,252 ----
  	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;
 =20
***************
*** 265,273 ****
  } gx_device_clist_reader;
 =20
! typedef union gx_device_clist_s {
      gx_device_clist_common common;
      gx_device_clist_reader reader;
      gx_device_clist_writer writer;
! } gx_device_clist;
 =20
  extern_st(st_device_clist);
--- 271,284 ----
  } gx_device_clist_reader;
 =20
! union gx_device_clist_s {
      gx_device_clist_common common;
      gx_device_clist_reader reader;
      gx_device_clist_writer writer;
! };
!=20
! #ifndef gx_device_clist_DEFINED
! #define gx_device_clist_DEFINED
! typedef union gx_device_clist_s gx_device_clist;
! #endif
 =20
  extern_st(st_device_clist);
***************
*** 277,281 ****
      gx_device_finalize)
  #define st_device_clist_max_ptrs\
!   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
 =20
  /* setup before opening clist device */
--- 288,292 ----
      gx_device_finalize)
  #define st_device_clist_max_ptrs\
!   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 3)
 =20
  /* setup before opening clist device */
***************
*** 292,295 ****
--- 303,307 ----
  	(xclist)->writer.disable_mask =3D (xdisable);\
  	(xclist)->writer.page_uses_transparency =3D (pageusestransparency);\
+ 	(xclist)->writer.pinst =3D NULL;\
      END
 =20
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxclmem.c	Tue Apr 10 10:54:58 2007
--- files\gs\src\gxclmem.c	Wed Apr 11 22:13:39 2007
***************
*** 1143,1147 ****
  gs_gxclmem_init(gs_memory_t *mem)
  {
!     clist_io_procs_file_global =3D &clist_io_procs_memory;
      return 0;
  }
--- 1143,1147 ----
  gs_gxclmem_init(gs_memory_t *mem)
  {
!     clist_io_procs_memory_global =3D &clist_io_procs_memory;
      return 0;
  }
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxclmem.h	Mon Apr  9 12:55:03 2007
--- files\gs\src\gxclmem.h	Thu Apr 12 10:22:48 2007
***************
*** 62,66 ****
  } LOG_MEMFILE_BLK;
 =20
! typedef struct MEMFILE {
      gs_memory_t *memory;	/* storage allocator */
      gs_memory_t *data_memory;	/* storage allocator for data */
--- 62,66 ----
  } LOG_MEMFILE_BLK;
 =20
! struct MEMFILE_s {
      gs_memory_t *memory;	/* storage allocator */
      gs_memory_t *data_memory;	/* storage allocator for data */
***************
*** 103,107 ****
      stream_state *compress_state;
      stream_state *decompress_state;
! } MEMFILE;
 =20
  /*
--- 103,111 ----
      stream_state *compress_state;
      stream_state *decompress_state;
! };
! #ifndef MEMFILE_DEFINED
! #define MEMFILE_DEFINED
! typedef struct MEMFILE_s MEMFILE;
! #endif
 =20
  /*
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxclread.c	Tue Apr 10 10:54:58 2007
--- files\gs\src\gxclread.c	Fri Apr 13 23:14:57 2007
***************
*** 143,152 ****
 =20
  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,
--- 143,146 ----
***************
*** 484,488 ****
 =20
  /* Playback the band file, taking the indicated action w/ its =
contents. */
! private int
  clist_playback_file_bands(clist_playback_action action,=20
  			  gx_device_clist_reader *crdev,
--- 478,482 ----
 =20
  /* Playback the band file, taking the indicated action w/ its =
contents. */
! int
  clist_playback_file_bands(clist_playback_action action,=20
  			  gx_device_clist_reader *crdev,
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxp1fill.c	Wed Mar 15 15:05:08 2006
--- files\gs\src\gxp1fill.c	Sat Apr 14 01:00:09 2007
***************
*** 27,30 ****
--- 27,31 ----
  #include "gxpcolor.h"
  #include "gxp1impl.h"
+ #include "gxcldev.h"
 =20
  /* Define the state for tile filling. */
***************
*** 236,239 ****
--- 237,250 ----
      return code;
  }
+=20
+ private int=20
+ 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;
+ }
+=20
  int
  gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int =
y,
***************
*** 253,256 ****
--- 264,285 ----
      if (rop_source =3D=3D NULL)
  	set_rop_no_source(rop_source, no_source, dev);
+     if (ptile->cdev !=3D NULL) {
+ 	gs_memory_t *mem =3D dev->memory;
+ 	gx_device_clist *cdev =3D ptile->cdev;
+ 	gx_device_clist_reader *crdev =3D (gx_device_clist_reader *)cdev;
+ 	int x0 =3D 0, y0 =3D 0;
+ 	gx_device_buf_procs_t buf_procs =3D {0};
+=20
+ 	crdev->yplane.depth =3D 0; /* Don't know what to set here. */
+ 	crdev->yplane.shift =3D 0;
+ 	crdev->yplane.index =3D -1;
+ 	crdev->pages =3D NULL;
+ 	crdev->num_pages =3D 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 =3D clist_playback_file_bands(playback_action_render,
+ 		    crdev, &crdev->page_info, dev, 0, 0, x0, y0);
+ 	return code;
+    }
      bits =3D &ptile->tbits;
      code =3D tile_fill_init(&state, pdevc, dev, false);
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxpcmap.c	Tue Apr 10 21:14:03 2007
--- files\gs\src\gxpcmap.c	Sat Apr 14 02:00:18 2007
***************
*** 29,32 ****
--- 29,33 ----
  #include "gxpcolor.h"
  #include "gxp1impl.h"
+ #include "gxclist.h"
  #include "gzstate.h"
 =20
***************
*** 138,148 ****
  };
 =20
  /* 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,=20
  		       gs_pattern1_instance_t *pinst, client_name_t cname)
  {
!     gx_device_pattern_accum *adev =3D
! 	gs_alloc_struct(mem, gx_device_pattern_accum,
  			&st_device_pattern_accum, cname);
 =20
--- 139,191 ----
  };
 =20
+=20
+ private int=20
+ dummy_free_up_bandlist_memory(gx_device *cldev, bool b)
+ {
+     return 0;
+ }
+=20
+ int=20
+ pattern_clist_open_device(gx_device *dev)
+ {
+     /* This function is defiled only for clist_init_bands. */
+     return gs_clist_device_procs.open_device(dev);
+ }
+=20
+ private dev_proc_create_buf_device(dummy_create_buf_device)
+ {
+     gx_device_memory *mdev =3D (gx_device_memory *)*pbdev;
+=20
+     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)
+ {
+ }
+=20
+ #define MAX_BITMAP_PATTERN_SIZE 10000
+=20
  /* Allocate a pattern accumulator, with an initial refct of 0. */
! gx_device_forward *
! gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * =
storage_memory,=20
  		       gs_pattern1_instance_t *pinst, client_name_t cname)
  {
!     gx_device *tdev =3D pinst->saved->device;
!     int depth =3D (pinst->template.PaintType =3D=3D 1 ? 1 : =
tdev->color_info.depth);
!     int raster =3D (pinst->size.x * depth + 7) / 8;
!     int64_t size =3D (int64_t)raster * pinst->size.y;
!     gx_device_forward *fdev;
!=20
!     if (size < MAX_BITMAP_PATTERN_SIZE) {
! 	gx_device_pattern_accum *adev =3D gs_alloc_struct(mem, =
gx_device_pattern_accum,
  			&st_device_pattern_accum, cname);
 =20
***************
*** 152,160 ****
  		   (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 =3D pinst;
!     adev->bitmap_memory =3D stoarge_memory;
!     return adev;
  }
 =20
--- 195,289 ----
  		       (const gx_device *)&gs_pattern_accum_device,
  		       mem, true);
  	adev->instance =3D pinst;
! 	adev->bitmap_memory =3D storage_memory;
! 	fdev =3D (gx_device_forward *)adev;
!     } else {
! 	int code;
! 	int save_height =3D tdev->height;
! 	gx_device_buf_procs_t buf_procs =3D {dummy_create_buf_device,
! 	dummy_size_buf_device, dummy_setup_buf_device, =
dummy_destroy_buf_device};
! 	gx_device_clist *cdev =3D gs_alloc_struct(mem, gx_device_clist,
! 			&st_device_clist, cname);
! 	gx_device_clist_writer *cwdev =3D (gx_device_clist_writer *)cdev;
! 	const int data_size =3D 1024*32;
! 	byte *data;
!=20
! 	if (cdev =3D=3D 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 =3D gs_alloc_bytes(storage_memory->non_gc_memory, data_size, =
cname);
! 	if (data =3D=3D NULL) {
! 	    gs_free_object(mem, cdev, cname);
! 	    return 0;
! 	}
! 	memset(cdev, 0, sizeof(*cdev));
! 	cwdev->params_size =3D sizeof(gx_device_clist);
! 	cwdev->static_procs =3D NULL;
! 	cwdev->dname =3D "pattern-clist";
! 	cwdev->memory =3D mem;
! 	cwdev->stype =3D &st_device_clist;
! 	cwdev->stype_is_dynamic =3D false;
! 	cwdev->finalize =3D NULL;
! 	rc_init(cwdev, mem, 1);
! 	cwdev->retained =3D true;
! 	cwdev->is_open =3D false;
! 	cwdev->max_fill_band =3D 0;
! 	cwdev->color_info =3D tdev->color_info;
! 	cwdev->cached_colors =3D tdev->cached_colors;
! 	cwdev->width =3D pinst->size.x;
! 	cwdev->height =3D pinst->size.y;
!         cwdev->LeadingEdge =3D tdev->LeadingEdge;
! 	/* Fields left zeroed :
! 	float MediaSize[2];
! 	float ImagingBBox[4];
! 	bool ImagingBBox_set;
! 	*/
! 	cwdev->HWResolution[0] =3D tdev->HWResolution[0];
! 	cwdev->HWResolution[1] =3D 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 =3D tdev->UseCIEColor;
! 	cwdev->LockSafetyParams =3D true;
! 	/* gx_page_device_procs page_procs; */
! 	cwdev->procs =3D gs_clist_device_procs;
! 	cwdev->procs.open_device =3D pattern_clist_open_device;
! 	gx_device_copy_color_params((gx_device *)cwdev, tdev);
! 	cwdev->target =3D tdev;
! 	clist_init_io_procs(cdev, true);
! 	cwdev->data =3D data;
! 	cwdev->data_size =3D data_size;
! 	cwdev->buf_procs =3D buf_procs ;
! 	cwdev->band_params.page_uses_transparency =3D false;
! 	cwdev->band_params.BandWidth =3D pinst->size.x;
! 	cwdev->band_params.BandHeight =3D pinst->size.x;
! 	cwdev->band_params.BandBufferSpace =3D max_long;
! 	cwdev->do_not_open_or_close_bandfiles =3D false;
! 	cwdev->bandlist_memory =3D storage_memory->non_gc_memory;
! 	cwdev->free_up_bandlist_memory =3D dummy_free_up_bandlist_memory;
! 	cwdev->disable_mask =3D 0;
! 	cwdev->page_uses_transparency =3D false;
! 	cwdev->pinst =3D pinst;
! 	fdev =3D (gx_device_forward *)cdev;
!     }
!     check_device_separable((gx_device *)fdev);
!     gx_device_forward_fill_in_procs(fdev);
!     return fdev;
  }
 =20
***************
*** 409,412 ****
--- 538,542 ----
  	tiles->tmask.data =3D 0;
  	tiles->index =3D i;
+ 	tiles->cdev =3D NULL;
      }
      return pcache;
***************
*** 486,503 ****
  int
  gx_pattern_cache_add_entry(gs_imager_state * pis,
! 		   gx_device_pattern_accum * padev, gx_color_tile ** pctile)
  {
-     gx_device_memory *mbits =3D padev->bits;
-     gx_device_memory *mmask =3D padev->mask;
-     const gs_pattern1_instance_t *pinst =3D padev->instance;
      gx_pattern_cache *pcache;
      ulong used =3D 0;
!     gx_bitmap_id id =3D pinst->id;
      gx_color_tile *ctile;
      int code =3D ensure_pattern_cache(pis);
 =20
      if (code < 0)
  	return code;
      pcache =3D pis->pattern_cache;
      /*
       * Check whether the pattern completely fills its box.
--- 616,638 ----
  int
  gx_pattern_cache_add_entry(gs_imager_state * pis,
! 		   gx_device_forward * fdev, gx_color_tile ** pctile)
  {
      gx_pattern_cache *pcache;
+     const gs_pattern1_instance_t *pinst;
      ulong used =3D 0;
!     gx_bitmap_id id;
      gx_color_tile *ctile;
      int code =3D ensure_pattern_cache(pis);
+     extern dev_proc_open_device(pattern_clist_open_device);
 =20
      if (code < 0)
  	return code;
      pcache =3D pis->pattern_cache;
+     if (fdev->procs.open_device !=3D pattern_clist_open_device) {
+ 	gx_device_pattern_accum *padev =3D (gx_device_pattern_accum *)fdev;
+ 	gx_device_memory *mbits =3D padev->bits;
+ 	gx_device_memory *mmask =3D padev->mask;
+=20
+ 	pinst =3D padev->instance;
  	/*
  	 * Check whether the pattern completely fills its box.
***************
*** 526,529 ****
--- 661,679 ----
  	if (mmask !=3D 0)
  	    used +=3D gdev_mem_bitmap_size(mmask);
+     } else {
+ 	gx_device_clist *cdev =3D (gx_device_clist *)fdev;
+ 	gx_device_clist_writer * cldev =3D (gx_device_clist_writer *)cdev;
+=20
+ 	code =3D clist_end_page(cldev);
+ 	if (code < 0)
+ 	    return code;
+ 	pinst =3D cdev->writer.pinst;
+ 	/* HACK: we would like to copy the pattern clist stream into the=20
+ 	   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 =3D 0;
+     }
+     id =3D pinst->id;
      ctile =3D &pcache->tiles[id % pcache->num_tiles];
      gx_pattern_cache_free_entry(pcache, ctile);
***************
*** 535,539 ****
      }
      ctile->id =3D id;
!     ctile->depth =3D padev->color_info.depth;
      ctile->uid =3D pinst->template.uid;
      ctile->tiling_type =3D pinst->template.TilingType;
--- 685,689 ----
      }
      ctile->id =3D id;
!     ctile->depth =3D fdev->color_info.depth;
      ctile->uid =3D pinst->template.uid;
      ctile->tiling_type =3D pinst->template.TilingType;
***************
*** 542,545 ****
--- 692,700 ----
      ctile->is_simple =3D pinst->is_simple;
      ctile->is_dummy =3D false;
+     if (fdev->procs.open_device !=3D pattern_clist_open_device) {
+ 	gx_device_pattern_accum *padev =3D (gx_device_pattern_accum *)fdev;
+ 	gx_device_memory *mbits =3D padev->bits;
+ 	gx_device_memory *mmask =3D padev->mask;
+=20
  	if (mbits !=3D 0) {
  	    make_bitmap(&ctile->tbits, mbits, gs_next_ids(pis->memory, 1));
***************
*** 552,556 ****
--- 707,726 ----
  	} else
  	    ctile->tmask.data =3D 0;
+ 	ctile->cdev =3D NULL;
  	pcache->bits_used +=3D used;
+     } else {
+ 	gx_device_clist *cdev =3D (gx_device_clist *)fdev;
+ 	gx_device_clist_writer *cwdev =3D (gx_device_clist_writer *)fdev;
+=20
+ 	ctile->tbits.data =3D 0;
+ 	ctile->tbits.size.x =3D 0;
+ 	ctile->tbits.size.y =3D 0;
+ 	ctile->tmask.data =3D 0;
+ 	ctile->tmask.size.x =3D 0;
+ 	ctile->tmask.size.y =3D 0;
+ 	ctile->cdev =3D cdev;
+ 	/* Prevent freeing files on pattern_paint_cleanup : */
+ 	cwdev->do_not_open_or_close_bandfiles =3D true;
+     }
      pcache->tiles_used++;
      *pctile =3D ctile;
***************
*** 586,589 ****
--- 756,760 ----
      ctile->tbits.id =3D gs_no_bitmap_id;
      memset(&ctile->tmask, 0 , sizeof(ctile->tmask));
+     ctile->cdev =3D NULL;
      pcache->tiles_used++;
      return 0;
***************
*** 624,628 ****
  		gx_device * dev, gs_color_select_t select)
  {
!     gx_device_pattern_accum *adev;
      gs_pattern1_instance_t *pinst =3D
  	(gs_pattern1_instance_t *)pdc->ccolor.pattern;
--- 795,799 ----
  		gx_device * dev, gs_color_select_t select)
  {
!     gx_device_forward *adev;
      gs_pattern1_instance_t *pinst =3D
  	(gs_pattern1_instance_t *)pdc->ccolor.pattern;
***************
*** 642,646 ****
       * last reference to it from a graphics state is deleted.
       */
!     adev =3D gx_pattern_accum_alloc(mem, mem, pinst, =
"gx_pattern_load");
      if (adev =3D=3D 0)
  	return_error(gs_error_VMerror);
--- 813,817 ----
       * last reference to it from a graphics state is deleted.
       */
!     adev =3D gx_pattern_accum_alloc(mem, pis->pattern_cache->memory, =
pinst, "gx_pattern_load");
      if (adev =3D=3D 0)
  	return_error(gs_error_VMerror);
***************
*** 665,669 ****
      }
      /* We REALLY don't like the following cast.... */
!     code =3D gx_pattern_cache_add_entry((gs_imager_state *)pis, adev, =
&ctile);
      if (code >=3D 0) {
  	if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
--- 836,841 ----
      }
      /* We REALLY don't like the following cast.... */
!     code =3D gx_pattern_cache_add_entry((gs_imager_state *)pis,=20
! 		adev, &ctile);
      if (code >=3D 0) {
  	if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
***************
*** 673,684 ****
      }
  #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");
      }
  #endif
--- 845,858 ----
      }
  #ifdef DEBUG
!     if (gs_debug_c('B') && adev->procs.open_device =3D=3D =
pattern_accum_open) {
! 	gx_device_pattern_accum *pdev =3D (gx_device_pattern_accum *)adev;
!=20
!         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
***************
*** 690,693 ****
--- 864,873 ----
      return code;
  fail:
+     if (adev->procs.open_device =3D=3D pattern_clist_open_device) {
+ 	gx_device_clist *pdev =3D (gx_device_clist *)adev;
+=20
+ 	gs_free_object(mem, pdev->common.data, "gx_pattern_load");
+ 	pdev->common.data =3D 0;
+     }
      gs_free_object(mem, adev, "gx_pattern_load");
      return code;
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\gxpcolor.h	Tue Apr 10 21:14:03 2007
--- files\gs\src\gxpcolor.h	Sat Apr 14 00:34:56 2007
***************
*** 25,28 ****
--- 25,33 ----
  #include "gxpcache.h"
 =20
+ #ifndef gx_device_clist_DEFINED
+ #define gx_device_clist_DEFINED
+ typedef union gx_device_clist_s gx_device_clist;
+ #endif
+=20
  /*
   * Define the type of a Pattern, also used with Pattern instances.
***************
*** 163,169 ****
      gx_strip_bitmap tmask;	/* data =3D 0 if no mask */
      /* (i.e., the mask is all 1's) */
!     bool is_simple;		/* true if xstep/ystep =3D tile size */
!     bool is_dummy;		/* if true, the device manages the pattern,=20
                                     and the content of the tile is =
empty. */
      /* The following is neither key nor value. */
      uint index;			/* the index of the tile within */
--- 168,176 ----
      gx_strip_bitmap tmask;	/* data =3D 0 if no mask */
      /* (i.e., the mask is all 1's) */
!     gx_device_clist *cdev;	/* not NULL if the graphics is a command =
list. */
!     byte is_simple;		/* true if xstep/ystep =3D tile size */
!     byte is_dummy;		/* if true, the device manages the pattern,=20
                                     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 */
***************
*** 172,177 ****
 =20
  #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)
  #define private_st_color_tile_element()	/* in gxpcmap.c */\
    gs_private_st_element(st_color_tile_element, gx_color_tile,\
--- 179,184 ----
 =20
  #define private_st_color_tile()	/* in gxpcmap.c */\
!   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,\
***************
*** 216,220 ****
 =20
  /* Allocate a pattern accumulator. */
! gx_device_pattern_accum * gx_pattern_accum_alloc(gs_memory_t * mem,=20
  		       gs_memory_t * stoarge_memory,=20
  		       gs_pattern1_instance_t *pinst, client_name_t cname);
--- 223,227 ----
 =20
  /* Allocate a pattern accumulator. */
! gx_device_forward * gx_pattern_accum_alloc(gs_memory_t * mem,=20
  		       gs_memory_t * stoarge_memory,=20
  		       gs_pattern1_instance_t *pinst, client_name_t cname);
***************
*** 224,228 ****
  /* 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 *,
  			       gx_color_tile **);
  /* Add a dummy Pattern cache entry.  Stubs a pattern tile for =
interpreter when
--- 231,235 ----
  /* 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_forward *,
  			       gx_color_tile **);
  /* Add a dummy Pattern cache entry.  Stubs a pattern tile for =
interpreter when
=20
=20
=20
*** F:\SVN-GS\HEAD\gs\src\zpcolor.c	Tue Apr 10 21:14:03 2007
--- files\gs\src\zpcolor.c	Thu Apr 12 10:22:15 2007
***************
*** 236,240 ****
  	(gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
      ref *pdict =3D &((int_pattern *) =
pinst->template.client_data)->dict;
!     gx_device_pattern_accum *pdev =3D NULL;
      gx_device *cdev =3D gs_currentdevice_inline(igs);
      int code;
--- 236,240 ----
  	(gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
      ref *pdict =3D &((int_pattern *) =
pinst->template.client_data)->dict;
!     gx_device_forward *pdev =3D NULL;
      gx_device *cdev =3D gs_currentdevice_inline(igs);
      int code;
***************
*** 317,321 ****
  {
      int o_stack_adjust =3D ref_stack_count(&o_stack) - =
esp->value.intval;
!     gx_device_pattern_accum *pdev =3D r_ptr(esp - 1, =
gx_device_pattern_accum);
 =20
      if (pdev !=3D NULL) {
--- 317,321 ----
  {
      int o_stack_adjust =3D ref_stack_count(&o_stack) - =
esp->value.intval;
!     gx_device_forward *pdev =3D r_ptr(esp - 1, gx_device_forward);
 =20
      if (pdev !=3D NULL) {
=20

------=_NextPart_000_002D_01C77E3B.6DBC5DA0
Content-Type: application/octet-stream;
	name="A12B.PS"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="A12B.PS"

<<
  /PaintType 1
  /PatternType 1
  /TilingType 1
  /BBox [0 0 60 60]
  /XStep 60
  /YStep 60
  /star
  { gsave
    0 12 moveto
    4
    { 144 rotate
      0 12 lineto
    } repeat
    closepath
    fill
    grestore
  }
  /PaintProc
  { begin
    0.3 setgray
    15 15 translate
    star
    30 30 translate
    star
    0.7 setgray
    -30 0 translate
    star
    30 -30 translate
    star
    end
    %.break
  } 
>>
matrix
makepattern

/Star4 exch def

120 120 184 120 4 copy
/Pattern setcolorspace
Star4 setcolor
rectfill
0 setgray
rectstroke
/Courier 270 selectfont
160 100 translate
0.1 setgray % 0.9 setgray
0 0 moveto
(A) show
Star4 setpattern
0 0 moveto
(A) show

showpage

------=_NextPart_000_002D_01C77E3B.6DBC5DA0
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review

------=_NextPart_000_002D_01C77E3B.6DBC5DA0--