1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/* $Id: gsovrc.c 9288 2008-12-13 20:05:37Z leonardo $ */
15
/* overprint/overprint mode compositor implementation */
20
#include "gsutil.h" /* for gs_next_ids */
32
/* GC descriptor for gs_overprint_t */
33
private_st_gs_overprint_t();
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.
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.
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
52
* The read routine returns the number of bytes read on success, or < 0 in
53
* the event of an error.
56
write_color_index(gx_color_index cindex, byte * data, uint * psize)
59
gx_color_index ctmp = cindex;
61
for (num_bytes = 1; (ctmp >>= 7) != 0; ++num_bytes)
63
if (num_bytes > *psize) {
65
return gs_error_rangecheck;
69
for (; num_bytes > 1; ctmp >>= 7, --num_bytes)
70
*data++ = 0x80 | (ctmp & 0x7f);
76
read_color_index(gx_color_index * pcindex, const byte * data, uint size)
78
gx_color_index cindex = 0;
79
int nbytes = 0, shift = 0;
81
for (;; shift += 7, data++) {
83
return_error(gs_error_rangecheck);
87
cindex += (c & 0x7f) << shift;
97
* Check for equality of two overprint compositor objects.
99
* This is fairly simple.
102
c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
104
if (pct0->type == pct1->type) {
105
const gs_overprint_params_t * pparams0;
106
const gs_overprint_params_t * pparams1;
108
pparams0 = &((const gs_overprint_t *)(pct0))->params;
109
pparams1 = &((const gs_overprint_t *)(pct1))->params;
110
if (!pparams0->retain_any_comps)
111
return !pparams1->retain_any_comps;
112
else if (pparams0->retain_spot_comps)
113
return pparams1->retain_spot_comps;
115
return pparams0->drawn_comps == pparams1->drawn_comps;
121
* Bits corresponding to boolean values in the first byte of the string
122
* representation of an overprint compositor.
124
#define OVERPRINT_ANY_COMPS 1
125
#define OVERPRINT_SPOT_COMPS 2
128
* Convert an overprint compositor to string form for use by the command
132
c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
134
const gs_overprint_params_t * pparams = &((const gs_overprint_t *)pct)->params;
136
int used = 1, avail = *psize;
138
/* encoded the booleans in a single byte */
139
if (pparams->retain_any_comps) {
140
flags |= OVERPRINT_ANY_COMPS;
142
/* write out the component bits only if necessary (and possible) */
143
if (pparams->retain_spot_comps)
144
flags |= OVERPRINT_SPOT_COMPS;
146
uint tmp_size = (avail > 0 ? avail - 1 : 0);
147
int code = write_color_index( pparams->drawn_comps,
151
if (code < 0 && code != gs_error_rangecheck)
157
/* check for overflow */
160
return_error(gs_error_rangecheck);
162
if_debug1('v', "[v]c_overprint_write(%d)\n", flags);
167
* Convert the string representation of the overprint parameter into the
172
gs_composite_t ** ppct,
177
gs_overprint_params_t params;
179
int code = 0, nbytes = 1;
182
return_error(gs_error_rangecheck);
184
if_debug1('v', "[v]c_overprint_read(%d)\n", flags);
185
params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0;
186
params.retain_spot_comps = (flags & OVERPRINT_SPOT_COMPS) != 0;
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);
197
code = gs_create_overprint(ppct, ¶ms, mem);
199
return code < 0 ? code : nbytes;
203
* Check for closing compositor.
206
c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev)
208
if (*ppcte != NULL && (*ppcte)->type->comp_id != GX_COMPOSITOR_OVERPRINT)
213
static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
214
static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
215
static composite_equal_proc(c_overprint_equal);
216
static composite_write_proc(c_overprint_write);
217
static composite_is_closing_proc(c_overprint_is_closing);
218
static composite_read_proc(c_overprint_read);
220
/* methods for the overprint compositor */
221
const gs_composite_type_t gs_composite_overprint_type = {
222
GX_COMPOSITOR_OVERPRINT,
224
c_overprint_create_default_compositor, /* procs.create_default_compositor */
225
c_overprint_equal, /* procs.equal */
226
c_overprint_write, /* procs.write */
227
c_overprint_read, /* procs.read */
228
gx_default_composite_adjust_ctm,
229
c_overprint_is_closing,
230
gx_default_composite_is_friendly,
231
gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
232
gx_default_composite_clist_read_update, /* procs.composite_clist_reade_update */
233
gx_default_composite_get_cropping /* procs.composite_get_cropping */
239
* Create an overprint compositor data structure.
241
* Currently this just a stub.
245
gs_composite_t ** ppct,
246
const gs_overprint_params_t * pparams,
249
gs_overprint_t * pct;
251
pct = gs_alloc_struct(mem, gs_overprint_t, &st_overprint,
252
"gs_create_overprint");
254
return_error(gs_error_VMerror);
255
pct->type = &gs_composite_overprint_type;
256
pct->id = gs_next_ids(mem, 1);
257
pct->params = *pparams;
259
*ppct = (gs_composite_t *)pct;
265
* Verify that a compositor data structure is for the overprint compositor.
266
* This is used by the gs_pdf1.4_device (and eventually the PDFWrite
267
* device), which implements overprint and overprint mode directly.
270
gs_is_overprint_compositor(const gs_composite_t * pct)
272
return pct->type == &gs_composite_overprint_type;
277
* The overprint device.
279
* In principle there are two versions of this device: one if the traget
280
* device is separable and linear, the other if it is not. The two have
281
* slightly different data structures, but differ primarily in terms of
282
* the standard set of methods. Because methods are non-static in
283
* GhostScript, we make use of the same data structure and handle the
284
* distinction during initialization.
286
* The data fields reflect entries in the gs_overprint_params_t
287
* structure. There is no explicit retain_any_comps field, as the current
288
* setting of this field can be determined by checking the fill_rectangle
289
* method. There is also no retain_spot_comps field, as the code will
290
* will determine explicitly which components are to be drawn.
292
typedef struct overprint_device_s {
293
gx_device_forward_common;
296
* The set of components to be drawn. This field is used only if the
297
* target color space is not separable and linear.
299
gx_color_index drawn_comps;
302
* The mask of gx_color_index bits to be retained during a drawing
303
* operation. A bit in this mask is 1 if the corresponding bit or
304
* the color index is to be retained; otherwise it is 0.
306
* The "non-drawn" region of the drawing gx_color_index is assumed
307
* to have the value zero, so for a separable and linear color
308
* encoding, the per-pixel drawing operation is:
310
* output = (output & retain_mask) | src
312
* (For the fully general case, replace src by (src & ~retain_mask).)
313
* Because of byte-alignment, byte-order and performance consideration,
314
* the actually implement operation may be more complex, but this does
315
* not change the overall effect.
317
* The actual value of retain_mask will be byte swap if this is
318
* required. It will be required if depth > 8 and the host processor
321
gx_color_index retain_mask;
323
} overprint_device_t;
325
gs_private_st_suffix_add0_final( st_overprint_device_t,
327
"overprint_device_t",
328
overprint_device_t_enum_ptrs,
329
overprint_device_t_reloc_ptrs,
335
* In the default (overprint false) case, the overprint device is almost
336
* a pure forwarding device: only the open_device and create_compositor
337
* methods are not pure-forwarding methods. The
338
* gx_device_foward_fill_in_procs procedure does not fill in all of the
339
* necessary procedures, so some of them are provided explicitly below.
340
* The put_params procedure also requires a small modification, so that
341
* the open/close state of this device always reflects that of its
344
* This and other method arrays are not declared const so that they may
345
* be initialized once via gx_device_forward_fill_in_procs. They are
346
* constant once this initialization is complete.
348
static dev_proc_open_device(overprint_open_device);
349
static dev_proc_put_params(overprint_put_params);
350
static dev_proc_get_page_device(overprint_get_page_device);
351
static dev_proc_create_compositor(overprint_create_compositor);
352
static dev_proc_get_color_comp_index(overprint_get_color_comp_index);
354
static gx_device_procs no_overprint_procs = {
355
overprint_open_device, /* open_device */
356
0, /* get_initial_matrix */
359
0, /* close_device */
360
0, /* map_rgb_color */
361
0, /* map_color_rgb */
362
gx_forward_fill_rectangle, /* fill_rectangle */
363
gx_forward_tile_rectangle, /* tile_rectangle */
364
gx_forward_copy_mono, /* copy_mono */
365
gx_forward_copy_color, /* copy_color */
366
0, /* draw_line (obsolete) */
369
overprint_put_params, /* put_params */
370
0, /* map_cmyk_color */
371
0, /* get_xfont_procs */
372
0, /* get_xfont_device */
373
0, /* map_rgb_alpha_color */
374
overprint_get_page_device, /* get_page_device */
375
0, /* get_alpha_bits (obsolete) */
382
0, /* fill_trapezoid */
383
0, /* fill_parallelogram */
384
0, /* fill_triangle */
385
0, /* draw_thin_line */
387
0, /* image_data (obsolete) */
388
0, /* end_image (obsolete) */
389
gx_forward_strip_tile_rectangle, /* strip_tile_rectangle */
390
0, /* strip_copy_rop */
391
0, /* get_clipping_box */
392
0, /* begin_typed_image */
393
0, /* get_bits_rectangle */
394
0, /* map_color_rgb_alpha */
395
overprint_create_compositor, /* create_compositor */
396
0, /* get_hardware_params */
398
0, /* gx_finish_copydevice */
399
0, /* begin_transparency_group */
400
0, /* end_transparency_group */
401
0, /* being_transparency_mask */
402
0, /* end_transparency_mask */
403
0, /* discard_transparency_layer */
404
0, /* get_color_mapping_procs */
405
overprint_get_color_comp_index, /* get_color_comp_index */
406
0, /* encode_color */
407
0, /* decode_color */
408
0, /* pattern_manage */
409
0, /* fill_rectangle_hl_color */
410
0, /* include_color_space */
411
0, /* fill_linear_color_scanline */
412
0, /* fill_linear_color_trapezoid */
413
0, /* fill_linear_color_triangle */
414
0, /* update_spot_equivalent_colors */
415
0, /* ret_devn_params */
420
* If overprint is set, the high and mid-level rendering methods are
421
* replaced by the default routines. The low-level color rendering methods
422
* are replaced with one of two sets of functions, depending on whether or
423
* not the target device has a separable and linear color encoding.
425
* 1. If the target device does not have a separable and linear
426
* encoding, an overprint-specific fill_rectangle method is used,
427
* and the default methods are used for all other low-level rendering
428
* methods. There is no way to achieve good rendering performance
429
* when overprint is true and the color encoding is not separable
430
* and linear, so there is little reason to use more elaborate
431
* methods int this case.
433
* 2. If the target device does have a separable and linear color
434
* model, at least the fill_rectangle method and potentially other
435
* methods will be replaced by overprint-specific methods. Those
436
* methods not replaced will have their default values. The number
437
* of methods replaced is dependent on the desired level of
438
* performance: the more methods, the better the performance.
440
* Note that certain procedures, such as copy_alpha and copy_rop,
441
* are likely to always be given their default values, as the concepts
442
* of alpha-compositing and raster operations are not compatible in
445
static dev_proc_fill_rectangle(overprint_generic_fill_rectangle);
446
static dev_proc_fill_rectangle(overprint_sep_fill_rectangle);
447
/* other low-level overprint_sep_* rendering methods prototypes go here */
449
static gx_device_procs generic_overprint_procs = {
450
overprint_open_device, /* open_device */
451
0, /* get_initial_matrix */
454
0, /* close_device */
455
0, /* map_rgb_color */
456
0, /* map_color_rgb */
457
overprint_generic_fill_rectangle, /* fill_rectangle */
458
gx_default_tile_rectangle, /* tile_rectangle */
459
gx_default_copy_mono, /* copy_mono */
460
gx_default_copy_color, /* copy_color */
461
gx_default_draw_line, /* draw_line (obsolete) */
464
overprint_put_params, /* put_params */
465
0, /* map_cmyk_color */
466
0, /* get_xfont_procs */
467
gx_default_get_xfont_device, /* get_xfont_device */
468
0, /* map_rgb_alpha_color */
469
overprint_get_page_device, /* get_page_device */
470
0, /* get_alpha_bits (obsolete) */
471
gx_default_copy_alpha, /* copy alpha */
473
gx_default_copy_rop, /* copy_rop */
474
gx_default_fill_path, /* fill_path */
475
gx_default_stroke_path, /* stroke_path */
476
gx_default_fill_mask, /* fill_mask */
477
gx_default_fill_trapezoid, /* fill_trapezoid */
478
gx_default_fill_parallelogram, /* fill_parallelogram */
479
gx_default_fill_triangle, /* fill_triangle */
480
gx_default_draw_thin_line, /* draw_thin_line */
481
gx_default_begin_image, /* begin_image */
482
0, /* image_data (obsolete) */
483
0, /* end_image (obsolete) */
484
gx_default_strip_tile_rectangle, /* strip_tile_rectangle */
485
gx_default_strip_copy_rop, /* strip_copy_rop */
486
0, /* get_clipping_box */
487
gx_default_begin_typed_image, /* begin_typed_image */
488
0, /* get_bits_rectangle */
489
0, /* map_color_rgb_alpha */
490
overprint_create_compositor, /* create_compositor */
491
0, /* get_hardware_params */
492
gx_default_text_begin, /* text_begin */
493
0, /* gx_finish_copydevice */
494
0, /* begin_transparency_group */
495
0, /* end_transparency_group */
496
0, /* begin_transparency_mask */
497
0, /* end_transparency_mask */
498
0, /* discard_transparency_layer */
499
0, /* get_color_mapping_procs */
500
overprint_get_color_comp_index, /* get_color_comp_index */
501
0, /* encode_color */
505
static gx_device_procs sep_overprint_procs = {
506
overprint_open_device, /* open_device */
507
0, /* get_initial_matrix */
510
0, /* close_device */
511
0, /* map_rgb_color */
512
0, /* map_color_rgb */
513
overprint_sep_fill_rectangle, /* fill_rectangle */
514
gx_default_tile_rectangle, /* tile_rectangle */
515
gx_default_copy_mono, /* copy_mono */
516
gx_default_copy_color, /* copy_color */
517
gx_default_draw_line, /* draw_line (obsolete) */
520
overprint_put_params, /* put_params */
521
0, /* map_cmyk_color */
522
0, /* get_xfont_procs */
523
gx_default_get_xfont_device, /* get_xfont_device */
524
0, /* map_rgb_alpha_color */
525
overprint_get_page_device, /* get_page_device */
526
0, /* get_alpha_bits (obsolete) */
527
gx_default_copy_alpha, /* copy alpha */
529
gx_default_copy_rop, /* copy_rop */
530
gx_default_fill_path, /* fill_path */
531
gx_default_stroke_path, /* stroke_path */
532
gx_default_fill_mask, /* fill_mask */
533
gx_default_fill_trapezoid, /* fill_trapezoid */
534
gx_default_fill_parallelogram, /* fill_parallelogram */
535
gx_default_fill_triangle, /* fill_triangle */
536
gx_default_draw_thin_line, /* draw_thin_line */
537
gx_default_begin_image, /* begin_image */
538
0, /* image_data (obsolete) */
539
0, /* end_image (obsolete) */
540
gx_default_strip_tile_rectangle, /* strip_tile_rectangle */
541
gx_default_strip_copy_rop, /* strip_copy_rop */
542
0, /* get_clipping_box */
543
gx_default_begin_typed_image, /* begin_typed_image */
544
0, /* get_bits_rectangle */
545
0, /* map_color_rgb_alpha */
546
overprint_create_compositor, /* create_compositor */
547
0, /* get_hardware_params */
548
gx_default_text_begin, /* text_begin */
549
0, /* gx_finish_copydevice */
550
0, /* begin_transparency_group */
551
0, /* end_transparency_group */
552
0, /* begin_transparency_mask */
553
0, /* end_transparency_mask */
554
0, /* discard_transparency_layer */
555
0, /* get_color_mapping_procs */
556
overprint_get_color_comp_index, /* get_color_comp_index */
557
0, /* encode_color */
562
* The prototype for the overprint device does not provide much
563
* information; it exists primarily to facilitate use gx_init_device
564
* and sundry other device utility routines.
566
const overprint_device_t gs_overprint_device = {
567
std_device_std_body_open( overprint_device_t, /* device type */
568
0, /* static_procs */
569
"overprint_device", /* dname */
570
0, 0, /* width, height */
571
1, 1 ), /* HWResolution */
578
* Utility to reorder bytes in a color or mask based on the endianness of
579
* the current device. This is required on little-endian machines if the
580
* depth is larger 8. The resulting value is also replicated to fill the
581
* entire gx_color_index if the depth is a divisor of the color index
582
* size. If this is not the case, the result will be in the low-order
583
* bytes of the color index.
585
* Though this process can be handled in full generality, the code below
586
* takes advantage of the fact that depths that are > 8 must be a multiple
589
#if !arch_is_big_endian
591
static gx_color_index
592
swap_color_index(int depth, gx_color_index color)
594
int shift = depth - 8;
595
gx_color_index mask = 0xff;
597
color = ((color >> shift) & mask)
598
| ((color & mask) << shift)
599
| (color & ~((mask << shift) | mask));
603
color = ((color >> shift) & mask)
604
| ((color & mask) << shift)
605
| (color & ~((mask << shift) | mask));
610
color = ((color >> shift) & mask)
611
| ((color & mask) << shift)
612
| (color & ~((mask << shift) | mask));
617
color = ((color >> shift) & mask)
618
| ((color & mask) << shift)
619
| (color & ~((mask << shift) | mask));
627
#endif /* !arch_is_big_endian */
630
* Update the retain_mask field to reflect the information in the
631
* drawn_comps field. This is useful only if the device color model
635
set_retain_mask(overprint_device_t * opdev)
637
int i, ncomps = opdev->color_info.num_components;
638
gx_color_index drawn_comps = opdev->drawn_comps, retain_mask = 0;
639
#if !arch_is_big_endian
640
int depth = opdev->color_info.depth;
643
for (i = 0; i < ncomps; i++, drawn_comps >>= 1) {
644
if ((drawn_comps & 0x1) == 0)
645
retain_mask |= opdev->color_info.comp_mask[i];
647
#if !arch_is_big_endian
649
retain_mask = swap_color_index(depth, retain_mask);
651
opdev->retain_mask = retain_mask;
654
/* enlarge mask of non-zero components */
655
static gx_color_index
656
check_drawn_comps(int ncomps, frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS])
659
gx_color_index mask = 0x1, drawn_comps = 0;
661
for (i = 0; i < ncomps; i++, mask <<= 1) {
662
if (cvals[i] != frac_0)
669
* Update the overprint-specific device parameters.
671
* If spot colors are to be retain, the set of process (non-spot) colors is
672
* determined by mapping through the standard color spaces and check which
673
* components assume non-zero values.
676
update_overprint_params(
677
overprint_device_t * opdev,
678
const gs_overprint_params_t * pparams )
680
int ncomps = opdev->color_info.num_components;
682
/* check if overprint is to be turned off */
683
if (!pparams->retain_any_comps || pparams->idle) {
684
/* if fill_rectangle forwards, overprint is already off */
685
if (dev_proc(opdev, fill_rectangle) != gx_forward_fill_rectangle)
686
memcpy( &opdev->procs,
688
sizeof(no_overprint_procs) );
692
/* set the procedures according to the color model */
693
if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
694
memcpy( &opdev->procs,
695
&sep_overprint_procs,
696
sizeof(sep_overprint_procs) );
698
memcpy( &opdev->procs,
699
&generic_overprint_procs,
700
sizeof(generic_overprint_procs) );
702
/* see if we need to determine the spot color components */
703
if (!pparams->retain_spot_comps)
704
opdev->drawn_comps = pparams->drawn_comps;
706
gx_device * dev = (gx_device *)opdev;
707
const gx_cm_color_map_procs * pprocs;
708
frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
709
gx_color_index drawn_comps = 0;
710
static const frac frac_13 = float2frac(1.0 / 3.0);
712
if ((pprocs = dev_proc(opdev, get_color_mapping_procs)(dev)) == 0 ||
713
pprocs->map_gray == 0 ||
714
pprocs->map_rgb == 0 ||
715
pprocs->map_cmyk == 0 )
716
return_error(gs_error_unknownerror);
718
pprocs->map_gray(dev, frac_13, cvals);
719
drawn_comps |= check_drawn_comps(ncomps, cvals);
721
pprocs->map_rgb(dev, 0, frac_13, frac_0, frac_0, cvals);
722
drawn_comps |= check_drawn_comps(ncomps, cvals);
723
pprocs->map_rgb(dev, 0, frac_0, frac_13, frac_0, cvals);
724
drawn_comps |= check_drawn_comps(ncomps, cvals);
725
pprocs->map_rgb(dev, 0, frac_0, frac_0, frac_13, cvals);
726
drawn_comps |= check_drawn_comps(ncomps, cvals);
728
pprocs->map_cmyk(dev, frac_13, frac_0, frac_0, frac_0, cvals);
729
drawn_comps |= check_drawn_comps(ncomps, cvals);
730
pprocs->map_cmyk(dev, frac_0, frac_13, frac_0, frac_0, cvals);
731
drawn_comps |= check_drawn_comps(ncomps, cvals);
732
pprocs->map_cmyk(dev, frac_0, frac_0, frac_13, frac_0, cvals);
733
drawn_comps |= check_drawn_comps(ncomps, cvals);
734
pprocs->map_cmyk(dev, frac_0, frac_0, frac_0, frac_13, cvals);
735
drawn_comps |= check_drawn_comps(ncomps, cvals);
737
opdev->drawn_comps = drawn_comps;
740
/* check for degenerate case */
741
if (opdev->drawn_comps == ((gx_color_index)1 << ncomps) - 1) {
742
memcpy( &opdev->procs,
744
sizeof(no_overprint_procs) );
748
/* if appropriate, update the retain_mask field */
749
if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
750
set_retain_mask(opdev);
757
* The open_device method for the overprint device is about as close to
758
* a pure "forwarding" open_device operation as is possible. Its only
759
* significant function is to ensure that the is_open field of the
760
* overprint device matches that of the target device.
762
* We assume this procedure is called only if the device is not already
763
* open, and that gs_opendevice will take care of the is_open flag.
766
overprint_open_device(gx_device * dev)
768
overprint_device_t * opdev = (overprint_device_t *)dev;
769
gx_device * tdev = opdev->target;
772
/* the overprint device must have a target */
774
return_error(gs_error_unknownerror);
775
if ((code = gs_opendevice(tdev)) >= 0)
776
gx_device_copy_params(dev, tdev);
781
* The put_params method for the overprint device will check if the
782
* target device has closed and, if so, close itself.
785
overprint_put_params(gx_device * dev, gs_param_list * plist)
787
overprint_device_t * opdev = (overprint_device_t *)dev;
788
gx_device * tdev = opdev->target;
792
if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
793
gx_device_decache_colors(dev);
795
code = gs_closedevice(dev);
801
* If the target device 'auto detects' new spot colors, then it will
802
* change its color_info data. Make sure that we have a current copy.
805
overprint_get_color_comp_index(gx_device * dev, const char * pname,
806
int name_size, int component_type)
808
overprint_device_t * opdev = (overprint_device_t *)dev;
809
gx_device * tdev = opdev->target;
813
code = gx_error_get_color_comp_index(dev, pname,
814
name_size, component_type);
816
code = dev_proc(tdev, get_color_comp_index)(tdev, pname,
817
name_size, component_type);
818
opdev->color_info = tdev->color_info;
824
* The overprint device must never be confused with a page device.
825
* Thus, we always forward the request for the page device to the
826
* target, as should all forwarding devices.
829
overprint_get_page_device(gx_device * dev)
831
overprint_device_t * opdev = (overprint_device_t *)dev;
832
gx_device * tdev = opdev->target;
834
return tdev == 0 ? 0 : dev_proc(tdev, get_page_device)(tdev);
838
* Calling create_compositor on the overprint device just updates the
839
* overprint parameters; no new device is created.
842
overprint_create_compositor(
845
const gs_composite_t * pct,
846
gs_imager_state * pis,
847
gs_memory_t * memory )
849
if (pct->type != &gs_composite_overprint_type)
850
return gx_default_create_compositor(dev, pcdev, pct, pis, memory);
852
gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params;
855
params.idle = pct->idle;
856
/* device must already exist, so just update the parameters */
857
code = update_overprint_params(
858
(overprint_device_t *)dev,
868
* The two rectangle-filling routines (which do the actual work) are just
869
* stubbs for the time being. The actual routines would allocate a buffer,
870
* use get_bits_rectangle to build a buffer of the existing data, modify
871
* the appropriate components, then invoke the copy_color procedure on the
875
overprint_generic_fill_rectangle(
881
gx_color_index color )
883
overprint_device_t * opdev = (overprint_device_t *)dev;
884
gx_device * tdev = opdev->target;
889
return gx_overprint_generic_fill_rectangle( tdev,
897
overprint_sep_fill_rectangle(
903
gx_color_index color )
905
overprint_device_t * opdev = (overprint_device_t *)dev;
906
gx_device * tdev = opdev->target;
911
int depth = tdev->color_info.depth;
914
* Swap the color index into the order required by a byte-oriented
915
* bitmap. This is required only for littl-endian processors, and
916
* then only if the depth > 8.
918
#if !arch_is_big_endian
920
color = swap_color_index(depth, color);
924
* We can handle rectangle filling via bits_fill_rectangle_masked
925
* if the depth is a divisor of 8 * sizeof(mono_fill_chunk). The
926
* non-masked fill_rectangle code uses a byte-oriented routine
927
* if depth > 8, but there is not much advantage to doing so if
928
* masking is required.
930
* Directly testing (8 * sizeof(mono_fill_chunk)) % depth is
931
* potentially expensive, since many rectangles are small. We
932
* can avoid the modulus operation by noting that
933
* 8 * sizeof(mono_fill_chunk) will be a power of 2, and so
934
* we need only check that depth is a power of 2 and
935
* depth < 8 * sizeof(mono_fill_chunk).
937
if ( depth <= 8 * sizeof(mono_fill_chunk) &&
938
(depth & (depth - 1)) == 0 )
939
return gx_overprint_sep_fill_rectangle_1( tdev,
945
return gx_overprint_sep_fill_rectangle_2( tdev,
954
/* complete a porcedure set */
956
fill_in_procs(gx_device_procs * pprocs)
958
gx_device_forward tmpdev;
961
* gx_device_forward_fill_in_procs calls gx_device_fill_in_procs, which
962
* requires the color_info field of the device be set to "reasonable"
963
* values. Which values is irrelevant in this case, but they must not
964
* contain dangling pointers, excessive numbers of components, etc.
966
memcpy( &tmpdev.color_info,
967
&gs_overprint_device.color_info,
968
sizeof(tmpdev.color_info) );
970
* Prevent the check_device_separable routine from executing while we
971
* fill in the procs. Our tmpdev is not complete enough for it.
973
tmpdev.color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
974
tmpdev.static_procs = 0;
975
memcpy(&tmpdev.procs, pprocs, sizeof(tmpdev.procs));
976
gx_device_forward_fill_in_procs(&tmpdev);
977
memcpy(pprocs, &tmpdev.procs, sizeof(tmpdev.procs));
981
* Create an overprint compositor.
983
* Note that this routine will be called only if the device is not already
984
* an overprint compositor. Hence, if pct->params.retain_any_comps is
985
* false, we can just return.
987
* We also suppress use of overprint if the current device color model has only
988
* a single component. In this case overprint mode is inapplicable (it applies
989
* only to CMYK devices), and nothing can possibly be gained by using overprint.
990
* More significantly, this cause avoids erroneous use of overprint when a
991
* mask caching device is the current device, which would otherwise require
992
* elaborate special handling in the caching device create_compositor
996
c_overprint_create_default_compositor(
997
const gs_composite_t * pct,
1000
gs_imager_state * pis,
1003
const gs_overprint_t * ovrpct = (const gs_overprint_t *)pct;
1004
overprint_device_t * opdev = 0;
1005
gs_overprint_params_t params;
1007
/* see if there is anything to do */
1008
if ( !ovrpct->params.retain_any_comps) {
1017
/* check if the procedure arrays have been initialized */
1018
if (no_overprint_procs.get_xfont_procs == 0) {
1019
fill_in_procs(&no_overprint_procs);
1020
fill_in_procs(&generic_overprint_procs);
1021
fill_in_procs(&sep_overprint_procs);
1024
/* build the overprint device */
1025
opdev = gs_alloc_struct_immovable( mem,
1027
&st_overprint_device_t,
1028
"create overprint compositor" );
1029
if ((*popdev = (gx_device *)opdev) == 0)
1030
return_error(gs_error_VMerror);
1031
gx_device_init( (gx_device *)opdev,
1032
(const gx_device *)&gs_overprint_device,
1035
gx_device_copy_params((gx_device *)opdev, tdev);
1036
gx_device_set_target((gx_device_forward *)opdev, tdev);
1038
params = ovrpct->params;
1039
params.idle = ovrpct->idle;
1041
/* set up the overprint parameters */
1042
return update_overprint_params( opdev, ¶ms);