summaryrefslogtreecommitdiff
path: root/base/gdevbbox.h
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevbbox.h')
-rw-r--r--base/gdevbbox.h142
1 files changed, 142 insertions, 0 deletions
diff --git a/base/gdevbbox.h b/base/gdevbbox.h
new file mode 100644
index 000000000..6c956d14e
--- /dev/null
+++ b/base/gdevbbox.h
@@ -0,0 +1,142 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* 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(void *proc_data)
+ dev_bbox_proc_init_box((*init_box));
+
+#define dev_bbox_proc_get_box(proc)\
+ void proc(const void *proc_data, gs_fixed_rect *pbox)
+ dev_bbox_proc_get_box((*get_box));
+
+#define dev_bbox_proc_add_rect(proc)\
+ void proc(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(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(gx_device_bbox * dev, gx_device * target, gs_memory_t *mem);
+
+/* Set whether a bounding box device propagates open/close to its target. */
+void gx_device_bbox_fwd_open_close(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(gx_device_bbox *dev,
+ bool white_is_opaque);
+
+/* Read back the bounding box in 1/72" units. */
+void gx_device_bbox_bbox(gx_device_bbox * dev, gs_rect * pbbox);
+
+/* Release a bounding box device. */
+void gx_device_bbox_release(gx_device_bbox *dev);
+
+#endif /* gdevbbox_INCLUDED */