xref: /plan9/sys/src/cmd/gs/src/gsovrc.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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(&params.drawn_comps, data + 1, size - 1);
192         if (code < 0)
193             return code;
194          nbytes += code;
195     }
196 
197     code = gs_create_overprint(ppct, &params, 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