xref: /plan9/sys/src/cmd/gs/src/gdevbbox.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 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: gdevbbox.h,v 1.6 2004/09/16 08:03:56 igor Exp $ */
18 /* Definitions and interface for bbox (bounding box accumulator) device */
19 /* Requires gxdevice.h */
20 
21 #ifndef gdevbbox_INCLUDED
22 #  define gdevbbox_INCLUDED
23 
24 /*
25  * This device keeps track of the per-page bounding box, and also optionally
26  * forwards all drawing commands to a target.  It can be used either as a
27  * free-standing device or as a component (e.g., by the EPS writer).
28  *
29  * One way to use a bounding box device is simply to include bbox.dev in the
30  * value of DEVICE_DEVSn in the makefile.  This produces a free-standing
31  * device named 'bbox' that can be selected in the usual way (-sDEVICE=bbox)
32  * and that prints out the bounding box at each showpage or copypage without
33  * doing any drawing.
34  *
35  * The other way to use a bounding box device is from C code as a component
36  * in a device pipeline.  To set up a bounding box device that doesn't do
37  * any drawing:
38  *      gx_device_bbox *bdev =
39  *        gs_alloc_struct_immovable(some_memory,
40  *                                  gx_device_bbox, &st_device_bbox,
41  *                                  "some identifying string for debugging");
42  *      gx_device_bbox_init(bdev, NULL);
43  * Non-drawing bounding box devices have an "infinite" page size.
44  *
45  * To set up a bounding box device that draws to another device tdev:
46  *      gx_device_bbox *bdev =
47  *        gs_alloc_struct_immovable(some_memory,
48  *                                  gx_device_bbox, &st_device_bbox,
49  *                                  "some identifying string for debugging");
50  *      gx_device_bbox_init(bdev, tdev);
51  * Bounding box devices that draw to a real device appear to have the
52  * same page size as that device.
53  *
54  * To intercept the end-of-page to call a routine eop of your own, after
55  * setting up the device:
56  *      dev_proc_output_page(eop);      -- declare a prototype for eop
57  *      ...
58  *      set_dev_proc(bdev, output_page, eop);
59  *      ...
60  *      int eop(gx_device *dev, int num_copies, int flush)
61  *      {       gs_rect bbox;
62  *              gx_device_bbox_bbox((gx_device_bbox *)dev, &bbox);
63  *              << do whatever you want >>
64  *              return gx_forward_output_page(dev, num_copies, flush);
65  *      }
66  *
67  * Note that bounding box devices, unlike almost all other forwarding
68  * devices, conditionally propagate the open_device and close_device
69  * calls to their target.  By default, they do propagate these calls:
70  * use gx_device_bbox_fwd_open_close to change this if you want.
71  */
72 /*
73  * Define virtual procedures for managing the accumulated bounding box.
74  * These may be redefined by subclasses, and are also used for compositors.
75  */
76 typedef struct gx_device_bbox_procs_s {
77 
78 #define dev_bbox_proc_init_box(proc)\
79   bool proc(void *proc_data)
80     dev_bbox_proc_init_box((*init_box));
81 
82 #define dev_bbox_proc_get_box(proc)\
83   void proc(const void *proc_data, gs_fixed_rect *pbox)
84     dev_bbox_proc_get_box((*get_box));
85 
86 #define dev_bbox_proc_add_rect(proc)\
87   void proc(void *proc_data, fixed x0, fixed y0, fixed x1, fixed y1)
88     dev_bbox_proc_add_rect((*add_rect));
89 
90 #define dev_bbox_proc_in_rect(proc)\
91   bool proc(const void *proc_data, const gs_fixed_rect *pbox)
92     dev_bbox_proc_in_rect((*in_rect));
93 
94 } gx_device_bbox_procs_t;
95 /* Default implementations */
96 dev_bbox_proc_init_box(bbox_default_init_box);
97 dev_bbox_proc_get_box(bbox_default_get_box);
98 dev_bbox_proc_add_rect(bbox_default_add_rect);
99 dev_bbox_proc_in_rect(bbox_default_in_rect);
100 
101 #define gx_device_bbox_common\
102 	gx_device_forward_common;\
103 	bool free_standing;\
104 	bool forward_open_close;\
105 	gx_device_bbox_procs_t box_procs;\
106 	void *box_proc_data;\
107 	bool white_is_opaque;\
108 	/* The following are updated dynamically. */\
109 	gs_fixed_rect bbox;\
110 	gx_color_index black, white;\
111 	gx_color_index transparent /* white or gx_no_color_index */
112 typedef struct gx_device_bbox_s gx_device_bbox;
113 #define gx_device_bbox_common_initial(fs, foc, wio)\
114   0 /* target */,\
115   fs, foc, {0}, 0, wio,\
116   {{0, 0}, {0, 0}}, gx_no_color_index, gx_no_color_index, gx_no_color_index
117 struct gx_device_bbox_s {
118     gx_device_bbox_common;
119 };
120 
121 extern_st(st_device_bbox);
122 #define public_st_device_bbox()	/* in gdevbbox.c */\
123   gs_public_st_suffix_add1_final(st_device_bbox, gx_device_bbox,\
124     "gx_device_bbox", device_bbox_enum_ptrs, device_bbox_reloc_ptrs,\
125     gx_device_finalize, st_device_forward, box_proc_data)
126 
127 /* Initialize a bounding box device. */
128 void gx_device_bbox_init(gx_device_bbox * dev, gx_device * target, gs_memory_t *mem);
129 
130 /* Set whether a bounding box device propagates open/close to its target. */
131 void gx_device_bbox_fwd_open_close(gx_device_bbox * dev,
132 				   bool forward_open_close);
133 
134 /* Set whether a bounding box device considers white to be opaque. */
135 void gx_device_bbox_set_white_opaque(gx_device_bbox *dev,
136 				     bool white_is_opaque);
137 
138 /* Read back the bounding box in 1/72" units. */
139 void gx_device_bbox_bbox(gx_device_bbox * dev, gs_rect * pbbox);
140 
141 /* Release a bounding box device. */
142 void gx_device_bbox_release(gx_device_bbox *dev);
143 
144 #endif /* gdevbbox_INCLUDED */
145