1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gdevprn.h 9683 2009-04-24 01:06:30Z giles $ */
15 /* Common header file for memory-buffered printers */
16 
17 #ifndef gdevprn_INCLUDED
18 #  define gdevprn_INCLUDED
19 
20 #include "memory_.h"
21 #include "string_.h"
22 #include "gx.h"
23 #include "gp.h"			/* for gp_file_name_sizeof */
24 #include "gserrors.h"
25 #include "gsmatrix.h"		/* for gxdevice.h */
26 #include "gsutil.h"		/* for memflip8x8 */
27 #include "gxdevice.h"
28 #include "gxdevmem.h"
29 #include "gxclist.h"
30 #include "gxrplane.h"
31 #include "gsparam.h"
32 
33 /*
34  * Define the parameters for the printer rendering method.
35  * If the entire bitmap fits in PRN_MAX_BITMAP, and there is at least
36  * PRN_MIN_MEMORY_LEFT memory left after allocating it, render in RAM,
37  * otherwise use a command list with a size of PRN_BUFFER_SPACE.
38  * (These are parameters that can be changed by a client program.)
39  */
40 /* Define parameters for machines with little dinky RAMs.... */
41 #define PRN_MAX_BITMAP_SMALL 32000
42 #define PRN_BUFFER_SPACE_SMALL 25000
43 #define PRN_MIN_MEMORY_LEFT_SMALL 32000
44 /* Define parameters for machines with great big hulking RAMs.... */
45 #define PRN_MAX_BITMAP_LARGE 10000000L
46 #define PRN_BUFFER_SPACE_LARGE 4000000L
47 #define PRN_MIN_MEMORY_LEFT_LARGE 500000L
48 /* Define parameters valid on all machines. */
49 #define PRN_MIN_BUFFER_SPACE 10000	/* give up if less than this */
50 /* Now define conditional parameters. */
51 #if arch_small_memory
52 #  define PRN_MAX_BITMAP PRN_MAX_BITMAP_SMALL
53 #  define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_SMALL
54 #  define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_SMALL
55 #else
56 /****** These should really be conditional on gs_debug_c('.') if
57  ****** DEBUG is defined, but they're used in static initializers,
58  ****** so we can't do it.
59  ******/
60 #  if 0				/****** #  ifdef DEBUG ***** */
61 #    define PRN_MAX_BITMAP\
62        (gs_debug_c('.') ? PRN_MAX_BITMAP_SMALL : PRN_MAX_BITMAP_LARGE)
63 #    define PRN_BUFFER_SPACE\
64        (gs_debug_c('.') ? PRN_BUFFER_SPACE_SMALL : PRN_BUFFER_SPACE_LARGE)
65 #    define PRN_MIN_MEMORY_LEFT\
66        (gs_debug_c('.') ? PRN_MIN_MEMORY_LEFT_SMALL : PRN_MIN_MEMORY_LEFT_LARGE)
67 #  else
68 #    define PRN_MAX_BITMAP PRN_MAX_BITMAP_LARGE
69 #    define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_LARGE
70 #    define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_LARGE
71 #  endif
72 #endif
73 
74 /* Define the abstract type for a printer device. */
75 #ifndef gx_device_printer_DEFINED
76 #  define gx_device_printer_DEFINED
77 typedef struct gx_device_printer_s gx_device_printer;
78 #endif
79 
80 /* Define the abstract type for some band device procedures' arguments. */
81 typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params;
82 
83 /* Define the abstract type for a page queue for async rendering. */
84 #ifndef gx_page_queue_DEFINED
85 #  define gx_page_queue_DEFINED
86 typedef struct gx_page_queue_s gx_page_queue_t;
87 #endif
88 
89 /* Define the abstract type for parameters describing buffer space. */
90 #ifndef gdev_prn_space_params_DEFINED
91 #  define gdev_prn_space_params_DEFINED
92 typedef struct gdev_prn_space_params_s gdev_prn_space_params;
93 #endif
94 
95 /*
96  * Define the special procedures for band devices.
97  */
98 typedef struct gx_printer_device_procs_s {
99 
100     /*
101      * Print the page on the output file.  Required only for devices
102      * where output_page is gdev_prn_output_page; ignored for other
103      * devices.
104      */
105 
106 #define prn_dev_proc_print_page(proc)\
107   int proc(gx_device_printer *, FILE *)
108     prn_dev_proc_print_page((*print_page));
109 /* BACKWARD COMPATIBILITY */
110 #define dev_proc_print_page(proc) prn_dev_proc_print_page(proc)
111 
112     /* Print the page on the output file, with a given # of copies. */
113 
114 #define prn_dev_proc_print_page_copies(proc)\
115   int proc(gx_device_printer *, FILE *, int)
116     prn_dev_proc_print_page_copies((*print_page_copies));
117 /* BACKWARD COMPATIBILITY */
118 #define dev_proc_print_page_copies(proc) prn_dev_proc_print_page_copies(proc)
119 
120     /*
121      * Define buffer device management procedures.
122      * See gxdevcli.h for the definitions.
123      */
124 
125     gx_device_buf_procs_t buf_procs;
126 
127     /*
128      * Compute effective space params. These results effectively override
129      * the space_params in the device, but does not replace them; that is to
130      * say that computed space params are temps used for computation.
131      * Procedure must fill in only those space_params that it wishes to
132      * override, using curr width, height, margins, etc.
133      *
134      * Caller is gdevprn.open & gdevprn.put_params, calls driver or
135      * default.
136      */
137 
138 #define prn_dev_proc_get_space_params(proc)\
139   void proc(const gx_device_printer *, gdev_prn_space_params *)
140     prn_dev_proc_get_space_params((*get_space_params));
141 
142     /*
143      * Only for gx_device_printer devices that overlap interpreting and
144      * rasterizing. Since there are 2 instances of the device (1 for writing
145      * the cmd list & 1 for rasterizing it), and each device is associated
146      * with an different thread, this function is called to start the
147      * rasterizer's thread. Once started, the rasterizer thread must call
148      * down to gdev_prn_asnyc_render_thread, which will only return after
149      * device closes.
150      *
151      * Caller is gdevprna.open, calls driver implementation or default.
152      */
153 
154 #define prn_dev_proc_start_render_thread(proc)\
155   int proc(gdev_prn_start_render_params *)
156     prn_dev_proc_start_render_thread((*start_render_thread));
157 
158     /*
159      * Only for gx_device_printer devices that overlap interpreting and
160      * rasterizing. Since there are 2 instances of the device (1 for writing
161      * the cmd list & 1 for rasterizing it), these fns are called to
162      * open/close the rasterizer's instance, once the writer's instance has
163      * been created & init'd. These procs must cascade down to
164      * gdev_prn_async_render_open/close.
165      *
166      * Caller is gdevprna, calls driver implementation or default.
167      */
168 
169 #define prn_dev_proc_open_render_device(proc)\
170   int proc(gx_device_printer *)
171     prn_dev_proc_open_render_device((*open_render_device));
172 
173 #define prn_dev_proc_close_render_device(proc)\
174   int proc(gx_device_printer *)
175     prn_dev_proc_close_render_device((*close_render_device));
176 
177     /*
178      * Buffer a page on the output device. A page may or may not have been
179      * fully rendered, but the rasterizer needs to realize the page to free
180      * up resources or support copypage. Printing a page may involve zero or
181      * more buffer_pages. All buffer_page output is overlaid in the buffer
182      * until a terminating print_page or print_page_copies clears the
183      * buffer. Note that, after the first buffer_page, the driver must call
184      * the lower-level gdev_prn_render_lines procedure instead of
185      * get_bits. The difference is that gdev_prn_render_lines requires the
186      * caller to supply the same buffered bitmap that was computed as a
187      * result of a previous buffer_page, so that gdev_prn_render_lines can
188      * add further marks to the existing buffered image. NB that output must
189      * be accumulated in buffer even if num_copies == 0.
190      *
191      * Caller is expected to be gdevprn, calls driver implementation or
192      * default.  */
193 
194 #define prn_dev_proc_buffer_page(proc)\
195   int proc(gx_device_printer *, FILE *, int)
196     prn_dev_proc_buffer_page((*buffer_page));
197 
198 } gx_printer_device_procs;
199 
200 /* ------ Printer device definition ------ */
201 
202 /* Structure for generic printer devices. */
203 /* This must be preceded by gx_device_common. */
204 /* Printer devices are actually a union of a memory device */
205 /* and a clist device, plus some additional state. */
206 #define prn_fname_sizeof gp_file_name_sizeof
207 typedef enum {
208     BandingAuto = 0,
209     BandingAlways,
210     BandingNever
211 } gdev_prn_banding_type;
212 struct gdev_prn_space_params_s {
213     long MaxBitmap;		/* max size of non-buffered bitmap */
214     long BufferSpace;		/* space to use for buffer */
215     gx_band_params_t band;	/* see gxclist.h */
216     bool params_are_read_only;	/* true if put_params may not modify this struct */
217     gdev_prn_banding_type banding_type;	/* used to force banding or bitmap */
218 };
219 
220 #define gx_prn_device_common\
221 	byte skip[max(sizeof(gx_device_memory), sizeof(gx_device_clist)) -\
222 		  sizeof(gx_device) + sizeof(double) /* padding */];\
223 	gx_printer_device_procs printer_procs;\
224 		/* ------ Device parameters that must be set ------ */\
225 		/* ------ before calling the device open routine. ------ */\
226 	gdev_prn_space_params space_params;\
227 	char fname[prn_fname_sizeof];	/* OutputFile */\
228 		/* ------ Other device parameters ------ */\
229 	bool OpenOutputFile;\
230 	bool ReopenPerPage;\
231         bool page_uses_transparency; /* PDF 1.4 transparency is used on page */\
232 	bool Duplex;\
233 	  int Duplex_set;		/* -1 = not supported */\
234 		/* ------ End of parameters ------ */\
235 	bool file_is_new;		/* true iff file just opened */\
236 	FILE *file;			/* output file */\
237 	long buffer_space;	/* amount of space for clist buffer, */\
238 					/* 0 means not using clist */\
239 	byte *buf;			/* buffer for rendering */\
240 		/* ---- Begin async rendering support --- */\
241 	gs_memory_t *buffer_memory;	/* allocator for command list */\
242 	gs_memory_t *bandlist_memory;	/* allocator for bandlist files */\
243 	proc_free_up_bandlist_memory((*free_up_bandlist_memory));  	/* if nz, proc to free some bandlist memory */\
244 	gx_page_queue_t *page_queue;	/* if <> 0,page queue for gdevprna NOT GC'd */\
245 	bool is_async_renderer;		/* device is only the rendering part of async device */\
246 	gx_device_printer *async_renderer;	/* in async writer, pointer to async renderer */\
247 	uint clist_disable_mask;	/* mask of clist options to disable */\
248 		/* ---- End async rendering support --- */\
249 	int num_render_threads_requested;	/* for multiple band rendering threads */\
250 	gx_device_procs save_procs_while_delaying_erasepage;	/* save device procs while delaying erasepage. */\
251 	gx_device_procs orig_procs	/* original (std_)procs */
252 
253 /* The device descriptor */
254 struct gx_device_printer_s {
255     gx_device_common;
256     gx_prn_device_common;
257 };
258 
259 extern_st(st_device_printer);
260 #define public_st_device_printer()	/* in gdevprn.c */\
261   gs_public_st_complex_only(st_device_printer, gx_device_printer,\
262     "gx_device_printer", 0, device_printer_enum_ptrs,\
263     device_printer_reloc_ptrs, gx_device_finalize)
264 
265 /* Define a typedef for the sake of ansi2knr. */
266 typedef dev_proc_print_page((*dev_proc_print_page_t));
267 
268 /* Standard device procedures for printers */
269 dev_proc_open_device(gdev_prn_open);
270 dev_proc_output_page(gdev_prn_output_page);
271 dev_proc_close_device(gdev_prn_close);
272 #define gdev_prn_map_rgb_color gx_default_b_w_map_rgb_color
273 #define gdev_prn_map_color_rgb gx_default_b_w_map_color_rgb
274 dev_proc_get_params(gdev_prn_get_params);
275 dev_proc_put_params(gdev_prn_put_params);
276 
277 /* Default printer-specific procedures */
278 /* VMS limits procedure names to 31 characters. */
279 prn_dev_proc_get_space_params(gx_default_get_space_params);
280 /* BACKWARD COMPATIBILITY */
281 #define gdev_prn_default_get_space_params gx_default_get_space_params
282 prn_dev_proc_start_render_thread(gx_default_start_render_thread); /* for async rendering only, see gdevprna.c */
283 prn_dev_proc_open_render_device(gx_default_open_render_device);
284 prn_dev_proc_close_render_device(gx_default_close_render_device);
285 prn_dev_proc_buffer_page(gx_default_buffer_page); /* returns an error */
286 
287 /* Macro for generating procedure table */
288 #define prn_procs(p_open, p_output_page, p_close)\
289   prn_color_procs(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb)
290 #define prn_params_procs(p_open, p_output_page, p_close, p_get_params, p_put_params)\
291   prn_color_params_procs(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb, p_get_params, p_put_params)
292 #define prn_color_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb)\
293   prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, gdev_prn_get_params, gdev_prn_put_params)
294 /* See gdev_prn_open for explanation of the NULLs below. */
295 #define prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_get_params, p_put_params) {\
296 	p_open,\
297 	NULL,	/* get_initial_matrix */\
298 	NULL,	/* sync_output */\
299 	p_output_page,\
300 	p_close,\
301 	p_map_rgb_color,\
302 	p_map_color_rgb,\
303 	NULL,	/* fill_rectangle */\
304 	NULL,	/* tile_rectangle */\
305 	NULL,	/* copy_mono */\
306 	NULL,	/* copy_color */\
307 	NULL,	/* draw_line */\
308 	NULL,	/* get_bits */\
309 	p_get_params,\
310 	p_put_params,\
311 	NULL,	/* map_cmyk_color */\
312 	NULL,	/* get_xfont_procs */\
313 	NULL,	/* get_xfont_device */\
314 	NULL,	/* map_rgb_alpha_color */\
315 	gx_page_device_get_page_device,\
316 	NULL,	/* get_alpha_bits */\
317 	NULL,	/* copy_alpha */\
318 	NULL,	/* get_band */\
319 	NULL,	/* copy_rop */\
320 	NULL,	/* fill_path */\
321 	NULL,	/* stroke_path */\
322 	NULL,	/* fill_mask */\
323 	NULL,	/* fill_trapezoid */\
324 	NULL,	/* fill_parallelogram */\
325 	NULL,	/* fill_triangle */\
326 	NULL,	/* draw_thin_line */\
327 	NULL,	/* begin_image */\
328 	NULL,	/* image_data */\
329 	NULL,	/* end_image */\
330 	NULL,	/* strip_tile_rectangle */\
331 	NULL,	/* strip_copy_rop, */\
332 	NULL,	/* get_clipping_box */\
333 	NULL,	/* begin_typed_image */\
334 	NULL,	/* get_bits_rectangle */\
335 	NULL,	/* map_color_rgb_alpha */\
336 	NULL,	/* create_compositor */\
337 	NULL,	/* get_hardware_params */\
338 	NULL,	/* text_begin */\
339 	NULL	/* finish_copydevice */\
340 }
341 
342 /* The standard printer device procedures */
343 /* (using gdev_prn_open/output_page/close). */
344 extern const gx_device_procs prn_std_procs;
345 
346 /*
347  * Define macros for generating the device structure,
348  * analogous to the std_device_body macros in gxdevice.h
349  * Note that the macros are broken up so as to be usable for devices that
350  * add further initialized state to the printer device.
351  *
352  * The 'margin' values provided here specify the unimageable region
353  * around the edges of the page (in inches), and the left and top margins
354  * also specify the displacement of the device (0,0) point from the
355  * upper left corner.  We should provide macros that allow specifying
356  * all 6 values independently, but we don't yet.
357  *
358  * Note that print_page and print_page_copies must not both be defaulted.
359  */
360 #define prn_device_body_rest2_(print_page, print_page_copies, duplex_set)\
361 	 { 0 },		/* std_procs */\
362 	 { 0 },		/* skip */\
363 	 { print_page,\
364 	   print_page_copies,\
365 	   { gx_default_create_buf_device,\
366 	     gx_default_size_buf_device,\
367 	     gx_default_setup_buf_device,\
368 	     gx_default_destroy_buf_device\
369 	   },\
370 	   gdev_prn_default_get_space_params,\
371 	   gx_default_start_render_thread,\
372 	   gx_default_open_render_device,\
373 	   gx_default_close_render_device,\
374 	   gx_default_buffer_page\
375 	 },\
376 	 { PRN_MAX_BITMAP, PRN_BUFFER_SPACE,\
377 	     { BAND_PARAMS_INITIAL_VALUES },\
378 	   0/*false*/,	/* params_are_read_only */\
379 	   BandingAuto	/* banding_type */\
380 	 },\
381 	 { 0 },		/* fname */\
382 	0/*false*/,	/* OpenOutputFile */\
383 	0/*false*/,	/* ReopenPerPage */\
384 	0/*false*/,	/* page_uses_transparency */\
385 	0/*false*/, duplex_set,	/* Duplex[_set] */\
386 	0/*false*/, 0, 0, 0, /* file_is_new ... buf */\
387 	0, 0, 0, 0, 0/*false*/, 0, 0, /* buffer_memory ... clist_dis'_mask */\
388 	0, 		/* num_render_threads_requested */\
389 	{ 0 },	/* save_procs_while_delaying_erasepage */\
390 	{ 0 }	/* ... orig_procs */
391 #define prn_device_body_rest_(print_page)\
392   prn_device_body_rest2_(print_page, gx_default_print_page_copies, -1)
393 #define prn_device_body_copies_rest_(print_page_copies)\
394   prn_device_body_rest2_(gx_print_page_single_copy, print_page_copies, -1)
395 
396 /* The Sun cc compiler won't allow \ within a macro argument list. */
397 /* This accounts for the short parameter names here and below. */
398 #define prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\
399 	std_device_full_body_type(dtype, &procs, dname, &st_device_printer,\
400 	  (int)((float)(w10) * (xdpi) / 10 + 0.5),\
401 	  (int)((float)(h10) * (ydpi) / 10 + 0.5),\
402 	  xdpi, ydpi,\
403 	  ncomp, depth, mg, mc, dg, dc,\
404 	  (float)(-(lo) * (xdpi)), (float)(-(to) * (ydpi)),\
405 	  (float)((lm) * 72.0), (float)((bm) * 72.0),\
406 	  (float)((rm) * 72.0), (float)((tm) * 72.0)\
407 	),\
408 	prn_device_body_rest_(print_page)
409 #define prn_device_margins_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\
410 	std_device_full_body_type(dtype, &procs, dname, stype,\
411 	  (int)((float)(w10) * (xdpi) / 10 + 0.5),\
412 	  (int)((float)(h10) * (ydpi) / 10 + 0.5),\
413 	  xdpi, ydpi,\
414 	  ncomp, depth, mg, mc, dg, dc,\
415 	  (float)(-(lo) * (xdpi)), (float)(-(to) * (ydpi)),\
416 	  (float)((lm) * 72.0), (float)((bm) * 72.0),\
417 	  (float)((rm) * 72.0), (float)((tm) * 72.0)\
418 	),\
419 	prn_device_body_rest_(print_page)
420 
421 #define prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\
422   prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\
423     lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)
424 #define prn_device_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\
425   prn_device_margins_stype_body(dtype, procs, dname, stype, w10, h10, xdpi, ydpi,\
426     lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)
427 
428 #define prn_device_margins_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\
429 	std_device_full_body_type_extended(dtype, &procs, dname, &st_device_printer,\
430 	  (int)((long)(w10) * (xdpi) / 10),\
431 	  (int)((long)(h10) * (ydpi) / 10),\
432 	  xdpi, ydpi,\
433 	  mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn,\
434 	  -(lo) * (xdpi), -(to) * (ydpi),\
435 	  (lm) * 72.0, (bm) * 72.0,\
436 	  (rm) * 72.0, (tm) * 72.0\
437 	),\
438 	prn_device_body_rest_(print_page)
439 
440 #define prn_device_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)\
441   prn_device_margins_body_extended(dtype, procs, dname, w10, h10, xdpi, ydpi,\
442     lm, tm, lm, bm, rm, tm, mcomp, ncomp, pol, depth, gi, mg, mc, dg, dc, ef, cn, print_page)
443 
444 #define prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\
445 	std_device_std_color_full_body_type(dtype, &procs, dname, &st_device_printer,\
446 	  (int)((float)(w10) * (xdpi) / 10 + 0.5),\
447 	  (int)((float)(h10) * (ydpi) / 10 + 0.5),\
448 	  xdpi, ydpi, color_bits,\
449 	  (float)(-(lo) * (xdpi)), (float)(-(to) * (ydpi)),\
450 	  (float)((lm) * 72.0), (float)((bm) * 72.0),\
451 	  (float)((rm) * 72.0), (float)((tm) * 72.0)\
452 	),\
453 	prn_device_body_rest_(print_page)
454 
455 #define prn_device_std_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\
456   prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\
457     lm, tm, lm, bm, rm, tm, color_bits, print_page)
458 
459 #define prn_device_std_margins_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\
460 	std_device_std_color_full_body_type(dtype, &procs, dname, &st_device_printer,\
461 	  (int)((float)(w10) * (xdpi) / 10 + 0.5),\
462 	  (int)((float)(h10) * (ydpi) / 10 + 0.5),\
463 	  xdpi, ydpi, color_bits,\
464 	  (float)(-(lo) * (xdpi)), (float)(-(to) * (ydpi)),\
465 	  (float)((lm) * 72.0), (float)((bm) * 72.0),\
466 	  (float)((rm) * 72.0), (float)((tm) * 72.0)\
467 	),\
468 	prn_device_body_copies_rest_(print_page_copies)
469 
470 #define prn_device_std_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\
471   prn_device_std_margins_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi,\
472     lm, tm, lm, bm, rm, tm, color_bits, print_page_copies)
473 
474      /* Note that the following macros add { } around the data. */
475 
476 #define prn_device_margins(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\
477 { prn_device_std_margins_body(gx_device_printer, procs, dname,\
478     w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\
479 }
480 
481 #define prn_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\
482   prn_device_margins(procs, dname, w10, h10, xdpi, ydpi,\
483     lm, tm, lm, bm, rm, tm, color_bits, print_page)
484 
485 #define prn_device_margins_copies(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\
486 { prn_device_std_margins_body_copies(gx_device_printer, procs, dname,\
487     w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page_copies)\
488 }
489 
490 #define prn_device_copies(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page_copies)\
491   prn_device_margins_copies(procs, dname, w10, h10, xdpi, ydpi,\
492     lm, tm, lm, bm, rm, tm, color_bits, print_page_copies)
493 
494 /* ------ Utilities ------ */
495 /* These are defined in gdevprn.c. */
496 
497 /*
498  * Open the printer's output file if necessary.
499  */
500 /* VMS limits procedure names to 31 characters. */
501 int gdev_prn_open_printer_seekable(gx_device *dev, bool binary_mode,
502 				   bool seekable);
503 /* BACKWARD COMPATIBILITY */
504 #define gdev_prn_open_printer_positionable gdev_prn_open_printer_seekable
505 /* open_printer defaults positionable = false */
506 int gdev_prn_open_printer(gx_device * dev, bool binary_mode);
507 /*
508  * Test whether the printer's output file was just opened, i.e., whether
509  * this is the first page being written to this file.  This is only valid
510  * at the entry to a driver's print_page procedure.
511  */
512 bool gdev_prn_file_is_new(const gx_device_printer *pdev);
513 
514 /*
515  * Determine the number of bytes required for one scan line of output to
516  * a printer device, without any padding.
517  */
518 #define gdev_prn_raster(pdev) gx_device_raster((gx_device *)(pdev), 0)
519 
520 /*
521  * Determine (conservatively) what colors are used in a given range of scan
522  * lines, and return the actual range of scan lines to which the result
523  * applies.  (Currently, the result will always actually apply to one or
524  * more full bands.)  In the non-banded case, this information is currently
525  * not available, so we return all-1s (i.e., any color may appear) as the
526  * 'or', and the entire page as the range; we may improve this someday.
527  *
528  * The return value is like get_band: the first Y value of the actual range
529  * is stored in *range_start, and the height of the range is returned.
530  * If the parameters are invalid, the procedure returns -1.
531  */
532 int gdev_prn_colors_used(gx_device *dev, int y, int height,
533 			 gx_colors_used_t *colors_used,
534 			 int *range_start);
535 /*
536  * Determine the colors used in a saved page.  We still need the device
537  * in order to know the total page height.
538  */
539 int gx_page_info_colors_used(const gx_device *dev,
540 			     const gx_band_page_info_t *page_info,
541 			     int y, int height,
542 			     gx_colors_used_t *colors_used,
543 			     int *range_start);
544 
545 /*
546  * Render a subrectangle of the page into a target device provided by the
547  * caller, optionally clearing the device before rendering.  The rectangle
548  * need not coincide exactly with band boundaries, but it will be most
549  * efficient if they do, since it is necessary to render every band that
550  * even partly falls within the rectangle.  This is the lowest-level
551  * rendering procedure: the other procedures for reading rasterized lines,
552  * defined below, ultimately call this one.
553  *
554  * render_plane is used only for internal cache bookkeeping: it doesn't
555  * affect what is passed to the buffer device.  It is the client's
556  * responsibility to set up a plane extraction device, if required, to
557  * select an individual plane for rendering.
558  *
559  * Note that it may be necessary to render more than one plane even if the
560  * caller only requests a single plane.  Currently this only occurs for
561  * non-trivial RasterOps on CMYK devices.  If this is the case, it is the
562  * client's responsibility to provide a target device that accumulates full
563  * pixels rather than a single plane: if the plane extraction device is
564  * asked to execute an operation that requires full pixels, it will return
565  * an error.
566  */
567 int gdev_prn_render_rectangle(gx_device_printer *pdev,
568 			      const gs_int_rect *prect,
569 			      gx_device *target,
570 			      const gx_render_plane_t *render_plane,
571 			      bool clear);
572 
573 /*
574  * Read one or more rasterized scan lines for printing.
575  * The procedure either copies the scan lines into the buffer and
576  * sets *actual_buffer = buffer and *actual_bytes_per_line = bytes_per_line,
577  * or sets *actual_buffer and *actual_bytes_per_line to reference
578  * already-rasterized scan lines.
579  *
580  * For non-banded devices, copying is never necessary.  For banded devices,
581  * if the client's buffer is at least as large as the single preallocated
582  * one (if any), the band will be rasterized directly into the client's
583  * buffer, again avoiding copying.  Alternatively, if there is a
584  * preallocated buffer and the call asks for no more data than will fit
585  * in that buffer, buffer may be NULL: any necessary rasterizing will
586  * occur in the preallocated buffer, and a pointer into the buffer will be
587  * returned.
588  */
589 int gdev_prn_get_lines(gx_device_printer *pdev, int y, int height,
590 		       byte *buffer, uint bytes_per_line,
591 		       byte **actual_buffer, uint *actual_bytes_per_line,
592 		       const gx_render_plane_t *render_plane);
593 
594 /*
595  * Read a rasterized scan line for sending to the printer.
596  * This is essentially a simplified form of gdev_prn_get_lines,
597  * except that it also calls gdev_prn_clear_trailing_bits.
598  */
599 int gdev_prn_get_bits(gx_device_printer *pdev, int y, byte *buffer,
600 		      byte **actual_buffer);
601 
602 /*
603  * Copy scan lines to send to the printer.  This is now DEPRECATED,
604  * because it copies the data even if the data are already available in
605  * the right form in the rasterizer buffer.  Use gdev_prn_get_bits
606  * instead.  For documentation, see the implementation in gdevprn.c.
607  */
608 int gdev_prn_copy_scan_lines(gx_device_printer *, int, byte *, uint);
609 
610 /*
611  * Clear any trailing bits in the last byte of one or more scan lines
612  * returned from the calls for reading out rasterized data.  Note that
613  * the device is only used to get the width and depth, and need not be
614  * a printer device.
615  */
616 void gdev_prn_clear_trailing_bits(byte *data, uint raster, int height,
617 				  const gx_device *dev);
618 
619 /*
620  * Close the printer's output file.
621  */
622 int gdev_prn_close_printer(gx_device *);
623 
624 /* Print a single copy of a page by calling print_page_copies. */
625 prn_dev_proc_print_page(gx_print_page_single_copy);
626 
627 /*
628  * Define a default print_page_copies procedure just calls print_page
629  * the given number of times.
630  */
631 prn_dev_proc_print_page_copies(gx_default_print_page_copies);
632 
633 /*
634  * Determine the number of scan lines that should actually be passed
635  * to the device.
636  */
637 int gdev_prn_print_scan_lines(gx_device *);
638 
639 /* Allocate / reallocate / free printer memory. */
640 int gdev_prn_allocate_memory(gx_device *pdev,
641 			     gdev_prn_space_params *space,
642 			     int new_width, int new_height);
643 int gdev_prn_reallocate_memory(gx_device *pdev,
644 			       gdev_prn_space_params *space,
645 			       int new_width, int new_height);
646 int gdev_prn_free_memory(gx_device *pdev);
647 
648 /*
649  * Create the buffer device for a printer device.  Clients should always
650  * call this, and never call the device procedure directly.  The actual
651  * create_buf_device procedure is passed as an argument because the banding
652  * code needs this: normally it is dev_proc(some_dev, create_buf_device).
653  */
654 typedef dev_proc_create_buf_device((*create_buf_device_proc_t));
655 int gdev_create_buf_device(create_buf_device_proc_t cbd_proc,
656 			   gx_device **pbdev, gx_device *target, int y,
657 			   const gx_render_plane_t *render_plane,
658 			   gs_memory_t *mem, gx_band_complexity_t *band_complexity);
659 
660 /* BACKWARD COMPATIBILITY */
661 #define dev_print_scan_lines(dev)\
662   gdev_prn_print_scan_lines((gx_device *)(dev))
663 #define gdev_mem_bytes_per_scan_line(dev)\
664   gdev_prn_raster((gx_device_printer *)(dev))
665 #define gdev_prn_transpose_8x8(inp,ils,outp,ols)\
666   memflip8x8(inp,ils,outp,ols)
667 
668 /* ------ Printer device types ------ */
669 /**************** THE FOLLOWING CODE IS NOT USED YET. ****************/
670 
671 #if 0				/**************** VMS linker gets upset *************** */
672 #endif
673 int gdev_prn_initialize(gx_device *, const char *, dev_proc_print_page((*)));
674 void gdev_prn_init_color(gx_device *, int, dev_proc_map_rgb_color((*)), dev_proc_map_color_rgb((*)));
675 
676 #define prn_device_type(dtname, initproc, pageproc)\
677 static dev_proc_print_page(pageproc);\
678 device_type(dtname, st_prn_device, initproc)
679 
680 #define prn_device_type_mono(dtname, dname, initproc, pageproc)\
681 static dev_proc_print_page(pageproc);\
682 static int \
683 initproc(gx_device *dev)\
684 {	return gdev_prn_initialize(dev, dname, pageproc);\
685 }\
686 device_type(dtname, st_prn_device, initproc)
687 
688 #define prn_device_type_color(dtname, dname, depth, initproc, pageproc, rcproc, crproc)\
689 static dev_proc_print_page(pageproc);\
690 static int \
691 initproc(gx_device *dev)\
692 {	int code = gdev_prn_initialize(dev, dname, pageproc);\
693 	gdev_prn_init_color(dev, depth, rcproc, crproc);\
694 	return code;\
695 }\
696 device_type(dtname, st_prn_device, initproc)
697 
698 #endif /* gdevprn_INCLUDED */
699