xref: /plan9-contrib/sys/src/cmd/gs/src/gdevbbox.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gdevbbox.h,v 1.6 2004/09/16 08:03:56 igor Exp $ */
187dd7cddfSDavid du Colombier /* Definitions and interface for bbox (bounding box accumulator) device */
197dd7cddfSDavid du Colombier /* Requires gxdevice.h */
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier #ifndef gdevbbox_INCLUDED
227dd7cddfSDavid du Colombier #  define gdevbbox_INCLUDED
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier /*
257dd7cddfSDavid du Colombier  * This device keeps track of the per-page bounding box, and also optionally
267dd7cddfSDavid du Colombier  * forwards all drawing commands to a target.  It can be used either as a
277dd7cddfSDavid du Colombier  * free-standing device or as a component (e.g., by the EPS writer).
287dd7cddfSDavid du Colombier  *
297dd7cddfSDavid du Colombier  * One way to use a bounding box device is simply to include bbox.dev in the
307dd7cddfSDavid du Colombier  * value of DEVICE_DEVSn in the makefile.  This produces a free-standing
317dd7cddfSDavid du Colombier  * device named 'bbox' that can be selected in the usual way (-sDEVICE=bbox)
327dd7cddfSDavid du Colombier  * and that prints out the bounding box at each showpage or copypage without
337dd7cddfSDavid du Colombier  * doing any drawing.
347dd7cddfSDavid du Colombier  *
357dd7cddfSDavid du Colombier  * The other way to use a bounding box device is from C code as a component
367dd7cddfSDavid du Colombier  * in a device pipeline.  To set up a bounding box device that doesn't do
377dd7cddfSDavid du Colombier  * any drawing:
387dd7cddfSDavid du Colombier  *      gx_device_bbox *bdev =
397dd7cddfSDavid du Colombier  *        gs_alloc_struct_immovable(some_memory,
407dd7cddfSDavid du Colombier  *                                  gx_device_bbox, &st_device_bbox,
417dd7cddfSDavid du Colombier  *                                  "some identifying string for debugging");
427dd7cddfSDavid du Colombier  *      gx_device_bbox_init(bdev, NULL);
437dd7cddfSDavid du Colombier  * Non-drawing bounding box devices have an "infinite" page size.
447dd7cddfSDavid du Colombier  *
457dd7cddfSDavid du Colombier  * To set up a bounding box device that draws to another device tdev:
467dd7cddfSDavid du Colombier  *      gx_device_bbox *bdev =
477dd7cddfSDavid du Colombier  *        gs_alloc_struct_immovable(some_memory,
487dd7cddfSDavid du Colombier  *                                  gx_device_bbox, &st_device_bbox,
497dd7cddfSDavid du Colombier  *                                  "some identifying string for debugging");
507dd7cddfSDavid du Colombier  *      gx_device_bbox_init(bdev, tdev);
517dd7cddfSDavid du Colombier  * Bounding box devices that draw to a real device appear to have the
527dd7cddfSDavid du Colombier  * same page size as that device.
537dd7cddfSDavid du Colombier  *
547dd7cddfSDavid du Colombier  * To intercept the end-of-page to call a routine eop of your own, after
557dd7cddfSDavid du Colombier  * setting up the device:
567dd7cddfSDavid du Colombier  *      dev_proc_output_page(eop);      -- declare a prototype for eop
577dd7cddfSDavid du Colombier  *      ...
587dd7cddfSDavid du Colombier  *      set_dev_proc(bdev, output_page, eop);
597dd7cddfSDavid du Colombier  *      ...
607dd7cddfSDavid du Colombier  *      int eop(gx_device *dev, int num_copies, int flush)
617dd7cddfSDavid du Colombier  *      {       gs_rect bbox;
627dd7cddfSDavid du Colombier  *              gx_device_bbox_bbox((gx_device_bbox *)dev, &bbox);
637dd7cddfSDavid du Colombier  *              << do whatever you want >>
647dd7cddfSDavid du Colombier  *              return gx_forward_output_page(dev, num_copies, flush);
657dd7cddfSDavid du Colombier  *      }
667dd7cddfSDavid du Colombier  *
677dd7cddfSDavid du Colombier  * Note that bounding box devices, unlike almost all other forwarding
687dd7cddfSDavid du Colombier  * devices, conditionally propagate the open_device and close_device
697dd7cddfSDavid du Colombier  * calls to their target.  By default, they do propagate these calls:
707dd7cddfSDavid du Colombier  * use gx_device_bbox_fwd_open_close to change this if you want.
717dd7cddfSDavid du Colombier  */
727dd7cddfSDavid du Colombier /*
737dd7cddfSDavid du Colombier  * Define virtual procedures for managing the accumulated bounding box.
747dd7cddfSDavid du Colombier  * These may be redefined by subclasses, and are also used for compositors.
757dd7cddfSDavid du Colombier  */
767dd7cddfSDavid du Colombier typedef struct gx_device_bbox_procs_s {
777dd7cddfSDavid du Colombier 
787dd7cddfSDavid du Colombier #define dev_bbox_proc_init_box(proc)\
79*593dc095SDavid du Colombier   bool proc(void *proc_data)
807dd7cddfSDavid du Colombier     dev_bbox_proc_init_box((*init_box));
817dd7cddfSDavid du Colombier 
827dd7cddfSDavid du Colombier #define dev_bbox_proc_get_box(proc)\
83*593dc095SDavid du Colombier   void proc(const void *proc_data, gs_fixed_rect *pbox)
847dd7cddfSDavid du Colombier     dev_bbox_proc_get_box((*get_box));
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier #define dev_bbox_proc_add_rect(proc)\
87*593dc095SDavid du Colombier   void proc(void *proc_data, fixed x0, fixed y0, fixed x1, fixed y1)
887dd7cddfSDavid du Colombier     dev_bbox_proc_add_rect((*add_rect));
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier #define dev_bbox_proc_in_rect(proc)\
91*593dc095SDavid du Colombier   bool proc(const void *proc_data, const gs_fixed_rect *pbox)
927dd7cddfSDavid du Colombier     dev_bbox_proc_in_rect((*in_rect));
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier } gx_device_bbox_procs_t;
957dd7cddfSDavid du Colombier /* Default implementations */
967dd7cddfSDavid du Colombier dev_bbox_proc_init_box(bbox_default_init_box);
977dd7cddfSDavid du Colombier dev_bbox_proc_get_box(bbox_default_get_box);
987dd7cddfSDavid du Colombier dev_bbox_proc_add_rect(bbox_default_add_rect);
997dd7cddfSDavid du Colombier dev_bbox_proc_in_rect(bbox_default_in_rect);
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier #define gx_device_bbox_common\
1027dd7cddfSDavid du Colombier 	gx_device_forward_common;\
1037dd7cddfSDavid du Colombier 	bool free_standing;\
1047dd7cddfSDavid du Colombier 	bool forward_open_close;\
1057dd7cddfSDavid du Colombier 	gx_device_bbox_procs_t box_procs;\
1067dd7cddfSDavid du Colombier 	void *box_proc_data;\
1077dd7cddfSDavid du Colombier 	bool white_is_opaque;\
1087dd7cddfSDavid du Colombier 	/* The following are updated dynamically. */\
1097dd7cddfSDavid du Colombier 	gs_fixed_rect bbox;\
1107dd7cddfSDavid du Colombier 	gx_color_index black, white;\
1117dd7cddfSDavid du Colombier 	gx_color_index transparent /* white or gx_no_color_index */
1127dd7cddfSDavid du Colombier typedef struct gx_device_bbox_s gx_device_bbox;
1137dd7cddfSDavid du Colombier #define gx_device_bbox_common_initial(fs, foc, wio)\
1147dd7cddfSDavid du Colombier   0 /* target */,\
1157dd7cddfSDavid du Colombier   fs, foc, {0}, 0, wio,\
1167dd7cddfSDavid du Colombier   {{0, 0}, {0, 0}}, gx_no_color_index, gx_no_color_index, gx_no_color_index
1177dd7cddfSDavid du Colombier struct gx_device_bbox_s {
1187dd7cddfSDavid du Colombier     gx_device_bbox_common;
1197dd7cddfSDavid du Colombier };
1207dd7cddfSDavid du Colombier 
1217dd7cddfSDavid du Colombier extern_st(st_device_bbox);
1227dd7cddfSDavid du Colombier #define public_st_device_bbox()	/* in gdevbbox.c */\
1237dd7cddfSDavid du Colombier   gs_public_st_suffix_add1_final(st_device_bbox, gx_device_bbox,\
1247dd7cddfSDavid du Colombier     "gx_device_bbox", device_bbox_enum_ptrs, device_bbox_reloc_ptrs,\
1257dd7cddfSDavid du Colombier     gx_device_finalize, st_device_forward, box_proc_data)
1267dd7cddfSDavid du Colombier 
1277dd7cddfSDavid du Colombier /* Initialize a bounding box device. */
128*593dc095SDavid du Colombier void gx_device_bbox_init(gx_device_bbox * dev, gx_device * target, gs_memory_t *mem);
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier /* Set whether a bounding box device propagates open/close to its target. */
131*593dc095SDavid du Colombier void gx_device_bbox_fwd_open_close(gx_device_bbox * dev,
132*593dc095SDavid du Colombier 				   bool forward_open_close);
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier /* Set whether a bounding box device considers white to be opaque. */
135*593dc095SDavid du Colombier void gx_device_bbox_set_white_opaque(gx_device_bbox *dev,
136*593dc095SDavid du Colombier 				     bool white_is_opaque);
1377dd7cddfSDavid du Colombier 
1387dd7cddfSDavid du Colombier /* Read back the bounding box in 1/72" units. */
139*593dc095SDavid du Colombier void gx_device_bbox_bbox(gx_device_bbox * dev, gs_rect * pbbox);
1407dd7cddfSDavid du Colombier 
1417dd7cddfSDavid du Colombier /* Release a bounding box device. */
142*593dc095SDavid du Colombier void gx_device_bbox_release(gx_device_bbox *dev);
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier #endif /* gdevbbox_INCLUDED */
145