summaryrefslogtreecommitdiff
path: root/gs/base/gsdfilt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/base/gsdfilt.c')
-rw-r--r--gs/base/gsdfilt.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/gs/base/gsdfilt.c b/gs/base/gsdfilt.c
new file mode 100644
index 000000000..ff5e7d3d5
--- /dev/null
+++ b/gs/base/gsdfilt.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 2001-2006 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 that
+ license. 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.
+*/
+/* $Id$ */
+/* Functions for managing the device filter stack */
+
+#include "ctype_.h"
+#include "memory_.h" /* for memchr, memcpy */
+#include "string_.h"
+#include "gx.h"
+#include "gp.h"
+#include "gscdefs.h" /* for gs_lib_device_list */
+#include "gserrors.h"
+#include "gsfname.h"
+#include "gsstruct.h"
+#include "gspath.h" /* gs_initclip prototype */
+#include "gspaint.h" /* gs_erasepage prototype */
+#include "gsmatrix.h" /* for gscoord.h */
+#include "gscoord.h" /* for gs_initmatrix */
+#include "gzstate.h"
+#include "gxcmap.h"
+#include "gxdevice.h"
+#include "gxdevmem.h"
+#include "gxiodev.h"
+
+#include "gsdfilt.h"
+
+gs_private_st_ptrs3(st_gs_device_filter_stack, gs_device_filter_stack_t,
+ "gs_device_filter_stack",
+ gs_device_filter_stack_enum_ptrs,
+ gs_device_filter_stack_reloc_ptrs,
+ next, df, next_device);
+
+gs_public_st_simple(st_gs_device_filter, gs_device_filter_t,
+ "gs_device_filter");
+
+int
+gs_push_device_filter(gs_memory_t *mem, gs_state *pgs, gs_device_filter_t *df)
+{
+ gs_device_filter_stack_t *dfs;
+ gx_device *new_dev = NULL;
+ int code;
+
+ dfs = gs_alloc_struct(mem, gs_device_filter_stack_t,
+ &st_gs_device_filter_stack, "gs_push_device_filter");
+ if (dfs == NULL)
+ return_error(gs_error_VMerror);
+ rc_increment(pgs->device);
+ dfs->next_device = pgs->device;
+ code = df->push(df, mem, pgs, &new_dev, pgs->device);
+ if (code < 0) {
+ gs_free_object(mem, dfs, "gs_push_device_filter");
+ return code;
+ }
+ dfs->next = pgs->dfilter_stack;
+ pgs->dfilter_stack = dfs;
+ dfs->df = df;
+ rc_init(dfs, mem, 1);
+ gs_setdevice_no_init(pgs, new_dev);
+ rc_decrement_only(new_dev, "gs_push_device_filter");
+ return code;
+}
+
+int
+gs_pop_device_filter(gs_memory_t *mem, gs_state *pgs)
+{
+ gs_device_filter_stack_t *dfs_tos = pgs->dfilter_stack;
+ gx_device *tos_device = pgs->device;
+ gs_device_filter_t *df;
+ int code;
+
+ if (dfs_tos == NULL)
+ return_error(gs_error_rangecheck);
+ df = dfs_tos->df;
+ pgs->dfilter_stack = dfs_tos->next;
+ code = df->prepop(df, mem, pgs, tos_device);
+ rc_increment(tos_device);
+ gs_setdevice_no_init(pgs, dfs_tos->next_device);
+ rc_decrement_only(dfs_tos->next_device, "gs_pop_device_filter");
+ dfs_tos->df = NULL;
+ rc_decrement_only(dfs_tos, "gs_pop_device_filter");
+ code = df->postpop(df, mem, pgs, tos_device);
+ rc_decrement_only(tos_device, "gs_pop_device_filter");
+ return code;
+}
+
+int
+gs_clear_device_filters(gs_memory_t *mem, gs_state *pgs)
+{
+ int code;
+
+ while (pgs->dfilter_stack != NULL) {
+ if ((code = gs_pop_device_filter(mem, pgs)) < 0)
+ return code;
+ }
+ return 0;
+}