1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2 All Rights Reserved.
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, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13
14 /* $Id: gsovrc.c 10200 2009-10-21 03:50:46Z mvrhel $ */
15 /* overprint/overprint mode compositor implementation */
16
17 #include "memory_.h"
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gsutil.h" /* for gs_next_ids */
21 #include "gxcomp.h"
22 #include "gxdevice.h"
23 #include "gsdevice.h"
24 #include "gxgetbit.h"
25 #include "gsovrc.h"
26 #include "gxdcolor.h"
27 #include "gxoprect.h"
28 #include "gsbitops.h"
29 #include "gxistate.h"
30
31
32 /* GC descriptor for gs_overprint_t */
33 private_st_gs_overprint_t();
34
35 /*
36 * Utility routine for encoding or decoding a color index. We cannot use
37 * the general integer encoding routins for these, as they may be 64 bits
38 * in length (the general routines are only designed for 32 bits). We also
39 * cannot use the color-specific routines, as we do not have the required
40 * device color information available.
41 *
42 * The scheme employed is the potentially 64-bit analog of the 32-bit
43 * routines: the low order seven bits of each bytes represents a base-128
44 * digit, and the high order bit is set if there is another digit. The
45 * encoding order is little-endian.
46 *
47 * The write routine returns 0 on success, with *psize set to the number
48 * of bytes used. Alternatively, the return value will be gs_error_rangecheck,
49 * with *psize set to the number of bytes required, if there was insufficient
50 * space.
51 *
52 * The read routine returns the number of bytes read on success, or < 0 in
53 * the event of an error.
54 */
55 static int
write_color_index(gx_color_index cindex,byte * data,uint * psize)56 write_color_index(gx_color_index cindex, byte * data, uint * psize)
57 {
58 int num_bytes = 0;
59 gx_color_index ctmp = cindex;
60
61 for (num_bytes = 1; (ctmp >>= 7) != 0; ++num_bytes)
62 ;
63 if (num_bytes > *psize) {
64 *psize = num_bytes;
65 return gs_error_rangecheck;
66 }
67 ctmp = cindex;
68 *psize = num_bytes;
69 for (; num_bytes > 1; ctmp >>= 7, --num_bytes)
70 *data++ = 0x80 | (ctmp & 0x7f);
71 *data = ctmp & 0x7f;
72 return 0;
73 }
74
75 static int
read_color_index(gx_color_index * pcindex,const byte * data,uint size)76 read_color_index(gx_color_index * pcindex, const byte * data, uint size)
77 {
78 gx_color_index cindex = 0;
79 int nbytes = 0, shift = 0;
80
81 for (;; shift += 7, data++) {
82 if (++nbytes > size)
83 return_error(gs_error_rangecheck);
84 else {
85 unsigned char byte = *data;
86 gx_color_index c = byte;
87
88 cindex += (c & 0x7f) << shift;
89 if ((c & 0x80) == 0)
90 break;
91 }
92 }
93 *pcindex = cindex;
94 return nbytes;
95 }
96
97 /*
98 * Check for equality of two overprint compositor objects.
99 *
100 * This is fairly simple.
101 */
102 static bool
c_overprint_equal(const gs_composite_t * pct0,const gs_composite_t * pct1)103 c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
104 {
105 if (pct0->type == pct1->type) {
106 const gs_overprint_params_t * pparams0;
107 const gs_overprint_params_t * pparams1;
108
109 pparams0 = &((const gs_overprint_t *)(pct0))->params;
110 pparams1 = &((const gs_overprint_t *)(pct1))->params;
111 if (!pparams0->retain_any_comps)
112 return !pparams1->retain_any_comps;
113 else if (pparams0->retain_spot_comps)
114 return pparams1->retain_spot_comps;
115 else
116 return pparams0->drawn_comps == pparams1->drawn_comps;
117 } else
118 return false;
119 }
120
121 /*
122 * Bits corresponding to boolean values in the first byte of the string
123 * representation of an overprint compositor.
124 */
125 #define OVERPRINT_ANY_COMPS 1
126 #define OVERPRINT_SPOT_COMPS 2
127
128 /*
129 * Convert an overprint compositor to string form for use by the command
130 * list device.
131 */
132 static int
c_overprint_write(const gs_composite_t * pct,byte * data,uint * psize,gx_device_clist_writer * cdev)133 c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
134 {
135 const gs_overprint_params_t * pparams = &((const gs_overprint_t *)pct)->params;
136 byte flags = 0;
137 int used = 1, avail = *psize;
138
139 /* encoded the booleans in a single byte */
140 if (pparams->retain_any_comps) {
141 flags |= OVERPRINT_ANY_COMPS;
142
143 /* write out the component bits only if necessary (and possible) */
144 if (pparams->retain_spot_comps)
145 flags |= OVERPRINT_SPOT_COMPS;
146 else {
147 uint tmp_size = (avail > 0 ? avail - 1 : 0);
148 int code = write_color_index( pparams->drawn_comps,
149 data + 1,
150 &tmp_size );
151
152 if (code < 0 && code != gs_error_rangecheck)
153 return code;
154 used += tmp_size;
155 }
156 }
157
158 /* check for overflow */
159 *psize = used;
160 if (used > avail)
161 return_error(gs_error_rangecheck);
162 data[0] = flags;
163 if_debug1('v', "[v]c_overprint_write(%d)\n", flags);
164 return 0;
165 }
166
167 /*
168 * Convert the string representation of the overprint parameter into the
169 * full compositor.
170 */
171 static int
c_overprint_read(gs_composite_t ** ppct,const byte * data,uint size,gs_memory_t * mem)172 c_overprint_read(
173 gs_composite_t ** ppct,
174 const byte * data,
175 uint size,
176 gs_memory_t * mem )
177 {
178 gs_overprint_params_t params;
179 byte flags = 0;
180 int code = 0, nbytes = 1;
181
182 if (size < 1)
183 return_error(gs_error_rangecheck);
184 flags = *data;
185 if_debug1('v', "[v]c_overprint_read(%d)\n", flags);
186 params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0;
187 params.retain_spot_comps = (flags & OVERPRINT_SPOT_COMPS) != 0;
188 params.idle = 0;
189
190 /* check if the drawn_comps array is present */
191 if (params.retain_any_comps && !params.retain_spot_comps) {
192 code = read_color_index(¶ms.drawn_comps, data + 1, size - 1);
193 if (code < 0)
194 return code;
195 nbytes += code;
196 }
197
198 code = gs_create_overprint(ppct, ¶ms, mem);
199
200 return code < 0 ? code : nbytes;
201 }
202
203 /*
204 * Check for closing compositor.
205 */
206 static int
c_overprint_is_closing(const gs_composite_t * this,gs_composite_t ** ppcte,gx_device * dev)207 c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev)
208 {
209 if (*ppcte != NULL && (*ppcte)->type->comp_id != GX_COMPOSITOR_OVERPRINT)
210 return 0;
211 return 3;
212 }
213
214 static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
215 static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
216 static composite_equal_proc(c_overprint_equal);
217 static composite_write_proc(c_overprint_write);
218 static composite_is_closing_proc(c_overprint_is_closing);
219 static composite_read_proc(c_overprint_read);
220
221 /* methods for the overprint compositor */
222 const gs_composite_type_t gs_composite_overprint_type = {
223 GX_COMPOSITOR_OVERPRINT,
224 {
225 c_overprint_create_default_compositor, /* procs.create_default_compositor */
226 c_overprint_equal, /* procs.equal */
227 c_overprint_write, /* procs.write */
228 c_overprint_read, /* procs.read */
229 gx_default_composite_adjust_ctm,
230 c_overprint_is_closing,
231 gx_default_composite_is_friendly,
232 gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
233 gx_default_composite_clist_read_update, /* procs.composite_clist_reade_update */
234 gx_default_composite_get_cropping /* procs.composite_get_cropping */
235 } /* procs */
236 };
237
238
239 /*
240 * Create an overprint compositor data structure.
241 *
242 * Currently this just a stub.
243 */
244 int
gs_create_overprint(gs_composite_t ** ppct,const gs_overprint_params_t * pparams,gs_memory_t * mem)245 gs_create_overprint(
246 gs_composite_t ** ppct,
247 const gs_overprint_params_t * pparams,
248 gs_memory_t * mem )
249 {
250 gs_overprint_t * pct;
251
252 pct = gs_alloc_struct(mem, gs_overprint_t, &st_overprint,
253 "gs_create_overprint");
254 if (pct == NULL)
255 return_error(gs_error_VMerror);
256 pct->type = &gs_composite_overprint_type;
257 pct->id = gs_next_ids(mem, 1);
258 pct->params = *pparams;
259 pct->idle = false;
260 *ppct = (gs_composite_t *)pct;
261 return 0;
262 }
263
264
265 /*
266 * Verify that a compositor data structure is for the overprint compositor.
267 * This is used by the gs_pdf1.4_device (and eventually the PDFWrite
268 * device), which implements overprint and overprint mode directly.
269 */
270 int
gs_is_overprint_compositor(const gs_composite_t * pct)271 gs_is_overprint_compositor(const gs_composite_t * pct)
272 {
273 return pct->type == &gs_composite_overprint_type;
274 }
275
276
277 /*
278 * The overprint device.
279 *
280 * In principle there are two versions of this device: one if the traget
281 * device is separable and linear, the other if it is not. The two have
282 * slightly different data structures, but differ primarily in terms of
283 * the standard set of methods. Because methods are non-static in
284 * GhostScript, we make use of the same data structure and handle the
285 * distinction during initialization.
286 *
287 * The data fields reflect entries in the gs_overprint_params_t
288 * structure. There is no explicit retain_any_comps field, as the current
289 * setting of this field can be determined by checking the fill_rectangle
290 * method. There is also no retain_spot_comps field, as the code will
291 * will determine explicitly which components are to be drawn.
292 */
293 typedef struct overprint_device_s {
294 gx_device_forward_common;
295
296 /*
297 * The set of components to be drawn. This field is used only if the
298 * target color space is not separable and linear.
299 */
300 gx_color_index drawn_comps;
301
302 /*
303 * The mask of gx_color_index bits to be retained during a drawing
304 * operation. A bit in this mask is 1 if the corresponding bit or
305 * the color index is to be retained; otherwise it is 0.
306 *
307 * The "non-drawn" region of the drawing gx_color_index is assumed
308 * to have the value zero, so for a separable and linear color
309 * encoding, the per-pixel drawing operation is:
310 *
311 * output = (output & retain_mask) | src
312 *
313 * (For the fully general case, replace src by (src & ~retain_mask).)
314 * Because of byte-alignment, byte-order and performance consideration,
315 * the actually implement operation may be more complex, but this does
316 * not change the overall effect.
317 *
318 * The actual value of retain_mask will be byte swap if this is
319 * required. It will be required if depth > 8 and the host processor
320 * is little-endian.
321 */
322 gx_color_index retain_mask;
323
324 } overprint_device_t;
325
326 gs_private_st_suffix_add0_final( st_overprint_device_t,
327 overprint_device_t,
328 "overprint_device_t",
329 overprint_device_t_enum_ptrs,
330 overprint_device_t_reloc_ptrs,
331 gx_device_finalize,
332 st_device_forward );
333
334
335 /*
336 * In the default (overprint false) case, the overprint device is almost
337 * a pure forwarding device: only the open_device and create_compositor
338 * methods are not pure-forwarding methods. The
339 * gx_device_foward_fill_in_procs procedure does not fill in all of the
340 * necessary procedures, so some of them are provided explicitly below.
341 * The put_params procedure also requires a small modification, so that
342 * the open/close state of this device always reflects that of its
343 * target.
344 *
345 * This and other method arrays are not declared const so that they may
346 * be initialized once via gx_device_forward_fill_in_procs. They are
347 * constant once this initialization is complete.
348 */
349 static dev_proc_open_device(overprint_open_device);
350 static dev_proc_put_params(overprint_put_params);
351 static dev_proc_get_page_device(overprint_get_page_device);
352 static dev_proc_create_compositor(overprint_create_compositor);
353 static dev_proc_get_color_comp_index(overprint_get_color_comp_index);
354
355 static gx_device_procs no_overprint_procs = {
356 overprint_open_device, /* open_device */
357 0, /* get_initial_matrix */
358 0, /* sync_output */
359 0, /* output_page */
360 0, /* close_device */
361 0, /* map_rgb_color */
362 0, /* map_color_rgb */
363 gx_forward_fill_rectangle, /* fill_rectangle */
364 gx_forward_tile_rectangle, /* tile_rectangle */
365 gx_forward_copy_mono, /* copy_mono */
366 gx_forward_copy_color, /* copy_color */
367 0, /* draw_line (obsolete) */
368 0, /* get_bits */
369 0, /* get_params */
370 overprint_put_params, /* put_params */
371 0, /* map_cmyk_color */
372 0, /* get_xfont_procs */
373 0, /* get_xfont_device */
374 0, /* map_rgb_alpha_color */
375 overprint_get_page_device, /* get_page_device */
376 0, /* get_alpha_bits (obsolete) */
377 0, /* copy alpha */
378 0, /* get_band */
379 0, /* copy_rop */
380 0, /* fill_path */
381 0, /* stroke_path */
382 0, /* fill_mask */
383 0, /* fill_trapezoid */
384 0, /* fill_parallelogram */
385 0, /* fill_triangle */
386 0, /* draw_thin_line */
387 0, /* begin_image */
388 0, /* image_data (obsolete) */
389 0, /* end_image (obsolete) */
390 gx_forward_strip_tile_rectangle, /* strip_tile_rectangle */
391 0, /* strip_copy_rop */
392 0, /* get_clipping_box */
393 0, /* begin_typed_image */
394 0, /* get_bits_rectangle */
395 0, /* map_color_rgb_alpha */
396 overprint_create_compositor, /* create_compositor */
397 0, /* get_hardware_params */
398 0, /* text_begin */
399 0, /* gx_finish_copydevice */
400 0, /* begin_transparency_group */
401 0, /* end_transparency_group */
402 0, /* being_transparency_mask */
403 0, /* end_transparency_mask */
404 0, /* discard_transparency_layer */
405 0, /* get_color_mapping_procs */
406 overprint_get_color_comp_index, /* get_color_comp_index */
407 0, /* encode_color */
408 0, /* decode_color */
409 0, /* pattern_manage */
410 0, /* fill_rectangle_hl_color */
411 0, /* include_color_space */
412 0, /* fill_linear_color_scanline */
413 0, /* fill_linear_color_trapezoid */
414 0, /* fill_linear_color_triangle */
415 0, /* update_spot_equivalent_colors */
416 0, /* ret_devn_params */
417 gx_forward_fillpage,
418 0, /* push_transparency_state */
419 0 /* pop_transparency_state */
420
421 };
422
423 /*
424 * If overprint is set, the high and mid-level rendering methods are
425 * replaced by the default routines. The low-level color rendering methods
426 * are replaced with one of two sets of functions, depending on whether or
427 * not the target device has a separable and linear color encoding.
428 *
429 * 1. If the target device does not have a separable and linear
430 * encoding, an overprint-specific fill_rectangle method is used,
431 * and the default methods are used for all other low-level rendering
432 * methods. There is no way to achieve good rendering performance
433 * when overprint is true and the color encoding is not separable
434 * and linear, so there is little reason to use more elaborate
435 * methods int this case.
436 *
437 * 2. If the target device does have a separable and linear color
438 * model, at least the fill_rectangle method and potentially other
439 * methods will be replaced by overprint-specific methods. Those
440 * methods not replaced will have their default values. The number
441 * of methods replaced is dependent on the desired level of
442 * performance: the more methods, the better the performance.
443 *
444 * Note that certain procedures, such as copy_alpha and copy_rop,
445 * are likely to always be given their default values, as the concepts
446 * of alpha-compositing and raster operations are not compatible in
447 * a strict sense.
448 */
449 static dev_proc_fill_rectangle(overprint_generic_fill_rectangle);
450 static dev_proc_fill_rectangle(overprint_sep_fill_rectangle);
451 /* other low-level overprint_sep_* rendering methods prototypes go here */
452
453 static gx_device_procs generic_overprint_procs = {
454 overprint_open_device, /* open_device */
455 0, /* get_initial_matrix */
456 0, /* sync_output */
457 0, /* output_page */
458 0, /* close_device */
459 0, /* map_rgb_color */
460 0, /* map_color_rgb */
461 overprint_generic_fill_rectangle, /* fill_rectangle */
462 gx_default_tile_rectangle, /* tile_rectangle */
463 gx_default_copy_mono, /* copy_mono */
464 gx_default_copy_color, /* copy_color */
465 gx_default_draw_line, /* draw_line (obsolete) */
466 0, /* get_bits */
467 0, /* get_params */
468 overprint_put_params, /* put_params */
469 0, /* map_cmyk_color */
470 0, /* get_xfont_procs */
471 gx_default_get_xfont_device, /* get_xfont_device */
472 0, /* map_rgb_alpha_color */
473 overprint_get_page_device, /* get_page_device */
474 0, /* get_alpha_bits (obsolete) */
475 gx_default_copy_alpha, /* copy alpha */
476 0, /* get_band */
477 gx_default_copy_rop, /* copy_rop */
478 gx_default_fill_path, /* fill_path */
479 gx_default_stroke_path, /* stroke_path */
480 gx_default_fill_mask, /* fill_mask */
481 gx_default_fill_trapezoid, /* fill_trapezoid */
482 gx_default_fill_parallelogram, /* fill_parallelogram */
483 gx_default_fill_triangle, /* fill_triangle */
484 gx_default_draw_thin_line, /* draw_thin_line */
485 gx_default_begin_image, /* begin_image */
486 0, /* image_data (obsolete) */
487 0, /* end_image (obsolete) */
488 gx_default_strip_tile_rectangle, /* strip_tile_rectangle */
489 gx_default_strip_copy_rop, /* strip_copy_rop */
490 0, /* get_clipping_box */
491 gx_default_begin_typed_image, /* begin_typed_image */
492 0, /* get_bits_rectangle */
493 0, /* map_color_rgb_alpha */
494 overprint_create_compositor, /* create_compositor */
495 0, /* get_hardware_params */
496 gx_default_text_begin, /* text_begin */
497 0, /* gx_finish_copydevice */
498 0, /* begin_transparency_group */
499 0, /* end_transparency_group */
500 0, /* begin_transparency_mask */
501 0, /* end_transparency_mask */
502 0, /* discard_transparency_layer */
503 0, /* get_color_mapping_procs */
504 overprint_get_color_comp_index, /* get_color_comp_index */
505 0, /* encode_color */
506 0 /* decode_color */
507 };
508
509 static gx_device_procs sep_overprint_procs = {
510 overprint_open_device, /* open_device */
511 0, /* get_initial_matrix */
512 0, /* sync_output */
513 0, /* output_page */
514 0, /* close_device */
515 0, /* map_rgb_color */
516 0, /* map_color_rgb */
517 overprint_sep_fill_rectangle, /* fill_rectangle */
518 gx_default_tile_rectangle, /* tile_rectangle */
519 gx_default_copy_mono, /* copy_mono */
520 gx_default_copy_color, /* copy_color */
521 gx_default_draw_line, /* draw_line (obsolete) */
522 0, /* get_bits */
523 0, /* get_params */
524 overprint_put_params, /* put_params */
525 0, /* map_cmyk_color */
526 0, /* get_xfont_procs */
527 gx_default_get_xfont_device, /* get_xfont_device */
528 0, /* map_rgb_alpha_color */
529 overprint_get_page_device, /* get_page_device */
530 0, /* get_alpha_bits (obsolete) */
531 gx_default_copy_alpha, /* copy alpha */
532 0, /* get_band */
533 gx_default_copy_rop, /* copy_rop */
534 gx_default_fill_path, /* fill_path */
535 gx_default_stroke_path, /* stroke_path */
536 gx_default_fill_mask, /* fill_mask */
537 gx_default_fill_trapezoid, /* fill_trapezoid */
538 gx_default_fill_parallelogram, /* fill_parallelogram */
539 gx_default_fill_triangle, /* fill_triangle */
540 gx_default_draw_thin_line, /* draw_thin_line */
541 gx_default_begin_image, /* begin_image */
542 0, /* image_data (obsolete) */
543 0, /* end_image (obsolete) */
544 gx_default_strip_tile_rectangle, /* strip_tile_rectangle */
545 gx_default_strip_copy_rop, /* strip_copy_rop */
546 0, /* get_clipping_box */
547 gx_default_begin_typed_image, /* begin_typed_image */
548 0, /* get_bits_rectangle */
549 0, /* map_color_rgb_alpha */
550 overprint_create_compositor, /* create_compositor */
551 0, /* get_hardware_params */
552 gx_default_text_begin, /* text_begin */
553 0, /* gx_finish_copydevice */
554 0, /* begin_transparency_group */
555 0, /* end_transparency_group */
556 0, /* begin_transparency_mask */
557 0, /* end_transparency_mask */
558 0, /* discard_transparency_layer */
559 0, /* get_color_mapping_procs */
560 overprint_get_color_comp_index, /* get_color_comp_index */
561 0, /* encode_color */
562 0 /* decode_color */
563 };
564
565 /*
566 * The prototype for the overprint device does not provide much
567 * information; it exists primarily to facilitate use gx_init_device
568 * and sundry other device utility routines.
569 */
570 const overprint_device_t gs_overprint_device = {
571 std_device_std_body_open( overprint_device_t, /* device type */
572 0, /* static_procs */
573 "overprint_device", /* dname */
574 0, 0, /* width, height */
575 1, 1 ), /* HWResolution */
576 { 0 } /* procs */
577 };
578
579
580
581 /*
582 * Utility to reorder bytes in a color or mask based on the endianness of
583 * the current device. This is required on little-endian machines if the
584 * depth is larger 8. The resulting value is also replicated to fill the
585 * entire gx_color_index if the depth is a divisor of the color index
586 * size. If this is not the case, the result will be in the low-order
587 * bytes of the color index.
588 *
589 * Though this process can be handled in full generality, the code below
590 * takes advantage of the fact that depths that are > 8 must be a multiple
591 * of 8 and <= 64
592 */
593 #if !arch_is_big_endian
594
595 static gx_color_index
swap_color_index(int depth,gx_color_index color)596 swap_color_index(int depth, gx_color_index color)
597 {
598 int shift = depth - 8;
599 gx_color_index mask = 0xff;
600
601 color = ((color >> shift) & mask)
602 | ((color & mask) << shift)
603 | (color & ~((mask << shift) | mask));
604 if (depth > 24) {
605 shift -= 16;
606 mask <<= 8;
607 color = ((color >> shift) & mask)
608 | ((color & mask) << shift)
609 | (color & ~((mask << shift) | mask));
610
611 if (depth > 40) {
612 shift -= 16;
613 mask <<= 8;
614 color = ((color >> shift) & mask)
615 | ((color & mask) << shift)
616 | (color & ~((mask << shift) | mask));
617
618 if (depth > 56) {
619 shift -= 16;
620 mask <<= 8;
621 color = ((color >> shift) & mask)
622 | ((color & mask) << shift)
623 | (color & ~((mask << shift) | mask));
624 }
625 }
626 }
627
628 return color;
629 }
630
631 #endif /* !arch_is_big_endian */
632
633 /*
634 * Update the retain_mask field to reflect the information in the
635 * drawn_comps field. This is useful only if the device color model
636 * is separable.
637 */
638 static void
set_retain_mask(overprint_device_t * opdev)639 set_retain_mask(overprint_device_t * opdev)
640 {
641 int i, ncomps = opdev->color_info.num_components;
642 gx_color_index drawn_comps = opdev->drawn_comps, retain_mask = 0;
643 #if !arch_is_big_endian
644 int depth = opdev->color_info.depth;
645 #endif
646
647 for (i = 0; i < ncomps; i++, drawn_comps >>= 1) {
648 if ((drawn_comps & 0x1) == 0)
649 retain_mask |= opdev->color_info.comp_mask[i];
650 }
651 #if !arch_is_big_endian
652 if (depth > 8)
653 retain_mask = swap_color_index(depth, retain_mask);
654 #endif
655 opdev->retain_mask = retain_mask;
656 }
657
658 /* enlarge mask of non-zero components */
659 static gx_color_index
check_drawn_comps(int ncomps,frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS])660 check_drawn_comps(int ncomps, frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS])
661 {
662 int i;
663 gx_color_index mask = 0x1, drawn_comps = 0;
664
665 for (i = 0; i < ncomps; i++, mask <<= 1) {
666 if (cvals[i] != frac_0)
667 drawn_comps |= mask;
668 }
669 return drawn_comps;
670 }
671
672 /*
673 * Update the overprint-specific device parameters.
674 *
675 * If spot colors are to be retain, the set of process (non-spot) colors is
676 * determined by mapping through the standard color spaces and check which
677 * components assume non-zero values.
678 */
679 static int
update_overprint_params(overprint_device_t * opdev,const gs_overprint_params_t * pparams)680 update_overprint_params(
681 overprint_device_t * opdev,
682 const gs_overprint_params_t * pparams )
683 {
684 int ncomps = opdev->color_info.num_components;
685
686 /* check if overprint is to be turned off */
687 if (!pparams->retain_any_comps || pparams->idle) {
688 /* if fill_rectangle forwards, overprint is already off */
689 if (dev_proc(opdev, fill_rectangle) != gx_forward_fill_rectangle)
690 memcpy( &opdev->procs,
691 &no_overprint_procs,
692 sizeof(no_overprint_procs) );
693 return 0;
694 }
695
696 /* set the procedures according to the color model */
697 if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
698 memcpy( &opdev->procs,
699 &sep_overprint_procs,
700 sizeof(sep_overprint_procs) );
701 else
702 memcpy( &opdev->procs,
703 &generic_overprint_procs,
704 sizeof(generic_overprint_procs) );
705
706 /* see if we need to determine the spot color components */
707 if (!pparams->retain_spot_comps)
708 opdev->drawn_comps = pparams->drawn_comps;
709 else {
710 gx_device * dev = (gx_device *)opdev;
711 const gx_cm_color_map_procs * pprocs;
712 frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
713 gx_color_index drawn_comps = 0;
714 static const frac frac_13 = float2frac(1.0 / 3.0);
715
716 if ((pprocs = dev_proc(opdev, get_color_mapping_procs)(dev)) == 0 ||
717 pprocs->map_gray == 0 ||
718 pprocs->map_rgb == 0 ||
719 pprocs->map_cmyk == 0 )
720 return_error(gs_error_unknownerror);
721
722 pprocs->map_gray(dev, frac_13, cvals);
723 drawn_comps |= check_drawn_comps(ncomps, cvals);
724
725 pprocs->map_rgb(dev, 0, frac_13, frac_0, frac_0, cvals);
726 drawn_comps |= check_drawn_comps(ncomps, cvals);
727 pprocs->map_rgb(dev, 0, frac_0, frac_13, frac_0, cvals);
728 drawn_comps |= check_drawn_comps(ncomps, cvals);
729 pprocs->map_rgb(dev, 0, frac_0, frac_0, frac_13, cvals);
730 drawn_comps |= check_drawn_comps(ncomps, cvals);
731
732 pprocs->map_cmyk(dev, frac_13, frac_0, frac_0, frac_0, cvals);
733 drawn_comps |= check_drawn_comps(ncomps, cvals);
734 pprocs->map_cmyk(dev, frac_0, frac_13, frac_0, frac_0, cvals);
735 drawn_comps |= check_drawn_comps(ncomps, cvals);
736 pprocs->map_cmyk(dev, frac_0, frac_0, frac_13, frac_0, cvals);
737 drawn_comps |= check_drawn_comps(ncomps, cvals);
738 pprocs->map_cmyk(dev, frac_0, frac_0, frac_0, frac_13, cvals);
739 drawn_comps |= check_drawn_comps(ncomps, cvals);
740
741 opdev->drawn_comps = drawn_comps;
742 }
743
744 /* check for degenerate case */
745 if (opdev->drawn_comps == ((gx_color_index)1 << ncomps) - 1) {
746 memcpy( &opdev->procs,
747 &no_overprint_procs,
748 sizeof(no_overprint_procs) );
749 return 0;
750 }
751
752 /* if appropriate, update the retain_mask field */
753 if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
754 set_retain_mask(opdev);
755
756 return 0;
757 }
758
759
760 /*
761 * The open_device method for the overprint device is about as close to
762 * a pure "forwarding" open_device operation as is possible. Its only
763 * significant function is to ensure that the is_open field of the
764 * overprint device matches that of the target device.
765 *
766 * We assume this procedure is called only if the device is not already
767 * open, and that gs_opendevice will take care of the is_open flag.
768 */
769 static int
overprint_open_device(gx_device * dev)770 overprint_open_device(gx_device * dev)
771 {
772 overprint_device_t * opdev = (overprint_device_t *)dev;
773 gx_device * tdev = opdev->target;
774 int code = 0;
775
776 /* the overprint device must have a target */
777 if (tdev == 0)
778 return_error(gs_error_unknownerror);
779 if ((code = gs_opendevice(tdev)) >= 0)
780 gx_device_copy_params(dev, tdev);
781 return code;
782 }
783
784 /*
785 * The put_params method for the overprint device will check if the
786 * target device has closed and, if so, close itself.
787 */
788 static int
overprint_put_params(gx_device * dev,gs_param_list * plist)789 overprint_put_params(gx_device * dev, gs_param_list * plist)
790 {
791 overprint_device_t * opdev = (overprint_device_t *)dev;
792 gx_device * tdev = opdev->target;
793 int code = 0;
794
795
796 if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
797 gx_device_decache_colors(dev);
798 if (!tdev->is_open)
799 code = gs_closedevice(dev);
800 }
801 return code;
802 }
803
804 /*
805 * If the target device 'auto detects' new spot colors, then it will
806 * change its color_info data. Make sure that we have a current copy.
807 */
808 int
overprint_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)809 overprint_get_color_comp_index(gx_device * dev, const char * pname,
810 int name_size, int component_type)
811 {
812 overprint_device_t * opdev = (overprint_device_t *)dev;
813 gx_device * tdev = opdev->target;
814 int code;
815
816 if (tdev == 0)
817 code = gx_error_get_color_comp_index(dev, pname,
818 name_size, component_type);
819 else {
820 code = dev_proc(tdev, get_color_comp_index)(tdev, pname,
821 name_size, component_type);
822 opdev->color_info = tdev->color_info;
823 }
824 return code;
825 }
826
827 /*
828 * The overprint device must never be confused with a page device.
829 * Thus, we always forward the request for the page device to the
830 * target, as should all forwarding devices.
831 */
832 static gx_device *
overprint_get_page_device(gx_device * dev)833 overprint_get_page_device(gx_device * dev)
834 {
835 overprint_device_t * opdev = (overprint_device_t *)dev;
836 gx_device * tdev = opdev->target;
837
838 return tdev == 0 ? 0 : dev_proc(tdev, get_page_device)(tdev);
839 }
840
841 /*
842 * Calling create_compositor on the overprint device just updates the
843 * overprint parameters; no new device is created.
844 */
845 static int
overprint_create_compositor(gx_device * dev,gx_device ** pcdev,const gs_composite_t * pct,gs_imager_state * pis,gs_memory_t * memory)846 overprint_create_compositor(
847 gx_device * dev,
848 gx_device ** pcdev,
849 const gs_composite_t * pct,
850 gs_imager_state * pis,
851 gs_memory_t * memory )
852 {
853 if (pct->type != &gs_composite_overprint_type)
854 return gx_default_create_compositor(dev, pcdev, pct, pis, memory);
855 else {
856 gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params;
857 int code;
858
859 params.idle = pct->idle;
860 /* device must already exist, so just update the parameters */
861 code = update_overprint_params(
862 (overprint_device_t *)dev,
863 ¶ms );
864 if (code >= 0)
865 *pcdev = dev;
866 return code;
867 }
868 }
869
870
871 /*
872 * The two rectangle-filling routines (which do the actual work) are just
873 * stubbs for the time being. The actual routines would allocate a buffer,
874 * use get_bits_rectangle to build a buffer of the existing data, modify
875 * the appropriate components, then invoke the copy_color procedure on the
876 * target device.
877 */
878 static int
overprint_generic_fill_rectangle(gx_device * dev,int x,int y,int width,int height,gx_color_index color)879 overprint_generic_fill_rectangle(
880 gx_device * dev,
881 int x,
882 int y,
883 int width,
884 int height,
885 gx_color_index color )
886 {
887 overprint_device_t * opdev = (overprint_device_t *)dev;
888 gx_device * tdev = opdev->target;
889
890 if (tdev == 0)
891 return 0;
892 else
893 return gx_overprint_generic_fill_rectangle( tdev,
894 opdev->drawn_comps,
895 x, y, width, height,
896 color,
897 dev->memory );
898 }
899
900 static int
overprint_sep_fill_rectangle(gx_device * dev,int x,int y,int width,int height,gx_color_index color)901 overprint_sep_fill_rectangle(
902 gx_device * dev,
903 int x,
904 int y,
905 int width,
906 int height,
907 gx_color_index color )
908 {
909 overprint_device_t * opdev = (overprint_device_t *)dev;
910 gx_device * tdev = opdev->target;
911
912 if (tdev == 0)
913 return 0;
914 else {
915 int depth = tdev->color_info.depth;
916
917 /*
918 * Swap the color index into the order required by a byte-oriented
919 * bitmap. This is required only for littl-endian processors, and
920 * then only if the depth > 8.
921 */
922 #if !arch_is_big_endian
923 if (depth > 8)
924 color = swap_color_index(depth, color);
925 #endif
926
927 /*
928 * We can handle rectangle filling via bits_fill_rectangle_masked
929 * if the depth is a divisor of 8 * sizeof(mono_fill_chunk). The
930 * non-masked fill_rectangle code uses a byte-oriented routine
931 * if depth > 8, but there is not much advantage to doing so if
932 * masking is required.
933 *
934 * Directly testing (8 * sizeof(mono_fill_chunk)) % depth is
935 * potentially expensive, since many rectangles are small. We
936 * can avoid the modulus operation by noting that
937 * 8 * sizeof(mono_fill_chunk) will be a power of 2, and so
938 * we need only check that depth is a power of 2 and
939 * depth < 8 * sizeof(mono_fill_chunk).
940 */
941 if ( depth <= 8 * sizeof(mono_fill_chunk) &&
942 (depth & (depth - 1)) == 0 )
943 return gx_overprint_sep_fill_rectangle_1( tdev,
944 opdev->retain_mask,
945 x, y, width, height,
946 color,
947 dev->memory );
948 else
949 return gx_overprint_sep_fill_rectangle_2( tdev,
950 opdev->retain_mask,
951 x, y, width, height,
952 color,
953 dev->memory );
954 }
955 }
956
957
958 /* complete a porcedure set */
959 static void
fill_in_procs(gx_device_procs * pprocs)960 fill_in_procs(gx_device_procs * pprocs)
961 {
962 gx_device_forward tmpdev;
963
964 /*
965 * gx_device_forward_fill_in_procs calls gx_device_fill_in_procs, which
966 * requires the color_info field of the device be set to "reasonable"
967 * values. Which values is irrelevant in this case, but they must not
968 * contain dangling pointers, excessive numbers of components, etc.
969 */
970 memcpy( &tmpdev.color_info,
971 &gs_overprint_device.color_info,
972 sizeof(tmpdev.color_info) );
973 /*
974 * Prevent the check_device_separable routine from executing while we
975 * fill in the procs. Our tmpdev is not complete enough for it.
976 */
977 tmpdev.color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
978 tmpdev.static_procs = 0;
979 memcpy(&tmpdev.procs, pprocs, sizeof(tmpdev.procs));
980 gx_device_forward_fill_in_procs(&tmpdev);
981 memcpy(pprocs, &tmpdev.procs, sizeof(tmpdev.procs));
982 }
983
984 /*
985 * Create an overprint compositor.
986 *
987 * Note that this routine will be called only if the device is not already
988 * an overprint compositor. Hence, if pct->params.retain_any_comps is
989 * false, we can just return.
990 *
991 * We also suppress use of overprint if the current device color model has only
992 * a single component. In this case overprint mode is inapplicable (it applies
993 * only to CMYK devices), and nothing can possibly be gained by using overprint.
994 * More significantly, this cause avoids erroneous use of overprint when a
995 * mask caching device is the current device, which would otherwise require
996 * elaborate special handling in the caching device create_compositor
997 * procedure.
998 */
999 static int
c_overprint_create_default_compositor(const gs_composite_t * pct,gx_device ** popdev,gx_device * tdev,gs_imager_state * pis,gs_memory_t * mem)1000 c_overprint_create_default_compositor(
1001 const gs_composite_t * pct,
1002 gx_device ** popdev,
1003 gx_device * tdev,
1004 gs_imager_state * pis,
1005 gs_memory_t * mem )
1006 {
1007 const gs_overprint_t * ovrpct = (const gs_overprint_t *)pct;
1008 overprint_device_t * opdev = 0;
1009 gs_overprint_params_t params;
1010
1011 /* see if there is anything to do */
1012 if ( !ovrpct->params.retain_any_comps) {
1013 *popdev = tdev;
1014 return 0;
1015 }
1016 if (pct->idle) {
1017 *popdev = tdev;
1018 return 0;
1019 }
1020
1021 /* check if the procedure arrays have been initialized */
1022 if (no_overprint_procs.get_xfont_procs == 0) {
1023 fill_in_procs(&no_overprint_procs);
1024 fill_in_procs(&generic_overprint_procs);
1025 fill_in_procs(&sep_overprint_procs);
1026 }
1027
1028 /* build the overprint device */
1029 opdev = gs_alloc_struct_immovable( mem,
1030 overprint_device_t,
1031 &st_overprint_device_t,
1032 "create overprint compositor" );
1033 if ((*popdev = (gx_device *)opdev) == 0)
1034 return_error(gs_error_VMerror);
1035 gx_device_init( (gx_device *)opdev,
1036 (const gx_device *)&gs_overprint_device,
1037 mem,
1038 true );
1039 gx_device_copy_params((gx_device *)opdev, tdev);
1040 gx_device_set_target((gx_device_forward *)opdev, tdev);
1041
1042 params = ovrpct->params;
1043 params.idle = ovrpct->idle;
1044
1045 /* set up the overprint parameters */
1046 return update_overprint_params( opdev, ¶ms);
1047 }
1048