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