xref: /plan9/sys/src/cmd/gs/src/gsdfilt.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /*
2   Copyright (C) 2001 artofcode LLC.
3 
4   This software is provided AS-IS with no warranty, either express or
5   implied.
6 
7   This software is distributed under license and may not be copied,
8   modified or distributed except as expressly authorized under the terms
9   of the license contained in the file LICENSE in this distribution.
10 
11   For more information about licensing, please refer to
12   http://www.ghostscript.com/licensing/. For information on
13   commercial licensing, go to http://www.artifex.com/licensing/ or
14   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
15   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
16 
17   Author: Raph Levien <raph@artofcode.com>
18 */
19 /* $Id: gsdfilt.c,v 1.9 2004/03/11 14:50:50 igor Exp $ */
20 /* Functions for managing the device filter stack */
21 
22 #include "ctype_.h"
23 #include "memory_.h"		/* for memchr, memcpy */
24 #include "string_.h"
25 #include "gx.h"
26 #include "gp.h"
27 #include "gscdefs.h"		/* for gs_lib_device_list */
28 #include "gserrors.h"
29 #include "gsfname.h"
30 #include "gsstruct.h"
31 #include "gspath.h"		/* gs_initclip prototype */
32 #include "gspaint.h"		/* gs_erasepage prototype */
33 #include "gsmatrix.h"		/* for gscoord.h */
34 #include "gscoord.h"		/* for gs_initmatrix */
35 #include "gzstate.h"
36 #include "gxcmap.h"
37 #include "gxdevice.h"
38 #include "gxdevmem.h"
39 #include "gxiodev.h"
40 
41 #include "gsdfilt.h"
42 
43 gs_private_st_ptrs3(st_gs_device_filter_stack, gs_device_filter_stack_t,
44 		    "gs_device_filter_stack",
45 		    gs_device_filter_stack_enum_ptrs,
46 		    gs_device_filter_stack_reloc_ptrs,
47 		    next, df, next_device);
48 
49 gs_public_st_simple(st_gs_device_filter, gs_device_filter_t,
50 		    "gs_device_filter");
51 
52 int
gs_push_device_filter(gs_memory_t * mem,gs_state * pgs,gs_device_filter_t * df)53 gs_push_device_filter(gs_memory_t *mem, gs_state *pgs, gs_device_filter_t *df)
54 {
55     gs_device_filter_stack_t *dfs;
56     gx_device *new_dev = NULL;
57     int code;
58 
59     dfs = gs_alloc_struct(mem, gs_device_filter_stack_t,
60 			  &st_gs_device_filter_stack, "gs_push_device_filter");
61     if (dfs == NULL)
62 	return_error(gs_error_VMerror);
63     rc_increment(pgs->device);
64     dfs->next_device = pgs->device;
65     code = df->push(df, mem, pgs, &new_dev, pgs->device);
66     if (code < 0) {
67 	gs_free_object(mem, dfs, "gs_push_device_filter");
68 	return code;
69     }
70     dfs->next = pgs->dfilter_stack;
71     pgs->dfilter_stack = dfs;
72     dfs->df = df;
73     rc_init(dfs, mem, 1);
74     gs_setdevice_no_init(pgs, new_dev);
75     rc_decrement_only(new_dev, "gs_push_device_filter");
76     return code;
77 }
78 
79 int
gs_pop_device_filter(gs_memory_t * mem,gs_state * pgs)80 gs_pop_device_filter(gs_memory_t *mem, gs_state *pgs)
81 {
82     gs_device_filter_stack_t *dfs_tos = pgs->dfilter_stack;
83     gx_device *tos_device = pgs->device;
84     gs_device_filter_t *df;
85     int code;
86 
87     if (dfs_tos == NULL)
88 	return_error(gs_error_rangecheck);
89     df = dfs_tos->df;
90     pgs->dfilter_stack = dfs_tos->next;
91     code = df->prepop(df, mem, pgs, tos_device);
92     rc_increment(tos_device);
93     gs_setdevice_no_init(pgs, dfs_tos->next_device);
94     rc_decrement_only(dfs_tos->next_device, "gs_pop_device_filter");
95     dfs_tos->df = NULL;
96     rc_decrement_only(dfs_tos, "gs_pop_device_filter");
97     code = df->postpop(df, mem, pgs, tos_device);
98     rc_decrement_only(tos_device, "gs_pop_device_filter");
99     return code;
100 }
101 
102 int
gs_clear_device_filters(gs_memory_t * mem,gs_state * pgs)103 gs_clear_device_filters(gs_memory_t *mem, gs_state *pgs)
104 {
105     int code;
106 
107     while (pgs->dfilter_stack != NULL) {
108 	if ((code = gs_pop_device_filter(mem, pgs)) < 0)
109 	    return code;
110     }
111     return 0;
112 }
113