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, ¶m);
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