2 |
- |
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: gscsepr.c,v 1.27 2004/08/04 19:36:12 stefan Exp $ */
|
|
|
18 |
/* Separation color space and operation definition */
|
|
|
19 |
#include "memory_.h"
|
|
|
20 |
#include "gx.h"
|
|
|
21 |
#include "gserrors.h"
|
|
|
22 |
#include "gsfunc.h"
|
|
|
23 |
#include "gsrefct.h"
|
|
|
24 |
#include "gsmatrix.h" /* for gscolor2.h */
|
|
|
25 |
#include "gscsepr.h"
|
|
|
26 |
#include "gxcspace.h"
|
|
|
27 |
#include "gxfixed.h" /* for gxcolor2.h */
|
|
|
28 |
#include "gxcolor2.h" /* for gs_indexed_map */
|
|
|
29 |
#include "gzstate.h" /* for pgs->overprint */
|
|
|
30 |
#include "gscdevn.h" /* for alloc_device_n_map */
|
|
|
31 |
#include "gxcdevn.h" /* for gs_device_n_map_s */
|
|
|
32 |
#include "gxcmap.h"
|
|
|
33 |
#include "gxdevcli.h"
|
|
|
34 |
#include "gsovrc.h"
|
|
|
35 |
#include "stream.h"
|
|
|
36 |
|
|
|
37 |
/* ---------------- Color space ---------------- */
|
|
|
38 |
|
|
|
39 |
gs_private_st_composite(st_color_space_Separation, gs_paint_color_space,
|
|
|
40 |
"gs_color_space_Separation",
|
|
|
41 |
cs_Separation_enum_ptrs, cs_Separation_reloc_ptrs);
|
|
|
42 |
|
|
|
43 |
/* Define the Separation color space type. */
|
|
|
44 |
private cs_proc_base_space(gx_alt_space_Separation);
|
|
|
45 |
private cs_proc_init_color(gx_init_Separation);
|
|
|
46 |
private cs_proc_concrete_space(gx_concrete_space_Separation);
|
|
|
47 |
private cs_proc_concretize_color(gx_concretize_Separation);
|
|
|
48 |
private cs_proc_remap_concrete_color(gx_remap_concrete_Separation);
|
|
|
49 |
private cs_proc_remap_color(gx_remap_Separation);
|
|
|
50 |
private cs_proc_install_cspace(gx_install_Separation);
|
|
|
51 |
private cs_proc_set_overprint(gx_set_overprint_Separation);
|
|
|
52 |
private cs_proc_adjust_cspace_count(gx_adjust_cspace_Separation);
|
|
|
53 |
private cs_proc_serialize(gx_serialize_Separation);
|
|
|
54 |
const gs_color_space_type gs_color_space_type_Separation = {
|
|
|
55 |
gs_color_space_index_Separation, true, false,
|
|
|
56 |
&st_color_space_Separation, gx_num_components_1,
|
|
|
57 |
gx_alt_space_Separation,
|
|
|
58 |
gx_init_Separation, gx_restrict01_paint_1,
|
|
|
59 |
gx_concrete_space_Separation,
|
|
|
60 |
gx_concretize_Separation, gx_remap_concrete_Separation,
|
|
|
61 |
gx_remap_Separation, gx_install_Separation,
|
|
|
62 |
gx_set_overprint_Separation,
|
|
|
63 |
gx_adjust_cspace_Separation, gx_no_adjust_color_count,
|
|
|
64 |
gx_serialize_Separation,
|
|
|
65 |
gx_cspace_is_linear_default
|
|
|
66 |
};
|
|
|
67 |
|
|
|
68 |
/* GC procedures */
|
|
|
69 |
|
|
|
70 |
private
|
|
|
71 |
ENUM_PTRS_WITH(cs_Separation_enum_ptrs, gs_color_space *pcs)
|
|
|
72 |
{
|
|
|
73 |
return ENUM_USING(*pcs->params.separation.alt_space.type->stype,
|
|
|
74 |
&pcs->params.separation.alt_space,
|
|
|
75 |
sizeof(pcs->params.separation.alt_space), index - 1);
|
|
|
76 |
}
|
|
|
77 |
ENUM_PTR(0, gs_color_space, params.separation.map);
|
|
|
78 |
ENUM_PTRS_END
|
|
|
79 |
private RELOC_PTRS_WITH(cs_Separation_reloc_ptrs, gs_color_space *pcs)
|
|
|
80 |
{
|
|
|
81 |
RELOC_PTR(gs_color_space, params.separation.map);
|
|
|
82 |
RELOC_USING(*pcs->params.separation.alt_space.type->stype,
|
|
|
83 |
&pcs->params.separation.alt_space,
|
|
|
84 |
sizeof(gs_base_color_space));
|
|
|
85 |
}
|
|
|
86 |
RELOC_PTRS_END
|
|
|
87 |
|
|
|
88 |
/* Get the alternate space for a Separation space. */
|
|
|
89 |
private const gs_color_space *
|
|
|
90 |
gx_alt_space_Separation(const gs_color_space * pcs)
|
|
|
91 |
{
|
|
|
92 |
return pcs->params.separation.use_alt_cspace
|
|
|
93 |
? (const gs_color_space *)&(pcs->params.separation.alt_space)
|
|
|
94 |
: NULL;
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
/* Get the concrete space for a Separation space. */
|
|
|
98 |
private const gs_color_space *
|
|
|
99 |
gx_concrete_space_Separation(const gs_color_space * pcs,
|
|
|
100 |
const gs_imager_state * pis)
|
|
|
101 |
{
|
|
|
102 |
#ifdef DEBUG
|
|
|
103 |
/*
|
|
|
104 |
* Verify that the color space and imager state info match.
|
|
|
105 |
*/
|
|
|
106 |
if (pcs->id != pis->color_component_map.cspace_id)
|
|
|
107 |
dprintf("gx_concretze_space_Separation: color space id mismatch");
|
|
|
108 |
#endif
|
|
|
109 |
|
|
|
110 |
/*
|
|
|
111 |
* Check if we are using the alternate color space.
|
|
|
112 |
*/
|
|
|
113 |
if (pis->color_component_map.use_alt_cspace) {
|
|
|
114 |
const gs_color_space *pacs =
|
|
|
115 |
(const gs_color_space *)&pcs->params.separation.alt_space;
|
|
|
116 |
|
|
|
117 |
return cs_concrete_space(pacs, pis);
|
|
|
118 |
}
|
|
|
119 |
/*
|
|
|
120 |
* Separation color spaces are concrete (when not using alt. color space).
|
|
|
121 |
*/
|
|
|
122 |
return pcs;
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
private int
|
|
|
126 |
check_Separation_component_name(const gs_color_space * pcs, gs_state * pgs);
|
|
|
127 |
|
|
|
128 |
/* Install a Separation color space. */
|
|
|
129 |
private int
|
|
|
130 |
gx_install_Separation(const gs_color_space * pcs, gs_state * pgs)
|
|
|
131 |
{
|
|
|
132 |
int code = check_Separation_component_name(pcs, pgs);
|
|
|
133 |
|
|
|
134 |
if (code < 0)
|
|
|
135 |
return code;
|
|
|
136 |
pgs->color_space->params.separation.use_alt_cspace =
|
|
|
137 |
using_alt_color_space(pgs);
|
|
|
138 |
if (pgs->color_space->params.separation.use_alt_cspace)
|
|
|
139 |
code = (*pcs->params.separation.alt_space.type->install_cspace)
|
|
|
140 |
((const gs_color_space *) & pcs->params.separation.alt_space, pgs);
|
|
|
141 |
/*
|
|
|
142 |
* Give the device an opportunity to capture equivalent colors for any
|
|
|
143 |
* spot colors which might be present in the color space.
|
|
|
144 |
*/
|
|
|
145 |
if (code >= 0)
|
|
|
146 |
code = dev_proc(pgs->device, update_spot_equivalent_colors)
|
|
|
147 |
(pgs->device, pgs);
|
|
|
148 |
return code;
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
/* Set the overprint information appropriate to a separation color space */
|
|
|
152 |
private int
|
|
|
153 |
gx_set_overprint_Separation(const gs_color_space * pcs, gs_state * pgs)
|
|
|
154 |
{
|
|
|
155 |
gs_devicen_color_map * pcmap = &pgs->color_component_map;
|
|
|
156 |
|
|
|
157 |
if (pcmap->use_alt_cspace)
|
|
|
158 |
return gx_spot_colors_set_overprint(
|
|
|
159 |
(const gs_color_space *)&pcs->params.separation.alt_space,
|
|
|
160 |
pgs );
|
|
|
161 |
else {
|
|
|
162 |
gs_overprint_params_t params;
|
|
|
163 |
|
|
|
164 |
params.retain_any_comps = pgs->overprint &&
|
|
|
165 |
pcs->params.separation.sep_type != SEP_ALL;
|
|
|
166 |
if (params.retain_any_comps) {
|
|
|
167 |
params.retain_spot_comps = false;
|
|
|
168 |
params.drawn_comps = 0;
|
|
|
169 |
if (pcs->params.separation.sep_type != SEP_NONE) {
|
|
|
170 |
int mcomp = pcmap->color_map[0];
|
|
|
171 |
|
|
|
172 |
if (mcomp >= 0)
|
|
|
173 |
gs_overprint_set_drawn_comp( params.drawn_comps, mcomp);
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
|
|
|
177 |
pgs->effective_overprint_mode = 0;
|
|
|
178 |
return gs_state_update_overprint(pgs, ¶ms);
|
|
|
179 |
}
|
|
|
180 |
}
|
|
|
181 |
|
|
|
182 |
/* Adjust the reference count of a Separation color space. */
|
|
|
183 |
private void
|
|
|
184 |
gx_adjust_cspace_Separation(const gs_color_space * pcs, int delta)
|
|
|
185 |
{
|
|
|
186 |
rc_adjust_const(pcs->params.separation.map, delta,
|
|
|
187 |
"gx_adjust_Separation");
|
|
|
188 |
(*pcs->params.separation.alt_space.type->adjust_cspace_count)
|
|
|
189 |
((const gs_color_space *)&pcs->params.separation.alt_space, delta);
|
|
|
190 |
}
|
|
|
191 |
|
|
|
192 |
/* ------ Constructors/accessors ------ */
|
|
|
193 |
|
|
|
194 |
/*
|
|
|
195 |
* Build a separation color space.
|
|
|
196 |
*/
|
|
|
197 |
int
|
|
|
198 |
gs_build_Separation(
|
|
|
199 |
gs_color_space * pcspace,
|
|
|
200 |
const gs_color_space * palt_cspace,
|
|
|
201 |
gs_memory_t * pmem
|
|
|
202 |
)
|
|
|
203 |
{
|
|
|
204 |
gs_separation_params * pcssepr = &pcspace->params.separation;
|
|
|
205 |
int code;
|
|
|
206 |
|
|
|
207 |
if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space)
|
|
|
208 |
return_error(gs_error_rangecheck);
|
|
|
209 |
|
|
|
210 |
code = alloc_device_n_map(&pcssepr->map, pmem, "gs_cspace_build_Separation");
|
|
|
211 |
if (pcssepr->map == NULL) {
|
|
|
212 |
gs_free_object(pmem, pcspace, "gs_cspace_build_Separation");
|
|
|
213 |
return_error(gs_error_VMerror);
|
|
|
214 |
}
|
|
|
215 |
return 0;
|
|
|
216 |
}
|
|
|
217 |
|
|
|
218 |
/*
|
|
|
219 |
* Build a separation color space.
|
|
|
220 |
*
|
|
|
221 |
* The values array provided with separation color spaces is actually cached
|
|
|
222 |
* information, but filled in by the client. The alternative space is the
|
|
|
223 |
* color space in which the tint procedure will provide alternative colors.
|
|
|
224 |
*/
|
|
|
225 |
int
|
|
|
226 |
gs_cspace_build_Separation(
|
|
|
227 |
gs_color_space ** ppcspace,
|
|
|
228 |
gs_separation_name sname,
|
|
|
229 |
const gs_color_space * palt_cspace,
|
|
|
230 |
int cache_size,
|
|
|
231 |
gs_memory_t * pmem
|
|
|
232 |
)
|
|
|
233 |
{
|
|
|
234 |
gs_color_space *pcspace = NULL;
|
|
|
235 |
gs_separation_params *pcssepr = NULL;
|
|
|
236 |
int code;
|
|
|
237 |
|
|
|
238 |
if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space)
|
|
|
239 |
return_error(gs_error_rangecheck);
|
|
|
240 |
|
|
|
241 |
code = gs_cspace_alloc(&pcspace, &gs_color_space_type_Separation, pmem);
|
|
|
242 |
if (code < 0)
|
|
|
243 |
return code;
|
|
|
244 |
|
|
|
245 |
code = gs_build_Separation(pcspace, palt_cspace, pmem);
|
|
|
246 |
if (code < 0) {
|
|
|
247 |
gs_free_object(pmem, pcspace, "gs_cspace_build_Separation");
|
|
|
248 |
return code;
|
|
|
249 |
}
|
|
|
250 |
pcssepr->sep_name = sname;
|
|
|
251 |
gs_cspace_init_from((gs_color_space *) & pcssepr->alt_space, palt_cspace);
|
|
|
252 |
*ppcspace = pcspace;
|
|
|
253 |
return 0;
|
|
|
254 |
}
|
|
|
255 |
|
|
|
256 |
#if 0 /* Unused; Unsupported by gx_serialize_device_n_map. */
|
|
|
257 |
/*
|
|
|
258 |
* Set the tint transformation procedure used by a Separation color space.
|
|
|
259 |
*/
|
|
|
260 |
int
|
|
|
261 |
gs_cspace_set_sepr_proc(gs_color_space * pcspace,
|
|
|
262 |
int (*proc)(const float *,
|
|
|
263 |
float *,
|
|
|
264 |
const gs_imager_state *,
|
|
|
265 |
void *
|
|
|
266 |
),
|
|
|
267 |
void *proc_data
|
|
|
268 |
)
|
|
|
269 |
{
|
|
|
270 |
gs_device_n_map *pimap;
|
|
|
271 |
|
|
|
272 |
if (gs_color_space_get_index(pcspace) != gs_color_space_index_Separation)
|
|
|
273 |
return_error(gs_error_rangecheck);
|
|
|
274 |
pimap = pcspace->params.separation.map;
|
|
|
275 |
pimap->tint_transform = proc;
|
|
|
276 |
pimap->tint_transform_data = proc_data;
|
|
|
277 |
pimap->cache_valid = false;
|
|
|
278 |
|
|
|
279 |
return 0;
|
|
|
280 |
}
|
|
|
281 |
#endif
|
|
|
282 |
|
|
|
283 |
/*
|
|
|
284 |
* Set the Separation tint transformation procedure to a Function.
|
|
|
285 |
*/
|
|
|
286 |
int
|
|
|
287 |
gs_cspace_set_sepr_function(const gs_color_space *pcspace, gs_function_t *pfn)
|
|
|
288 |
{
|
|
|
289 |
gs_device_n_map *pimap;
|
|
|
290 |
|
|
|
291 |
if (gs_color_space_get_index(pcspace) != gs_color_space_index_Separation ||
|
|
|
292 |
pfn->params.m != 1 || pfn->params.n !=
|
|
|
293 |
gs_color_space_num_components((const gs_color_space *)
|
|
|
294 |
&pcspace->params.separation.alt_space)
|
|
|
295 |
)
|
|
|
296 |
return_error(gs_error_rangecheck);
|
|
|
297 |
pimap = pcspace->params.separation.map;
|
|
|
298 |
pimap->tint_transform = map_devn_using_function;
|
|
|
299 |
pimap->tint_transform_data = pfn;
|
|
|
300 |
pimap->cache_valid = false;
|
|
|
301 |
return 0;
|
|
|
302 |
}
|
|
|
303 |
|
|
|
304 |
/*
|
|
|
305 |
* If the Separation tint transformation procedure is a Function,
|
|
|
306 |
* return the function object, otherwise return 0.
|
|
|
307 |
*/
|
|
|
308 |
gs_function_t *
|
|
|
309 |
gs_cspace_get_sepr_function(const gs_color_space *pcspace)
|
|
|
310 |
{
|
|
|
311 |
if (gs_color_space_get_index(pcspace) == gs_color_space_index_Separation &&
|
|
|
312 |
pcspace->params.separation.map->tint_transform ==
|
|
|
313 |
map_devn_using_function)
|
|
|
314 |
return pcspace->params.separation.map->tint_transform_data;
|
|
|
315 |
return 0;
|
|
|
316 |
}
|
|
|
317 |
|
|
|
318 |
/* ------ Internal procedures ------ */
|
|
|
319 |
|
|
|
320 |
/* Initialize a Separation color. */
|
|
|
321 |
private void
|
|
|
322 |
gx_init_Separation(gs_client_color * pcc, const gs_color_space * pcs)
|
|
|
323 |
{
|
|
|
324 |
pcc->paint.values[0] = 1.0;
|
|
|
325 |
}
|
|
|
326 |
|
|
|
327 |
/* Remap a Separation color. */
|
|
|
328 |
|
|
|
329 |
private int
|
|
|
330 |
gx_remap_Separation(const gs_client_color * pcc, const gs_color_space * pcs,
|
|
|
331 |
gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
|
|
|
332 |
gs_color_select_t select)
|
|
|
333 |
{
|
|
|
334 |
int code = 0;
|
|
|
335 |
|
|
|
336 |
if (pcs->params.separation.sep_type != SEP_NONE)
|
|
|
337 |
code = gx_default_remap_color(pcc, pcs, pdc, pis, dev, select);
|
|
|
338 |
else {
|
|
|
339 |
color_set_null(pdc);
|
|
|
340 |
}
|
|
|
341 |
/* Save original color space and color info into dev color */
|
|
|
342 |
pdc->ccolor.paint.values[0] = pcc->paint.values[0];
|
|
|
343 |
pdc->ccolor_valid = true;
|
|
|
344 |
return code;
|
|
|
345 |
}
|
|
|
346 |
|
|
|
347 |
private int
|
|
|
348 |
gx_concretize_Separation(const gs_client_color *pc, const gs_color_space *pcs,
|
|
|
349 |
frac *pconc, const gs_imager_state *pis)
|
|
|
350 |
{
|
|
|
351 |
float ftemp;
|
|
|
352 |
int code;
|
|
|
353 |
gs_client_color cc;
|
|
|
354 |
const gs_color_space *pacs =
|
|
|
355 |
(const gs_color_space *)&pcs->params.separation.alt_space;
|
|
|
356 |
|
|
|
357 |
if (pcs->params.separation.sep_type == SEP_OTHER &&
|
|
|
358 |
pcs->params.separation.use_alt_cspace) {
|
|
|
359 |
gs_device_n_map *map = pcs->params.separation.map;
|
|
|
360 |
|
|
|
361 |
/* Check the 1-element cache first. */
|
|
|
362 |
if (map->cache_valid && map->tint[0] == pc->paint.values[0]) {
|
|
|
363 |
int i, num_out = gs_color_space_num_components(pacs);
|
|
|
364 |
|
|
|
365 |
for (i = 0; i < num_out; ++i)
|
|
|
366 |
pconc[i] = map->conc[i];
|
|
|
367 |
return 0;
|
|
|
368 |
}
|
|
|
369 |
code = (*pcs->params.separation.map->tint_transform)
|
|
|
370 |
(pc->paint.values, &cc.paint.values[0],
|
|
|
371 |
pis, pcs->params.separation.map->tint_transform_data);
|
|
|
372 |
if (code < 0)
|
|
|
373 |
return code;
|
|
|
374 |
return cs_concretize_color(&cc, pacs, pconc, pis);
|
|
|
375 |
}
|
|
|
376 |
else {
|
|
|
377 |
pconc[0] = unit_frac(pc->paint.values[0], ftemp);
|
|
|
378 |
}
|
|
|
379 |
return 0;
|
|
|
380 |
}
|
|
|
381 |
|
|
|
382 |
private int
|
|
|
383 |
gx_remap_concrete_Separation(const frac * pconc, const gs_color_space * pcs,
|
|
|
384 |
gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
|
|
|
385 |
gs_color_select_t select)
|
|
|
386 |
{
|
|
|
387 |
#ifdef DEBUG
|
|
|
388 |
/*
|
|
|
389 |
* Verify that the color space and imager state info match.
|
|
|
390 |
*/
|
|
|
391 |
if (pcs->id != pis->color_component_map.cspace_id)
|
|
|
392 |
dprintf("gx_remap_concrete_Separation: color space id mismatch");
|
|
|
393 |
#endif
|
|
|
394 |
|
|
|
395 |
if (pis->color_component_map.use_alt_cspace) {
|
|
|
396 |
const gs_color_space *pacs =
|
|
|
397 |
(const gs_color_space *)&pcs->params.separation.alt_space;
|
|
|
398 |
|
|
|
399 |
return (*pacs->type->remap_concrete_color)
|
|
|
400 |
(pconc, pacs, pdc, pis, dev, select);
|
|
|
401 |
}
|
|
|
402 |
else {
|
|
|
403 |
gx_remap_concrete_separation(pconc[0], pdc, pis, dev, select);
|
|
|
404 |
return 0;
|
|
|
405 |
}
|
|
|
406 |
}
|
|
|
407 |
|
|
|
408 |
/*
|
|
|
409 |
* Check that the color component name for a Separation color space
|
|
|
410 |
* matches the device colorant names. Also build a gs_devicen_color_map
|
|
|
411 |
* structure.
|
|
|
412 |
*/
|
|
|
413 |
private int
|
|
|
414 |
check_Separation_component_name(const gs_color_space * pcs, gs_state * pgs)
|
|
|
415 |
{
|
|
|
416 |
const gs_separation_name name = pcs->params.separation.sep_name;
|
|
|
417 |
int colorant_number;
|
|
|
418 |
byte * pname;
|
|
|
419 |
uint name_size;
|
|
|
420 |
gs_devicen_color_map * pcolor_component_map
|
|
|
421 |
= &pgs->color_component_map;
|
|
|
422 |
gx_device * dev = pgs->device;
|
|
|
423 |
|
|
|
424 |
pcolor_component_map->num_components = 1;
|
|
|
425 |
pcolor_component_map->cspace_id = pcs->id;
|
|
|
426 |
pcolor_component_map->num_colorants = dev->color_info.num_components;
|
|
|
427 |
pcolor_component_map->sep_type = pcs->params.separation.sep_type;
|
|
|
428 |
/*
|
|
|
429 |
* If this is a None or All separation then we do not need to
|
|
|
430 |
* use the alternate color space.
|
|
|
431 |
*/
|
|
|
432 |
if (pcs->params.separation.sep_type != SEP_OTHER) {
|
|
|
433 |
pcolor_component_map->use_alt_cspace = false;
|
|
|
434 |
return 0;
|
|
|
435 |
}
|
|
|
436 |
/*
|
|
|
437 |
* Always use the alternate color space if the current device is
|
|
|
438 |
* using an additive color model. Separations are only for use
|
|
|
439 |
* with a subtractive color model.
|
|
|
440 |
*/
|
|
|
441 |
if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
|
|
|
442 |
pcolor_component_map->use_alt_cspace = true;
|
|
|
443 |
return 0;
|
|
|
444 |
}
|
|
|
445 |
/*
|
|
|
446 |
* Get the character string and length for the component name.
|
|
|
447 |
*/
|
|
|
448 |
pcs->params.separation.get_colorname_string(dev->memory, name, &pname, &name_size);
|
|
|
449 |
/*
|
|
|
450 |
* Compare the colorant name to the device's. If the device's
|
|
|
451 |
* compare routine returns GX_DEVICE_COLOR_MAX_COMPONENTS then the
|
|
|
452 |
* colorant is in the SeparationNames list but not in the
|
|
|
453 |
* SeparationOrder list.
|
|
|
454 |
*/
|
|
|
455 |
colorant_number = (*dev_proc(dev, get_color_comp_index))
|
|
|
456 |
(dev, (const char *)pname, name_size, SEPARATION_NAME);
|
|
|
457 |
if (colorant_number >= 0) { /* If valid colorant name */
|
|
|
458 |
pcolor_component_map->color_map[0] =
|
|
|
459 |
(colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) ? -1
|
|
|
460 |
: colorant_number;
|
|
|
461 |
pcolor_component_map->use_alt_cspace = false;
|
|
|
462 |
}
|
|
|
463 |
else
|
|
|
464 |
pcolor_component_map->use_alt_cspace = true;
|
|
|
465 |
return 0;
|
|
|
466 |
}
|
|
|
467 |
|
|
|
468 |
|
|
|
469 |
/* ---------------- Notes on real Separation colors ---------------- */
|
|
|
470 |
|
|
|
471 |
typedef ulong gs_separation; /* BOGUS */
|
|
|
472 |
|
|
|
473 |
#define gs_no_separation ((gs_separation)(-1L))
|
|
|
474 |
|
|
|
475 |
#define dev_proc_lookup_separation(proc)\
|
|
|
476 |
gs_separation proc(gx_device *dev, const byte *sname, uint len,\
|
|
|
477 |
gx_color_value *num_levels)
|
|
|
478 |
|
|
|
479 |
#define dev_proc_map_tint_color(proc)\
|
|
|
480 |
gx_color_index proc(gx_device *dev, gs_separation sepr, bool overprint,\
|
|
|
481 |
gx_color_value tint)
|
|
|
482 |
|
|
|
483 |
/*
|
|
|
484 |
* This next comment is outdated since the Separation color space no longer
|
|
|
485 |
* has the multi element cache (lookup table) however the remainder is
|
|
|
486 |
* still appropriate.
|
|
|
487 |
*
|
|
|
488 |
* In principle, setting a Separation color space, or setting the device
|
|
|
489 |
* when the current color space is a Separation space, calls the
|
|
|
490 |
* lookup_separation device procedure to obtain the separation ID and
|
|
|
491 |
* the number of achievable levels. Currently, the only hooks for doing
|
|
|
492 |
* this are unsuitable: gx_set_cmap_procs isn't called when the color
|
|
|
493 |
* space changes, and doing it in gx_remap_Separation is inefficient.
|
|
|
494 |
* Probably the best approach is to call gx_set_cmap_procs whenever the
|
|
|
495 |
* color space changes. In fact, if we do this, we can probably short-cut
|
|
|
496 |
* two levels of procedure call in color remapping (gx_remap_color, by
|
|
|
497 |
* turning it into a macro, and gx_remap_DeviceXXX, by calling the
|
|
|
498 |
* cmap_proc procedure directly). Some care will be required for the
|
|
|
499 |
* implicit temporary resetting of the color space in [color]image.
|
|
|
500 |
*/
|
|
|
501 |
|
|
|
502 |
/* ---------------- Serialization. -------------------------------- */
|
|
|
503 |
|
|
|
504 |
private int
|
|
|
505 |
gx_serialize_Separation(const gs_color_space * pcs, stream * s)
|
|
|
506 |
{
|
|
|
507 |
const gs_separation_params * p = &pcs->params.separation;
|
|
|
508 |
uint n;
|
|
|
509 |
int code = gx_serialize_cspace_type(pcs, s);
|
|
|
510 |
|
|
|
511 |
if (code < 0)
|
|
|
512 |
return code;
|
|
|
513 |
code = sputs(s, (const byte *)&p->sep_name, sizeof(p->sep_name), &n);
|
|
|
514 |
if (code < 0)
|
|
|
515 |
return code;
|
|
|
516 |
code = cs_serialize((const gs_color_space *)&p->alt_space, s);
|
|
|
517 |
if (code < 0)
|
|
|
518 |
return code;
|
|
|
519 |
code = gx_serialize_device_n_map(pcs, p->map, s);
|
|
|
520 |
if (code < 0)
|
|
|
521 |
return code;
|
|
|
522 |
return sputs(s, (const byte *)&p->sep_type, sizeof(p->sep_type), &n);
|
|
|
523 |
/* p->use_alt_cspace isn't a property of the space. */
|
|
|
524 |
}
|