xref: /plan9/sys/src/cmd/gs/src/zcssepr.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: zcssepr.c,v 1.16 2004/08/19 19:33:09 stefan Exp $ */
18 /* Separation color space support */
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "oper.h"
22 #include "gsstruct.h"
23 #include "gscolor.h"
24 #include "gsmatrix.h"		/* for gxcolor2.h */
25 #include "gxcspace.h"
26 #include "gxfixed.h"		/* ditto */
27 #include "gxcolor2.h"
28 #include "estack.h"
29 #include "ialloc.h"
30 #include "icsmap.h"
31 #include "ifunc.h"
32 #include "igstate.h"
33 #include "iname.h"
34 #include "ivmspace.h"
35 #include "store.h"
36 #include "gscsepr.h"
37 #include "gscdevn.h"
38 #include "gxcdevn.h"
39 #include "zht2.h"
40 
41 /* Imported from gscsepr.c */
42 extern const gs_color_space_type gs_color_space_type_Separation;
43 /* Imported from gscdevn.c */
44 extern const gs_color_space_type gs_color_space_type_DeviceN;
45 
46 /*
47  * Adobe first created the separation colorspace type and then later created
48  * the DeviceN colorspace.  Logically the separation colorspace is the same
49  * as a DeviceN colorspace with a single component, except for the /None and
50  * /All parameter values.  We treat the separation colorspace as a DeviceN
51  * colorspace except for the /All case.
52  */
53 
54 /* <array> .setseparationspace - */
55 /* The current color space is the alternate space for the separation space. */
56 private int
zsetseparationspace(i_ctx_t * i_ctx_p)57 zsetseparationspace(i_ctx_t *i_ctx_p)
58 {
59     os_ptr op = osp;
60     const ref *pcsa;
61     gs_color_space cs;
62     const gs_color_space * pacs;
63     ref_colorspace cspace_old;
64     ref sname, name_none, name_all;
65     gs_device_n_map *pmap = NULL;
66     gs_function_t *pfn = NULL;
67     separation_type sep_type;
68     int code;
69     const gs_memory_t * mem = imemory;
70 
71     /* Verify that we have an array as our input parameter */
72     check_read_type(*op, t_array);
73     if (r_size(op) != 4)
74 	return_error(e_rangecheck);
75 
76     /* The alternate color space has been selected as the current color space */
77     pacs = gs_currentcolorspace(igs);
78     cs = *pacs;
79     if (!cs.type->can_be_alt_space)
80 	return_error(e_rangecheck);
81 
82     /*
83      * pcsa is a pointer to element 1 (2nd element)  in the Separation colorspace
84      * description array.  Thus pcsa[2] is element #3 (4th element) which is the
85      * tint transform.
86      */
87     pcsa = op->value.const_refs + 1;
88     sname = *pcsa;
89     switch (r_type(&sname)) {
90 	default:
91 	    return_error(e_typecheck);
92 	case t_string:
93 	    code = name_from_string(mem, &sname, &sname);
94 	    if (code < 0)
95 		return code;
96 	    /* falls through */
97 	case t_name:
98 	    break;
99     }
100 
101     if ((code = name_ref(mem, (const byte *)"All", 3, &name_all, 0)) < 0)
102 	return code;
103     if ((code = name_ref(mem, (const byte *)"None", 4, &name_none, 0)) < 0)
104 	return code;
105     sep_type = ( name_eq(&sname, &name_all) ? SEP_ALL :
106 	         name_eq(&sname, &name_none) ? SEP_NONE : SEP_OTHER);
107 
108     /* Check tint transform procedure. */
109     /* See comment above about psca */
110     check_proc(pcsa[2]);
111     pfn = ref_function(pcsa + 2);
112     if (pfn == NULL)
113 	return_error(e_rangecheck);
114 
115     cspace_old = istate->colorspace;
116     /* See zcsindex.c for why we use memmove here. */
117     memmove(&cs.params.separation.alt_space, &cs,
118 	        sizeof(cs.params.separation.alt_space));
119     /* Now set the current color space as Separation */
120     code = gs_build_Separation(&cs, pacs, imemory);
121     if (code < 0)
122 	return code;
123     pmap = cs.params.separation.map;
124     gs_cspace_init(&cs, &gs_color_space_type_Separation, imemory, false);
125     cs.params.separation.sep_type = sep_type;
126     cs.params.separation.sep_name = name_index(mem, &sname);
127     cs.params.separation.get_colorname_string = gs_get_colorname_string;
128     istate->colorspace.procs.special.separation.layer_name = pcsa[0];
129     istate->colorspace.procs.special.separation.tint_transform = pcsa[2];
130     if (code >= 0)
131         code = gs_cspace_set_sepr_function(&cs, pfn);
132     if (code >= 0)
133 	code = gs_setcolorspace(igs, &cs);
134     if (code < 0) {
135 	istate->colorspace = cspace_old;
136 	ifree_object(pmap, ".setseparationspace(pmap)");
137 	return code;
138     }
139     rc_decrement(pmap, ".setseparationspace(pmap)");  /* build sets rc = 1 */
140     pop(1);
141     return 0;
142 }
143 
144 /* - currentoverprint <bool> */
145 private int
zcurrentoverprint(i_ctx_t * i_ctx_p)146 zcurrentoverprint(i_ctx_t *i_ctx_p)
147 {
148     os_ptr op = osp;
149 
150     push(1);
151     make_bool(op, gs_currentoverprint(igs));
152     return 0;
153 }
154 
155 /* <bool> setoverprint - */
156 private int
zsetoverprint(i_ctx_t * i_ctx_p)157 zsetoverprint(i_ctx_t *i_ctx_p)
158 {
159     os_ptr op = osp;
160 
161     check_type(*op, t_boolean);
162     gs_setoverprint(igs, op->value.boolval);
163     pop(1);
164     return 0;
165 }
166 
167 /* - .currentoverprintmode <int> */
168 private int
zcurrentoverprintmode(i_ctx_t * i_ctx_p)169 zcurrentoverprintmode(i_ctx_t *i_ctx_p)
170 {
171     os_ptr op = osp;
172 
173     push(1);
174     make_int(op, gs_currentoverprintmode(igs));
175     return 0;
176 }
177 
178 /* <int> .setoverprintmode - */
179 private int
zsetoverprintmode(i_ctx_t * i_ctx_p)180 zsetoverprintmode(i_ctx_t *i_ctx_p)
181 {
182     os_ptr op = osp;
183     int param;
184     int code = int_param(op, max_int, &param);
185 
186     if (code < 0 || (code = gs_setoverprintmode(igs, param)) < 0)
187 	return code;
188     pop(1);
189     return 0;
190 }
191 
192 /* ------ Initialization procedure ------ */
193 
194 const op_def zcssepr_l2_op_defs[] =
195 {
196     op_def_begin_level2(),
197     {"0currentoverprint", zcurrentoverprint},
198     {"0.currentoverprintmode", zcurrentoverprintmode},
199     {"1setoverprint", zsetoverprint},
200     {"1.setoverprintmode", zsetoverprintmode},
201     {"1.setseparationspace", zsetseparationspace},
202     op_def_end(0)
203 };
204