2 |
- |
1 |
/* Copyright (C) 2004 Artifex Software Inc., artofcode LLC. 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: gsequivc.c,v 1.6 2005/07/08 22:04:31 dan Exp $ */
|
|
|
18 |
/* Routines for determining equivalent color for spot colors */
|
|
|
19 |
|
|
|
20 |
#include "math_.h"
|
|
|
21 |
#include "gdevprn.h"
|
|
|
22 |
#include "gsparam.h"
|
|
|
23 |
#include "gstypes.h"
|
|
|
24 |
#include "gxdcconv.h"
|
|
|
25 |
#include "gdevdevn.h"
|
|
|
26 |
#include "gsequivc.h"
|
|
|
27 |
#include "gzstate.h"
|
|
|
28 |
#include "gsstate.h"
|
|
|
29 |
#include "gscspace.h"
|
|
|
30 |
#include "gxcspace.h"
|
|
|
31 |
|
|
|
32 |
/*
|
|
|
33 |
* These routines are part of the logic for determining an equivalent
|
|
|
34 |
* process color model color for a spot color. The definition of a
|
|
|
35 |
* Separation or DeviceN color space include a tint transform function.
|
|
|
36 |
* This tint transform function is used if the specified spot or separation
|
|
|
37 |
* colorant is not present. We want to be able to display the spot colors
|
|
|
38 |
* on our RGB or CMYK display. We are using the tint transform function
|
|
|
39 |
* to determine a CMYK equivalent to the spot color. Current only CMYK
|
|
|
40 |
* equivalent colors are supported. This is because the CMYK is the only
|
|
|
41 |
* standard subtractive color space.
|
|
|
42 |
*
|
|
|
43 |
* This process consists of the following steps:
|
|
|
44 |
*
|
|
|
45 |
* 1. Whenever new spot colors are found, set status flags indicating
|
|
|
46 |
* that we have one or more spot colors for which we need to determine an
|
|
|
47 |
* equivalent color. New spot colors can either be explicitly specified by
|
|
|
48 |
* the SeparationColorNames device parameter or they may be detected by the
|
|
|
49 |
* device's get_color_comp_index routine.
|
|
|
50 |
*
|
|
|
51 |
* 2. Whenever a Separation or DeviceN color space is installed, the
|
|
|
52 |
* update_spot_equivalent_colors device proc is called. This allows the
|
|
|
53 |
* device to check if the color space contains a spot color for which the
|
|
|
54 |
* device does not know the equivalent CMYK color. The routine
|
|
|
55 |
* update_spot_equivalent_cmyk_colors is provided for this task (and the
|
|
|
56 |
* next item).
|
|
|
57 |
*
|
|
|
58 |
* 3. For each spot color for which an equivalent color is not known, we
|
|
|
59 |
* do the following:
|
|
|
60 |
* a. Create a copy of the color space and change the copy so that it
|
|
|
61 |
* uses its alternate colorspace.
|
|
|
62 |
* b. Create a copy of the current imager state and modify its color
|
|
|
63 |
* mapping (cmap) procs to use a special set of 'capture' procs.
|
|
|
64 |
* c. Based upon the type of color space (Separation or DeviceN) create
|
|
|
65 |
* a 'color' which consists of the desired spot color set to 100% and
|
|
|
66 |
* and other components set to zero.
|
|
|
67 |
* d. Call the remap_color routine using our modified color space and
|
|
|
68 |
* state structures. Since we have forced the use of the alternate
|
|
|
69 |
* color space, we will eventually execute one of the 'capture' color
|
|
|
70 |
* space mapping procs. This will give us either a gray, RGB, or
|
|
|
71 |
* CMYK color which is equivalent to the original spot color. If the
|
|
|
72 |
* color is gray or RGB we convert it to CMYK.
|
|
|
73 |
* e. Save the equivalent CMYK color in the device structure.
|
|
|
74 |
*
|
|
|
75 |
* 4. When a page is to be displayed or a file created, the saved equivalent
|
|
|
76 |
* color is used as desired. It can be written into the output file. It
|
|
|
77 |
* may also be used to provide color values which can be combined with the
|
|
|
78 |
* process color model components for a pixel, to correctly display spot
|
|
|
79 |
* colors on a monitor. (Note: Overprinting effects with spot colors are
|
|
|
80 |
* not correctly displayed on an RGB monitor if the device simply uses an RGB
|
|
|
81 |
* process color model. Instead it is necessary to use a subtractive process
|
|
|
82 |
* color model and save both process color and spot color data and then
|
|
|
83 |
* convert the overall result to RGB for display.)
|
|
|
84 |
*
|
|
|
85 |
* For this process to work properly, the following changes need to made to
|
|
|
86 |
* the device.
|
|
|
87 |
*
|
|
|
88 |
* 1. The device source module needs to include gsequivc.c for a definition
|
|
|
89 |
* of the relevant structures and routines. An equivalent_cmyk_color_params
|
|
|
90 |
* structure needs to be added to the device's structure definition and
|
|
|
91 |
* it needs to be initialized. For examples see the definition of the
|
|
|
92 |
* psd_device structure in src/gdevpsd.c and the definitions of the
|
|
|
93 |
* gs_psdrgb_device and gs_psdcmyk_devices devices in the same module.
|
|
|
94 |
* 2. Logic needs to be added to the device's get_color_comp_index and
|
|
|
95 |
* put_param routines to check if any separations have been added to the
|
|
|
96 |
* device. For examples see code fragments in psd_get_color_comp_index and
|
|
|
97 |
* psd_put_params in src/gdevpsd.c.
|
|
|
98 |
* 3. The device needs to have its own version of the
|
|
|
99 |
* update_spot_equivalent_colors routine. For examples see the definition
|
|
|
100 |
* of the device_procs macro and the psd_update_spot_equivalent_colors
|
|
|
101 |
* routine in src/gdevpsd.c.
|
|
|
102 |
* 4. The device then uses the saved equivalent color values when its output
|
|
|
103 |
* is created. For example see the psd_write_header routine in
|
|
|
104 |
* src/gdevpsd.c.
|
|
|
105 |
*/
|
|
|
106 |
|
|
|
107 |
/* Function protypes */
|
|
|
108 |
private void capture_spot_equivalent_cmyk_colors(gx_device * pdev,
|
|
|
109 |
const gs_state * pgs, const gs_client_color * pcc,
|
|
|
110 |
const gs_color_space * pcs, int sep_num,
|
|
|
111 |
equivalent_cmyk_color_params * pparams);
|
|
|
112 |
|
|
|
113 |
#define compare_color_names(name, name_size, str, str_size) \
|
|
|
114 |
(name_size == str_size && \
|
|
|
115 |
(strncmp((const char *)name, (const char *)str, name_size) == 0))
|
|
|
116 |
|
|
|
117 |
private void
|
|
|
118 |
update_Separation_spot_equivalent_cmyk_colors(gx_device * pdev,
|
|
|
119 |
const gs_state * pgs, const gs_color_space * pcs,
|
|
|
120 |
gs_devn_params * pdevn_params,
|
|
|
121 |
equivalent_cmyk_color_params * pparams)
|
|
|
122 |
{
|
|
|
123 |
int i;
|
|
|
124 |
|
|
|
125 |
/*
|
|
|
126 |
* Check if the color space's separation name matches any of the
|
|
|
127 |
* separations for which we need an equivalent CMYK color.
|
|
|
128 |
*/
|
|
|
129 |
for (i = 0; i < pdevn_params->separations.num_separations; i++) {
|
|
|
130 |
if (pparams->color[i].color_info_valid == false) {
|
|
|
131 |
const devn_separation_name * dev_sep_name =
|
|
|
132 |
&(pdevn_params->separations.names[i]);
|
|
|
133 |
unsigned int cs_sep_name_size;
|
|
|
134 |
unsigned char * pcs_sep_name;
|
|
|
135 |
|
|
|
136 |
pcs->params.separation.get_colorname_string
|
|
|
137 |
(pdev->memory, pcs->params.separation.sep_name, &pcs_sep_name,
|
|
|
138 |
&cs_sep_name_size);
|
|
|
139 |
if (compare_color_names(dev_sep_name->data, dev_sep_name->size,
|
|
|
140 |
pcs_sep_name, cs_sep_name_size)) {
|
|
|
141 |
gs_color_space temp_cs = *pcs;
|
|
|
142 |
gs_client_color client_color;
|
|
|
143 |
|
|
|
144 |
/*
|
|
|
145 |
* Create a copy of the color space and then modify it
|
|
|
146 |
* to force the use of the alternate color space.
|
|
|
147 |
*/
|
|
|
148 |
temp_cs.params.separation.use_alt_cspace = true;
|
|
|
149 |
client_color.paint.values[0] = 1.0;
|
|
|
150 |
capture_spot_equivalent_cmyk_colors(pdev, pgs, &client_color,
|
|
|
151 |
&temp_cs, i, pparams);
|
|
|
152 |
break;
|
|
|
153 |
}
|
|
|
154 |
}
|
|
|
155 |
}
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
private void
|
|
|
159 |
update_DeviceN_spot_equivalent_cmyk_colors(gx_device * pdev,
|
|
|
160 |
const gs_state * pgs, const gs_color_space * pcs,
|
|
|
161 |
gs_devn_params * pdevn_params,
|
|
|
162 |
equivalent_cmyk_color_params * pparams)
|
|
|
163 |
{
|
|
|
164 |
int i;
|
|
|
165 |
unsigned int j;
|
|
|
166 |
unsigned int cs_sep_name_size;
|
|
|
167 |
unsigned char * pcs_sep_name;
|
|
|
168 |
|
|
|
169 |
/*
|
|
|
170 |
* Check if the color space contains components named 'None'. If so then
|
|
|
171 |
* our capture logic does not work properly. When present, the 'None'
|
|
|
172 |
* components contain alternate color information. However this info is
|
|
|
173 |
* specified as part of the 'color' and not part of the color space. Thus
|
|
|
174 |
* we do not have this data when this routine is called. See the
|
|
|
175 |
* description of DeviceN color spaces in section 4.5 of the PDF spec.
|
|
|
176 |
* In this situation we exit rather than produce invalid values.
|
|
|
177 |
*/
|
|
|
178 |
for (j = 0; j < pcs->params.device_n.num_components; j++) {
|
|
|
179 |
pcs->params.device_n.get_colorname_string
|
|
|
180 |
(pdev->memory, pcs->params.device_n.names[j],
|
|
|
181 |
&pcs_sep_name, &cs_sep_name_size);
|
|
|
182 |
if (compare_color_names("None", 4, pcs_sep_name, cs_sep_name_size))
|
|
|
183 |
return;
|
|
|
184 |
}
|
|
|
185 |
|
|
|
186 |
/*
|
|
|
187 |
* Check if the color space's separation names matches any of the
|
|
|
188 |
* separations for which we need an equivalent CMYK color.
|
|
|
189 |
*/
|
|
|
190 |
for (i = 0; i < pdevn_params->separations.num_separations; i++) {
|
|
|
191 |
if (pparams->color[i].color_info_valid == false) {
|
|
|
192 |
const devn_separation_name * dev_sep_name =
|
|
|
193 |
&(pdevn_params->separations.names[i]);
|
|
|
194 |
|
|
|
195 |
for (j = 0; j < pcs->params.device_n.num_components; j++) {
|
|
|
196 |
pcs->params.device_n.get_colorname_string
|
|
|
197 |
(pdev->memory, pcs->params.device_n.names[j], &pcs_sep_name,
|
|
|
198 |
&cs_sep_name_size);
|
|
|
199 |
if (compare_color_names(dev_sep_name->data, dev_sep_name->size,
|
|
|
200 |
pcs_sep_name, cs_sep_name_size)) {
|
|
|
201 |
gs_color_space temp_cs = *pcs;
|
|
|
202 |
gs_client_color client_color;
|
|
|
203 |
|
|
|
204 |
/*
|
|
|
205 |
* Create a copy of the color space and then modify it
|
|
|
206 |
* to force the use of the alternate color space.
|
|
|
207 |
*/
|
|
|
208 |
memset(&client_color, 0, sizeof(client_color));
|
|
|
209 |
temp_cs.params.device_n.use_alt_cspace = true;
|
|
|
210 |
client_color.paint.values[j] = 1.0;
|
|
|
211 |
capture_spot_equivalent_cmyk_colors(pdev, pgs, &client_color,
|
|
|
212 |
&temp_cs, i, pparams);
|
|
|
213 |
break;
|
|
|
214 |
}
|
|
|
215 |
}
|
|
|
216 |
}
|
|
|
217 |
}
|
|
|
218 |
}
|
|
|
219 |
|
|
|
220 |
private bool check_all_colors_known(int num_spot,
|
|
|
221 |
equivalent_cmyk_color_params * pparams)
|
|
|
222 |
{
|
|
|
223 |
for (num_spot--; num_spot >= 0; num_spot--)
|
|
|
224 |
if (pparams->color[num_spot].color_info_valid == false)
|
|
|
225 |
return false;
|
|
|
226 |
return true;
|
|
|
227 |
}
|
|
|
228 |
|
|
|
229 |
/* If possible, update the equivalent CMYK color for a spot color */
|
|
|
230 |
void
|
|
|
231 |
update_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
|
|
|
232 |
gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams)
|
|
|
233 |
{
|
|
|
234 |
const gs_color_space * pcs;
|
|
|
235 |
|
|
|
236 |
/* If all of the color_info is valid then there is nothing to do. */
|
|
|
237 |
if (pparams->all_color_info_valid)
|
|
|
238 |
return;
|
|
|
239 |
|
|
|
240 |
/* Verify that we really have some separations. */
|
|
|
241 |
if (pdevn_params->separations.num_separations == 0) {
|
|
|
242 |
pparams->all_color_info_valid = true;
|
|
|
243 |
return;
|
|
|
244 |
}
|
|
|
245 |
/*
|
|
|
246 |
* Verify that the given color space is a Separation or a DeviceN color
|
|
|
247 |
* space. If so then when check if the color space contains a separation
|
|
|
248 |
* color for which we need a CMYK equivalent.
|
|
|
249 |
*/
|
|
|
250 |
pcs = pgs->color_space;
|
|
|
251 |
if (pcs != NULL) {
|
|
|
252 |
if (pcs->type->index == gs_color_space_index_Separation) {
|
|
|
253 |
update_Separation_spot_equivalent_cmyk_colors(pdev, pgs, pcs,
|
|
|
254 |
pdevn_params, pparams);
|
|
|
255 |
pparams->all_color_info_valid = check_all_colors_known
|
|
|
256 |
(pdevn_params->separations.num_separations, pparams);
|
|
|
257 |
}
|
|
|
258 |
else if (pcs->type->index == gs_color_space_index_DeviceN) {
|
|
|
259 |
update_DeviceN_spot_equivalent_cmyk_colors(pdev, pgs, pcs,
|
|
|
260 |
pdevn_params, pparams);
|
|
|
261 |
pparams->all_color_info_valid = check_all_colors_known
|
|
|
262 |
(pdevn_params->separations.num_separations, pparams);
|
|
|
263 |
}
|
|
|
264 |
}
|
|
|
265 |
}
|
|
|
266 |
|
|
|
267 |
private void
|
|
|
268 |
save_spot_equivalent_cmyk_color(int sep_num,
|
|
|
269 |
equivalent_cmyk_color_params * pparams, frac cmyk[4])
|
|
|
270 |
{
|
|
|
271 |
pparams->color[sep_num].c = cmyk[0];
|
|
|
272 |
pparams->color[sep_num].m = cmyk[1];
|
|
|
273 |
pparams->color[sep_num].y = cmyk[2];
|
|
|
274 |
pparams->color[sep_num].k = cmyk[3];
|
|
|
275 |
pparams->color[sep_num].color_info_valid = true;
|
|
|
276 |
}
|
|
|
277 |
|
|
|
278 |
/*
|
|
|
279 |
* A structure definition for a device for capturing equivalent colors
|
|
|
280 |
*/
|
|
|
281 |
typedef struct color_capture_device_s {
|
|
|
282 |
gx_device_common;
|
|
|
283 |
gx_prn_device_common;
|
|
|
284 |
/* ... device-specific parameters ... */
|
|
|
285 |
/* The following values are needed by the cmap procs for saving data */
|
|
|
286 |
int sep_num; /* Number of the separation being captured */
|
|
|
287 |
/* Pointer to original device's equivalent CMYK colors */
|
|
|
288 |
equivalent_cmyk_color_params * pequiv_cmyk_colors;
|
|
|
289 |
} color_capture_device;
|
|
|
290 |
|
|
|
291 |
/*
|
|
|
292 |
* Replacement routines for the cmap procs. These routines will capture the
|
|
|
293 |
* equivalent color.
|
|
|
294 |
*/
|
|
|
295 |
private cmap_proc_gray(cmap_gray_capture_cmyk_color);
|
|
|
296 |
private cmap_proc_rgb(cmap_rgb_capture_cmyk_color);
|
|
|
297 |
private cmap_proc_cmyk(cmap_cmyk_capture_cmyk_color);
|
|
|
298 |
private cmap_proc_rgb_alpha(cmap_rgb_alpha_capture_cmyk_color);
|
|
|
299 |
private cmap_proc_separation(cmap_separation_capture_cmyk_color);
|
|
|
300 |
private cmap_proc_devicen(cmap_devicen_capture_cmyk_color);
|
|
|
301 |
|
|
|
302 |
private const gx_color_map_procs cmap_capture_cmyk_color = {
|
|
|
303 |
cmap_gray_capture_cmyk_color,
|
|
|
304 |
cmap_rgb_capture_cmyk_color,
|
|
|
305 |
cmap_cmyk_capture_cmyk_color,
|
|
|
306 |
cmap_rgb_alpha_capture_cmyk_color,
|
|
|
307 |
cmap_separation_capture_cmyk_color,
|
|
|
308 |
cmap_devicen_capture_cmyk_color
|
|
|
309 |
};
|
|
|
310 |
|
|
|
311 |
private void
|
|
|
312 |
cmap_gray_capture_cmyk_color(frac gray, gx_device_color * pdc,
|
|
|
313 |
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
|
|
|
314 |
{
|
|
|
315 |
equivalent_cmyk_color_params * pparams =
|
|
|
316 |
((color_capture_device *)dev)->pequiv_cmyk_colors;
|
|
|
317 |
int sep_num = ((color_capture_device *)dev)->sep_num;
|
|
|
318 |
frac cmyk[4];
|
|
|
319 |
|
|
|
320 |
cmyk[0] = cmyk[1] = cmyk[2] = frac_0;
|
|
|
321 |
cmyk[3] = frac_1 - gray;
|
|
|
322 |
save_spot_equivalent_cmyk_color(sep_num, pparams, cmyk);
|
|
|
323 |
}
|
|
|
324 |
|
|
|
325 |
private void
|
|
|
326 |
cmap_rgb_capture_cmyk_color(frac r, frac g, frac b, gx_device_color * pdc,
|
|
|
327 |
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
|
|
|
328 |
{
|
|
|
329 |
equivalent_cmyk_color_params * pparams =
|
|
|
330 |
((color_capture_device *)dev)->pequiv_cmyk_colors;
|
|
|
331 |
int sep_num = ((color_capture_device *)dev)->sep_num;
|
|
|
332 |
frac cmyk[4];
|
|
|
333 |
|
|
|
334 |
color_rgb_to_cmyk(r, g, b, pis, cmyk);
|
|
|
335 |
save_spot_equivalent_cmyk_color(sep_num, pparams, cmyk);
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
private void
|
|
|
339 |
cmap_cmyk_capture_cmyk_color(frac c, frac m, frac y, frac k, gx_device_color * pdc,
|
|
|
340 |
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
|
|
|
341 |
{
|
|
|
342 |
equivalent_cmyk_color_params * pparams =
|
|
|
343 |
((color_capture_device *)dev)->pequiv_cmyk_colors;
|
|
|
344 |
int sep_num = ((color_capture_device *)dev)->sep_num;
|
|
|
345 |
frac cmyk[4];
|
|
|
346 |
|
|
|
347 |
cmyk[0] = c;
|
|
|
348 |
cmyk[1] = m;
|
|
|
349 |
cmyk[2] = y;
|
|
|
350 |
cmyk[3] = k;
|
|
|
351 |
save_spot_equivalent_cmyk_color(sep_num, pparams, cmyk);
|
|
|
352 |
}
|
|
|
353 |
|
|
|
354 |
private void
|
|
|
355 |
cmap_rgb_alpha_capture_cmyk_color(frac r, frac g, frac b, frac alpha,
|
|
|
356 |
gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
|
|
|
357 |
gs_color_select_t select)
|
|
|
358 |
{
|
|
|
359 |
cmap_rgb_capture_cmyk_color(r, g, b, pdc, pis, dev, select);
|
|
|
360 |
}
|
|
|
361 |
|
|
|
362 |
private void
|
|
|
363 |
cmap_separation_capture_cmyk_color(frac all, gx_device_color * pdc,
|
|
|
364 |
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
|
|
|
365 |
{
|
|
|
366 |
dprintf("cmap_separation_capture_cmyk_color - this routine should not be executed\n");
|
|
|
367 |
}
|
|
|
368 |
|
|
|
369 |
private void
|
|
|
370 |
cmap_devicen_capture_cmyk_color(const frac * pcc, gx_device_color * pdc,
|
|
|
371 |
const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
|
|
|
372 |
{
|
|
|
373 |
dprintf("cmap_devicen_capture_cmyk_color - this routine should not be executed\n");
|
|
|
374 |
}
|
|
|
375 |
|
|
|
376 |
/*
|
|
|
377 |
* Note: The color space (pcs) has already been modified to use the
|
|
|
378 |
* alternate color space.
|
|
|
379 |
*/
|
|
|
380 |
private void
|
|
|
381 |
capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs,
|
|
|
382 |
const gs_client_color * pcc, const gs_color_space * pcs,
|
|
|
383 |
int sep_num, equivalent_cmyk_color_params * pparams)
|
|
|
384 |
{
|
|
|
385 |
gs_imager_state temp_state = *((const gs_imager_state *)pgs);
|
|
|
386 |
color_capture_device temp_device = { 0 };
|
|
|
387 |
gx_device_color dev_color;
|
|
|
388 |
|
|
|
389 |
/*
|
|
|
390 |
* Create a temp device. The primary purpose of this device is pass the
|
|
|
391 |
* separation number and a pointer to the original device's equivalent
|
|
|
392 |
* color parameters. Since we only using this device for a very specific
|
|
|
393 |
* purpose, we only set up the color_info structure and and our data.
|
|
|
394 |
*/
|
|
|
395 |
temp_device.color_info = pdev->color_info;
|
|
|
396 |
temp_device.sep_num = sep_num;
|
|
|
397 |
temp_device.pequiv_cmyk_colors = pparams;
|
|
|
398 |
/*
|
|
|
399 |
* Create a temp copy of the imager state. We do this so that we
|
|
|
400 |
* can modify the color space mapping (cmap) procs. We use our
|
|
|
401 |
* replacment procs to capture the color. The installation of a
|
|
|
402 |
* Separation or DeviceN color space also sets a use_alt_cspace flag
|
|
|
403 |
* in the state. We also need to set this to use the alternate space.
|
|
|
404 |
*/
|
|
|
405 |
temp_state.cmap_procs = &cmap_capture_cmyk_color;
|
|
|
406 |
temp_state.color_component_map.use_alt_cspace = true;
|
|
|
407 |
|
|
|
408 |
/* Now capture the color */
|
|
|
409 |
pcs->type->remap_color (pcc, pcs, &dev_color, &temp_state,
|
|
|
410 |
(gx_device *)&temp_device, gs_color_select_texture);
|
|
|
411 |
}
|