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