/* Copyright (C) 1996, 1997, 1998, 1999 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gdevbbox.h,v 1.2.6.1.2.1 2003/01/17 00:49:00 giles Exp $ */ /* Definitions and interface for bbox (bounding box accumulator) device */ /* Requires gxdevice.h */ #ifndef gdevbbox_INCLUDED # define gdevbbox_INCLUDED /* * This device keeps track of the per-page bounding box, and also optionally * forwards all drawing commands to a target. It can be used either as a * free-standing device or as a component (e.g., by the EPS writer). * * One way to use a bounding box device is simply to include bbox.dev in the * value of DEVICE_DEVSn in the makefile. This produces a free-standing * device named 'bbox' that can be selected in the usual way (-sDEVICE=bbox) * and that prints out the bounding box at each showpage or copypage without * doing any drawing. * * The other way to use a bounding box device is from C code as a component * in a device pipeline. To set up a bounding box device that doesn't do * any drawing: * gx_device_bbox *bdev = * gs_alloc_struct_immovable(some_memory, * gx_device_bbox, &st_device_bbox, * "some identifying string for debugging"); * gx_device_bbox_init(bdev, NULL); * Non-drawing bounding box devices have an "infinite" page size. * * To set up a bounding box device that draws to another device tdev: * gx_device_bbox *bdev = * gs_alloc_struct_immovable(some_memory, * gx_device_bbox, &st_device_bbox, * "some identifying string for debugging"); * gx_device_bbox_init(bdev, tdev); * Bounding box devices that draw to a real device appear to have the * same page size as that device. * * To intercept the end-of-page to call a routine eop of your own, after * setting up the device: * dev_proc_output_page(eop); -- declare a prototype for eop * ... * set_dev_proc(bdev, output_page, eop); * ... * int eop(gx_device *dev, int num_copies, int flush) * { gs_rect bbox; * gx_device_bbox_bbox((gx_device_bbox *)dev, &bbox); * << do whatever you want >> * return gx_forward_output_page(dev, num_copies, flush); * } * * Note that bounding box devices, unlike almost all other forwarding * devices, conditionally propagate the open_device and close_device * calls to their target. By default, they do propagate these calls: * use gx_device_bbox_fwd_open_close to change this if you want. */ /* * Define virtual procedures for managing the accumulated bounding box. * These may be redefined by subclasses, and are also used for compositors. */ typedef struct gx_device_bbox_procs_s { #define dev_bbox_proc_init_box(proc)\ bool proc(P1(void *proc_data)) dev_bbox_proc_init_box((*init_box)); #define dev_bbox_proc_get_box(proc)\ void proc(P2(const void *proc_data, gs_fixed_rect *pbox)) dev_bbox_proc_get_box((*get_box)); #define dev_bbox_proc_add_rect(proc)\ void proc(P5(void *proc_data, fixed x0, fixed y0, fixed x1, fixed y1)) dev_bbox_proc_add_rect((*add_rect)); #define dev_bbox_proc_in_rect(proc)\ bool proc(P2(const void *proc_data, const gs_fixed_rect *pbox)) dev_bbox_proc_in_rect((*in_rect)); } gx_device_bbox_procs_t; /* Default implementations */ dev_bbox_proc_init_box(bbox_default_init_box); dev_bbox_proc_get_box(bbox_default_get_box); dev_bbox_proc_add_rect(bbox_default_add_rect); dev_bbox_proc_in_rect(bbox_default_in_rect); #define gx_device_bbox_common\ gx_device_forward_common;\ bool free_standing;\ bool forward_open_close;\ gx_device_bbox_procs_t box_procs;\ void *box_proc_data;\ bool white_is_opaque;\ /* The following are updated dynamically. */\ gs_fixed_rect bbox;\ gx_color_index black, white;\ gx_color_index transparent /* white or gx_no_color_index */ typedef struct gx_device_bbox_s gx_device_bbox; #define gx_device_bbox_common_initial(fs, foc, wio)\ 0 /* target */,\ fs, foc, {0}, 0, wio,\ {{0, 0}, {0, 0}}, gx_no_color_index, gx_no_color_index, gx_no_color_index struct gx_device_bbox_s { gx_device_bbox_common; }; extern_st(st_device_bbox); #define public_st_device_bbox() /* in gdevbbox.c */\ gs_public_st_suffix_add1_final(st_device_bbox, gx_device_bbox,\ "gx_device_bbox", device_bbox_enum_ptrs, device_bbox_reloc_ptrs,\ gx_device_finalize, st_device_forward, box_proc_data) /* Initialize a bounding box device. */ void gx_device_bbox_init(P2(gx_device_bbox * dev, gx_device * target)); /* Set whether a bounding box device propagates open/close to its target. */ void gx_device_bbox_fwd_open_close(P2(gx_device_bbox * dev, bool forward_open_close)); /* Set whether a bounding box device considers white to be opaque. */ void gx_device_bbox_set_white_opaque(P2(gx_device_bbox *dev, bool white_is_opaque)); /* Read back the bounding box in 1/72" units. */ void gx_device_bbox_bbox(P2(gx_device_bbox * dev, gs_rect * pbbox)); /* Release a bounding box device. */ void gx_device_bbox_release(P1(gx_device_bbox *dev)); #endif /* gdevbbox_INCLUDED */