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