xref: /plan9/sys/src/cmd/gs/src/gxclist.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxclist.h,v 1.7 2005/03/14 18:08:36 dan Exp $ */
18 /* Command list definitions for Ghostscript. */
19 /* Requires gxdevice.h and gxdevmem.h */
20 
21 #ifndef gxclist_INCLUDED
22 #  define gxclist_INCLUDED
23 
24 #include "gscspace.h"
25 #include "gxband.h"
26 #include "gxbcache.h"
27 #include "gxclio.h"
28 #include "gxdevbuf.h"
29 #include "gxistate.h"
30 #include "gxrplane.h"
31 
32 /*
33  * A command list is essentially a compressed list of driver calls.
34  * Command lists are used to record an image that must be rendered in bands
35  * for high-resolution and/or limited-memory printers.
36  *
37  * Command lists work in two phases.  The first phase records driver calls,
38  * sorting them according to the band(s) they affect.  The second phase
39  * reads back the commands band-by-band to create the bitmap images.
40  * When opened, a command list is in the recording state; it switches
41  * automatically from recording to reading when its get_bits procedure
42  * is called.  Currently, there is a hack to reopen the device after
43  * each page is processed, in order to switch back to recording.
44  */
45 
46 /*
47  * The command list contains both commands for particular bands (the vast
48  * majority) and commands that apply to a range of bands.  In order to
49  * synchronize the two, we maintain the following invariant for buffered
50  * commands:
51  *
52  *      If there are any band-range commands in the buffer, they are the
53  *      first commands in the buffer, before any specific-band commands.
54  *
55  * To maintain this invariant, whenever we are about to put an band-range
56  * command in the buffer, we check to see if the buffer already has any
57  * band-range commands in it, and if so, whether they are the last commands
58  * in the buffer and are for the same range; if the answer to any of these
59  * questions is negative, we flush the buffer.
60  */
61 
62 /* ---------------- Public structures ---------------- */
63 
64 /*
65  * Define a saved page object.  This consists of a snapshot of the device
66  * structure, information about the page per se, and the num_copies
67  * parameter of output_page.
68  */
69 typedef struct gx_saved_page_s {
70     gx_device device;
71     char dname[8 + 1];		/* device name for checking */
72     gx_band_page_info_t info;
73     int num_copies;
74 } gx_saved_page;
75 
76 /*
77  * Define a saved page placed at a particular (X,Y) offset for rendering.
78  */
79 typedef struct gx_placed_page_s {
80     gx_saved_page *page;
81     gs_int_point offset;
82 } gx_placed_page;
83 
84 /*
85  * Define a procedure to cause some bandlist memory to be freed up,
86  * probably by rendering current bandlist contents.
87  */
88 #define proc_free_up_bandlist_memory(proc)\
89   int proc(gx_device *dev, bool flush_current)
90 
91 /* ---------------- Internal structures ---------------- */
92 
93 /*
94  * Currently, halftoning occurs during the first phase, producing calls
95  * to tile_rectangle.  Both phases keep a cache of recently seen bitmaps
96  * (halftone cells and characters), which allows writing only a short cache
97  * index in the command list rather than the entire bitmap.
98  *
99  * We keep only a single cache for all bands, but since the second phase
100  * reads the command lists for each band separately, we have to keep track
101  * for each cache entry E and band B whether the definition of E has been
102  * written into B's list.  We do this with a bit mask in each entry.
103  *
104  * Eventually, we will replace this entire arrangement with one in which
105  * we pass the actual halftone screen (whitening order) to all bands
106  * through the command list, and halftoning occurs on the second phase.
107  * This not only will shrink the command list, but will allow us to apply
108  * other rendering algorithms such as error diffusion in the second phase.
109  */
110 typedef struct {
111     ulong offset;		/* writing: offset from cdev->data, */
112     /*   0 means unused */
113     /* reading: offset from cdev->chunk.data */
114 } tile_hash;
115 typedef struct {
116     gx_cached_bits_common;
117     /* To save space, instead of storing rep_width and rep_height, */
118     /* we store width / rep_width and height / rep_height. */
119     byte x_reps, y_reps;
120     ushort rep_shift;
121     ushort index;		/* index in table (hash table when writing) */
122     ushort num_bands;		/* # of 1-bits in the band mask */
123     /* byte band_mask[]; */
124 #define ts_mask(pts) (byte *)((pts) + 1)
125     /* byte bits[]; */
126 #define ts_bits(cldev,pts) (ts_mask(pts) + (cldev)->tile_band_mask_size)
127 } tile_slot;
128 
129 /* Define the prefix on each command run in the writing buffer. */
130 typedef struct cmd_prefix_s cmd_prefix;
131 struct cmd_prefix_s {
132     cmd_prefix *next;
133     uint size;
134 };
135 
136 /* Define the pointers for managing a list of command runs in the buffer. */
137 /* There is one of these for each band, plus one for band-range commands. */
138 typedef struct cmd_list_s {
139     cmd_prefix *head, *tail;	/* list of commands for band */
140 } cmd_list;
141 
142 /*
143  * In order to keep the per-band state down to a reasonable size,
144  * we store only a single set of the imager state parameters;
145  * for each parameter, each band has a flag that says whether that band
146  * 'knows' the current value of the parameters.
147  */
148 extern const gs_imager_state clist_imager_state_initial;
149 
150 /*
151  * Define the main structure for holding command list state.
152  * Unless otherwise noted, all elements are used in both the writing (first)
153  * and reading (second) phase.
154  */
155 typedef struct gx_clist_state_s gx_clist_state;
156 
157 #define gx_device_clist_common_members\
158 	gx_device_forward_common;	/* (see gxdevice.h) */\
159 		/* Following must be set before writing or reading. */\
160 		/* See gx_device_clist_writer, below, for more that must be init'd */\
161 	/* gx_device *target; */	/* device for which commands */\
162 					/* are being buffered */\
163 	gx_device_buf_procs_t buf_procs;\
164 	gs_memory_t *bandlist_memory;	/* allocator for in-memory bandlist files */\
165 	byte *data;			/* buffer area */\
166 	uint data_size;			/* size of buffer */\
167 	gx_band_params_t band_params;	/* band buffering parameters */\
168 	bool do_not_open_or_close_bandfiles;	/* if true, do not open/close bandfiles */\
169 	bool page_uses_transparency;	/* if true then page uses PDF 1.4 transparency */\
170 		/* Following are used for both writing and reading. */\
171 	gx_bits_cache_chunk chunk;	/* the only chunk of bits */\
172 	gx_bits_cache bits;\
173 	uint tile_hash_mask;		/* size of tile hash table -1 */\
174 	uint tile_band_mask_size;	/* size of band mask preceding */\
175 					/* each tile in the cache */\
176 	tile_hash *tile_table;		/* table for tile cache: */\
177 					/* see tile_hash above */\
178 					/* (a hash table when writing) */\
179 	int ymin, ymax;			/* current band, <0 when writing */\
180 		/* Following are set when writing, read when reading. */\
181 	gx_band_page_info_t page_info;	/* page information */\
182 	int nbands		/* # of bands */
183 
184 typedef struct gx_device_clist_common_s {
185     gx_device_clist_common_members;
186 } gx_device_clist_common;
187 
188 #define clist_band_height(cldev) ((cldev)->page_info.band_height)
189 #define clist_cfname(cldev) ((cldev)->page_info.cfname)
190 #define clist_cfile(cldev) ((cldev)->page_info.cfile)
191 #define clist_bfname(cldev) ((cldev)->page_info.bfname)
192 #define clist_bfile(cldev) ((cldev)->page_info.bfile)
193 
194 /* Define the length of the longest dash pattern we are willing to store. */
195 /* (Strokes with longer patterns are converted to fills.) */
196 #define cmd_max_dash 11
197 
198 /* Define the state of a band list when writing. */
199 typedef struct clist_color_space_s {
200     byte byte1;			/* see cmd_opv_set_color_space in gxclpath.h */
201     gs_id id;			/* space->id for comparisons */
202     const gs_color_space *space;
203 } clist_color_space_t;
204 typedef struct gx_device_clist_writer_s {
205     gx_device_clist_common_members;	/* (must be first) */
206     int error_code;		/* error returned by cmd_put_op */
207     gx_clist_state *states;	/* current state of each band */
208     byte *cbuf;			/* start of command buffer */
209     byte *cnext;		/* next slot in command buffer */
210     byte *cend;			/* end of command buffer */
211     cmd_list *ccl;		/* &clist_state.list of last command */
212     cmd_list band_range_list;	/* list of band-range commands */
213     int band_range_min, band_range_max;		/* range for list */
214     uint tile_max_size;		/* max size of a single tile (bytes) */
215     uint tile_max_count;	/* max # of hash table entries */
216     gx_strip_bitmap tile_params;	/* current tile parameters */
217     int tile_depth;		/* current tile depth */
218     int tile_known_min, tile_known_max;  /* range of bands that knows the */
219 				/* current tile parameters */
220     /*
221      * NOTE: we must not set the line_params.dash.pattern member of the
222      * imager state to point to the dash_pattern member of the writer
223      * state (except transiently), since this would confuse the
224      * garbage collector.
225      */
226     gs_imager_state imager_state;	/* current values of imager params */
227     float dash_pattern[cmd_max_dash];	/* current dash pattern */
228     const gx_clip_path *clip_path;	/* current clip path, */
229 				/* only non-transient for images */
230     gs_id clip_path_id;		/* id of current clip path */
231     clist_color_space_t color_space;	/* current color space, */
232 				/* only used for non-mask images */
233     gs_id transfer_ids[4];	/* ids of transfer maps */
234     gs_id black_generation_id;	/* id of black generation map */
235     gs_id undercolor_removal_id;	/* id of u.c.r. map */
236     gs_id device_halftone_id;	/* id of device halftone */
237     gs_id image_enum_id;	/* non-0 if we are inside an image */
238 				/* that we are passing through */
239 	int error_is_retryable;		/* Extra status used to distinguish hard VMerrors */
240 	                           /* from warnings upgraded to VMerrors. */
241 	                           /* T if err ret'd by cmd_put_op et al can be retried */
242 	int permanent_error;		/* if < 0, error only cleared by clist_reset() */
243 	int driver_call_nesting;	/* nesting level of non-retryable driver calls */
244 	int ignore_lo_mem_warnings;	/* ignore warnings from clist file/mem */
245 		/* Following must be set before writing */
246 	proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if nz, proc to free some bandlist memory */
247 	int disable_mask;		/* mask of routines to disable clist_disable_xxx */
248 } gx_device_clist_writer;
249 
250 /* Bits for gx_device_clist_writer.disable_mask. Bit set disables behavior */
251 #define clist_disable_fill_path	(1 << 0)
252 #define clist_disable_stroke_path (1 << 1)
253 #define clist_disable_hl_image (1 << 2)
254 #define clist_disable_complex_clip (1 << 3)
255 #define clist_disable_nonrect_hl_image (1 << 4)
256 #define clist_disable_pass_thru_params (1 << 5)	/* disable EXCEPT at top of page */
257 #define clist_disable_copy_alpha (1 << 6) /* target does not support copy_alpha */
258 
259 /* Define the state of a band list when reading. */
260 /* For normal rasterizing, pages and num_pages are both 0. */
261 typedef struct gx_device_clist_reader_s {
262     gx_device_clist_common_members;	/* (must be first) */
263     gx_render_plane_t yplane;		/* current plane, index = -1 */
264 					/* means all planes */
265     const gx_placed_page *pages;
266     int num_pages;
267 } gx_device_clist_reader;
268 
269 typedef union gx_device_clist_s {
270     gx_device_clist_common common;
271     gx_device_clist_reader reader;
272     gx_device_clist_writer writer;
273 } gx_device_clist;
274 
275 extern_st(st_device_clist);
276 #define public_st_device_clist()	/* in gxclist.c */\
277   gs_public_st_complex_only(st_device_clist, gx_device_clist,\
278     "gx_device_clist", 0, device_clist_enum_ptrs, device_clist_reloc_ptrs,\
279     gx_device_finalize)
280 #define st_device_clist_max_ptrs\
281   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
282 
283 /* setup before opening clist device */
284 #define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable, pageusestransparency)\
285     BEGIN\
286 	(xclist)->common.data = (xdata);\
287 	(xclist)->common.data_size = (xdata_size);\
288 	(xclist)->common.target = (xtarget);\
289 	(xclist)->common.buf_procs = (xbuf_procs);\
290 	(xclist)->common.band_params = (xband_params);\
291 	(xclist)->common.do_not_open_or_close_bandfiles = (xexternal);\
292 	(xclist)->common.bandlist_memory = (xmemory);\
293 	(xclist)->writer.free_up_bandlist_memory = (xfree_bandlist);\
294 	(xclist)->writer.disable_mask = (xdisable);\
295 	(xclist)->writer.page_uses_transparency = (pageusestransparency);\
296     END
297 
298 /* Determine whether this clist device is able to recover VMerrors */
299 #define clist_test_VMerror_recoverable(cldev)\
300   ((cldev)->free_up_bandlist_memory != 0)
301 
302 /* The device template itself is never used, only the procedures. */
303 extern const gx_device_procs gs_clist_device_procs;
304 
305 /* Reset (or prepare to append to) the command list after printing a page. */
306 int clist_finish_page(gx_device * dev, bool flush);
307 
308 /* Close the band files and delete their contents. */
309 int clist_close_output_file(gx_device *dev);
310 
311 /*
312  * Close and delete the contents of the band files associated with a
313  * page_info structure (a page that has been separated from the device).
314  */
315 int clist_close_page_info(gx_band_page_info_t *ppi);
316 
317 /*
318  * Compute the colors-used information in the page_info structure from the
319  * information in the individual writer bands.  This is only useful at the
320  * end of a page.  gdev_prn_colors_used calls this procedure if it hasn't
321  * been called since the page was started.  clist_end_page also calls it.
322  */
323 void clist_compute_colors_used(gx_device_clist_writer *cldev);
324 
325 /* Define the abstract type for a printer device. */
326 #ifndef gx_device_printer_DEFINED
327 #  define gx_device_printer_DEFINED
328 typedef struct gx_device_printer_s gx_device_printer;
329 #endif
330 
331 /* Do device setup from params passed in the command list. */
332 int clist_setup_params(gx_device *dev);
333 
334 /*
335  * Render a rectangle to a client-supplied image.  This implements
336  * gdev_prn_render_rectangle for devices that are using banding.
337  *
338  * Note that clist_render_rectangle only guarantees to render *at least* the
339  * requested rectangle to bdev, offset by (-prect->p.x, -prect->p.y):
340  * anything it does to avoid rendering regions outside the rectangle is
341  * merely an optimization.  If the client really wants the output clipped to
342  * some rectangle smaller than ((0, 0), (bdev->width, bdev->height)), it
343  * must set up a clipping device.
344  */
345 int clist_render_rectangle(gx_device_clist *cdev,
346 			   const gs_int_rect *prect, gx_device *bdev,
347 			   const gx_render_plane_t *render_plane,
348 			   bool clear);
349 
350 #endif /* gxclist_INCLUDED */
351