~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gsovrc.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
  
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
7
   This software is distributed under license and may not be copied, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
 
 
14
/* $Id: gsovrc.c 9288 2008-12-13 20:05:37Z leonardo $ */
 
15
/* overprint/overprint mode compositor implementation */
 
16
 
 
17
#include "memory_.h"
 
18
#include "gx.h"
 
19
#include "gserrors.h"
 
20
#include "gsutil.h"             /* for gs_next_ids */
 
21
#include "gxcomp.h"
 
22
#include "gxdevice.h"
 
23
#include "gsdevice.h"
 
24
#include "gxgetbit.h"
 
25
#include "gsovrc.h"
 
26
#include "gxdcolor.h"
 
27
#include "gxoprect.h"
 
28
#include "gsbitops.h"
 
29
#include "gxistate.h"
 
30
 
 
31
 
 
32
/* GC descriptor for gs_overprint_t */
 
33
private_st_gs_overprint_t();
 
34
 
 
35
/*
 
36
 * Utility routine for encoding or decoding a color index. We cannot use
 
37
 * the general integer encoding routins for these, as they may be 64 bits
 
38
 * in length (the general routines are only designed for 32 bits). We also
 
39
 * cannot use the color-specific routines, as we do not have the required
 
40
 * device color information available.
 
41
 *
 
42
 * The scheme employed is the potentially 64-bit analog of the 32-bit
 
43
 * routines: the low order seven bits of each bytes represents a base-128
 
44
 * digit, and the high order bit is set if there is another digit. The
 
45
 * encoding order is little-endian.
 
46
 *
 
47
 * The write routine returns 0 on success, with *psize set to the number
 
48
 * of bytes used. Alternatively, the return value will be gs_error_rangecheck,
 
49
 * with *psize set to the number of bytes required, if there was insufficient
 
50
 * space.
 
51
 *
 
52
 * The read routine returns the number of bytes read on success, or < 0 in
 
53
 * the event of an error.
 
54
 */
 
55
static int
 
56
write_color_index(gx_color_index cindex, byte * data, uint * psize)
 
57
{
 
58
    int             num_bytes = 0;
 
59
    gx_color_index  ctmp = cindex;
 
60
 
 
61
    for (num_bytes = 1; (ctmp >>= 7) != 0; ++num_bytes)
 
62
        ;
 
63
    if (num_bytes > *psize) {
 
64
        *psize = num_bytes;
 
65
        return gs_error_rangecheck;
 
66
    }
 
67
    ctmp = cindex;
 
68
    *psize = num_bytes;
 
69
    for (; num_bytes > 1; ctmp >>= 7, --num_bytes)
 
70
        *data++ = 0x80 | (ctmp & 0x7f);
 
71
    *data = ctmp & 0x7f;
 
72
    return 0;
 
73
}
 
74
 
 
75
static int
 
76
read_color_index(gx_color_index * pcindex, const byte * data, uint size)
 
77
{
 
78
    gx_color_index  cindex = 0;
 
79
    int             nbytes = 0, shift = 0;
 
80
 
 
81
    for (;; shift += 7, data++) {
 
82
        if (++nbytes > size)
 
83
            return_error(gs_error_rangecheck);
 
84
        else {
 
85
            int     c = *data;
 
86
 
 
87
            cindex += (c & 0x7f) << shift;
 
88
            if ((c & 0x80) == 0)
 
89
                break;
 
90
        }
 
91
    }
 
92
    *pcindex = cindex;
 
93
    return nbytes;
 
94
}
 
95
 
 
96
/*
 
97
 * Check for equality of two overprint compositor objects.
 
98
 *
 
99
 * This is fairly simple.
 
100
 */
 
101
static bool
 
102
c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
 
103
{
 
104
    if (pct0->type == pct1->type) {
 
105
        const gs_overprint_params_t *    pparams0;
 
106
        const gs_overprint_params_t *    pparams1;
 
107
 
 
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;
 
114
        else
 
115
            return pparams0->drawn_comps == pparams1->drawn_comps;
 
116
    } else
 
117
        return false;
 
118
}
 
119
 
 
120
/*
 
121
 * Bits corresponding to boolean values in the first byte of the string
 
122
 * representation of an overprint compositor.
 
123
 */
 
124
#define OVERPRINT_ANY_COMPS     1
 
125
#define OVERPRINT_SPOT_COMPS    2
 
126
 
 
127
/*
 
128
 * Convert an overprint compositor to string form for use by the command
 
129
 * list device.
 
130
 */
 
131
static int
 
132
c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
 
133
{
 
134
    const gs_overprint_params_t *   pparams = &((const gs_overprint_t *)pct)->params;
 
135
    byte                            flags = 0;
 
136
    int                             used = 1, avail = *psize;
 
137
 
 
138
    /* encoded the booleans in a single byte */
 
139
    if (pparams->retain_any_comps) {
 
140
        flags |= OVERPRINT_ANY_COMPS;
 
141
 
 
142
        /* write out the component bits only if necessary (and possible) */
 
143
        if (pparams->retain_spot_comps)
 
144
            flags |= OVERPRINT_SPOT_COMPS;
 
145
        else {
 
146
            uint    tmp_size = (avail > 0 ? avail - 1 : 0);
 
147
            int     code = write_color_index( pparams->drawn_comps,
 
148
                                              data + 1,
 
149
                                              &tmp_size );
 
150
 
 
151
            if (code < 0 && code != gs_error_rangecheck)
 
152
                return code;
 
153
            used += tmp_size;
 
154
        }            
 
155
    }
 
156
 
 
157
    /* check for overflow */
 
158
    *psize = used;
 
159
    if (used > avail)
 
160
        return_error(gs_error_rangecheck);
 
161
    data[0] = flags;
 
162
    if_debug1('v', "[v]c_overprint_write(%d)\n", flags);
 
163
    return 0;
 
164
}
 
165
 
 
166
/*
 
167
 * Convert the string representation of the overprint parameter into the
 
168
 * full compositor.
 
169
 */
 
170
static int
 
171
c_overprint_read(
 
172
    gs_composite_t **       ppct,
 
173
    const byte *            data,
 
174
    uint                    size,
 
175
    gs_memory_t *           mem )
 
176
{
 
177
    gs_overprint_params_t   params;
 
178
    byte                    flags = 0;
 
179
    int                     code = 0, nbytes = 1;
 
180
 
 
181
    if (size < 1)
 
182
        return_error(gs_error_rangecheck);
 
183
    flags = *data;
 
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;
 
187
    params.idle = 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
 * Check for closing compositor. 
 
204
 */
 
205
static int
 
206
c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev)
 
207
{
 
208
    if (*ppcte != NULL && (*ppcte)->type->comp_id != GX_COMPOSITOR_OVERPRINT)
 
209
        return 0;
 
210
    return 3;
 
211
}
 
212
 
 
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);
 
219
 
 
220
/* methods for the overprint compositor */
 
221
const gs_composite_type_t   gs_composite_overprint_type = {
 
222
    GX_COMPOSITOR_OVERPRINT,
 
223
    {
 
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 */
 
234
    }                                           /* procs */
 
235
};
 
236
 
 
237
 
 
238
/*
 
239
 * Create an overprint compositor data structure.
 
240
 *
 
241
 * Currently this just a stub.
 
242
 */
 
243
int
 
244
gs_create_overprint(
 
245
    gs_composite_t **               ppct,
 
246
    const gs_overprint_params_t *   pparams,
 
247
    gs_memory_t *                   mem )
 
248
{
 
249
    gs_overprint_t *                pct;
 
250
 
 
251
    pct = gs_alloc_struct(mem, gs_overprint_t, &st_overprint,
 
252
                             "gs_create_overprint");
 
253
    if (pct == NULL)
 
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;
 
258
    pct->idle = false;
 
259
    *ppct = (gs_composite_t *)pct;
 
260
    return 0;
 
261
}
 
262
 
 
263
 
 
264
/*
 
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.
 
268
 */
 
269
int
 
270
gs_is_overprint_compositor(const gs_composite_t * pct)
 
271
{
 
272
    return pct->type == &gs_composite_overprint_type;
 
273
}
 
274
 
 
275
 
 
276
/*
 
277
 * The overprint device.
 
278
 *
 
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.
 
285
 *
 
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.
 
291
 */
 
292
typedef struct overprint_device_s {
 
293
    gx_device_forward_common;
 
294
 
 
295
    /*
 
296
     * The set of components to be drawn. This field is used only if the
 
297
     * target color space is not separable and linear.
 
298
     */
 
299
    gx_color_index  drawn_comps;
 
300
 
 
301
    /*
 
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.
 
305
     *
 
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:
 
309
     *
 
310
     *  output = (output & retain_mask) | src
 
311
     *
 
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.
 
316
     *
 
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
 
319
     * is little-endian.
 
320
     */
 
321
    gx_color_index  retain_mask;
 
322
 
 
323
} overprint_device_t;
 
324
 
 
325
gs_private_st_suffix_add0_final( st_overprint_device_t,
 
326
                                 overprint_device_t,
 
327
                                 "overprint_device_t",
 
328
                                 overprint_device_t_enum_ptrs,
 
329
                                 overprint_device_t_reloc_ptrs,
 
330
                                 gx_device_finalize,
 
331
                                 st_device_forward );
 
332
 
 
333
 
 
334
/*
 
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
 
342
 * target.
 
343
 *
 
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.
 
347
 */
 
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);
 
353
 
 
354
static gx_device_procs no_overprint_procs = {
 
355
    overprint_open_device,              /* open_device */
 
356
    0,                                  /* get_initial_matrix */
 
357
    0,                                  /* sync_output */
 
358
    0,                                  /* output_page */
 
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) */
 
367
    0,                                  /* get_bits */
 
368
    0,                                  /* get_params */
 
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) */
 
376
    0,                                  /* copy alpha */
 
377
    0,                                  /* get_band */
 
378
    0,                                  /* copy_rop */
 
379
    0,                                  /* fill_path */
 
380
    0,                                  /* stroke_path */
 
381
    0,                                  /* fill_mask */
 
382
    0,                                  /* fill_trapezoid */
 
383
    0,                                  /* fill_parallelogram */
 
384
    0,                                  /* fill_triangle */
 
385
    0,                                  /* draw_thin_line */
 
386
    0,                                  /* begin_image */
 
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 */
 
397
    0,                                  /* text_begin */
 
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 */
 
416
    gx_forward_fillpage
 
417
};
 
418
 
 
419
/*
 
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.
 
424
 *
 
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.
 
432
 *
 
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.
 
439
 *
 
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
 
443
 *     a strict sense.
 
444
 */
 
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 */
 
448
 
 
449
static gx_device_procs generic_overprint_procs = {
 
450
    overprint_open_device,              /* open_device */
 
451
    0,                                  /* get_initial_matrix */
 
452
    0,                                  /* sync_output */
 
453
    0,                                  /* output_page */
 
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) */
 
462
    0,                                  /* get_bits */
 
463
    0,                                  /* get_params */
 
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 */
 
472
    0,                                  /* get_band */
 
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 */
 
502
    0                                   /* decode_color */
 
503
};
 
504
 
 
505
static gx_device_procs sep_overprint_procs = {
 
506
    overprint_open_device,              /* open_device */
 
507
    0,                                  /* get_initial_matrix */
 
508
    0,                                  /* sync_output */
 
509
    0,                                  /* output_page */
 
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) */
 
518
    0,                                  /* get_bits */
 
519
    0,                                  /* get_params */
 
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 */
 
528
    0,                                  /* get_band */
 
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 */
 
558
    0                                   /* decode_color */
 
559
};
 
560
 
 
561
/*
 
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.
 
565
 */
 
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 */
 
572
    { 0 }                                           /* procs */
 
573
};
 
574
 
 
575
 
 
576
 
 
577
/*
 
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.
 
584
 *
 
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
 
587
 * of 8 and <= 64
 
588
 */
 
589
#if !arch_is_big_endian
 
590
 
 
591
static gx_color_index
 
592
swap_color_index(int depth, gx_color_index color)
 
593
{
 
594
    int             shift = depth - 8;
 
595
    gx_color_index  mask = 0xff;
 
596
 
 
597
    color =  ((color >> shift) & mask)
 
598
           | ((color & mask) << shift)
 
599
           | (color & ~((mask << shift) | mask));
 
600
    if (depth > 24) {
 
601
        shift -= 16;
 
602
        mask <<= 8;
 
603
        color =  ((color >> shift) & mask)
 
604
               | ((color & mask) << shift)
 
605
               | (color & ~((mask << shift) | mask));
 
606
 
 
607
        if (depth > 40) {
 
608
            shift -= 16;
 
609
            mask <<= 8;
 
610
            color =  ((color >> shift) & mask)
 
611
                   | ((color & mask) << shift)
 
612
                   | (color & ~((mask << shift) | mask));
 
613
 
 
614
            if (depth > 56) {
 
615
                shift -= 16;
 
616
                mask <<= 8;
 
617
                color =  ((color >> shift) & mask)
 
618
                       | ((color & mask) << shift)
 
619
                       | (color & ~((mask << shift) | mask));
 
620
            }
 
621
        }
 
622
    }
 
623
 
 
624
    return color;
 
625
}
 
626
 
 
627
#endif  /* !arch_is_big_endian */
 
628
 
 
629
/*
 
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
 
632
 * is separable.
 
633
 */
 
634
static void
 
635
set_retain_mask(overprint_device_t * opdev)
 
636
{
 
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;
 
641
#endif
 
642
 
 
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];
 
646
    }
 
647
#if !arch_is_big_endian
 
648
    if (depth > 8)
 
649
        retain_mask = swap_color_index(depth, retain_mask);
 
650
#endif
 
651
    opdev->retain_mask = retain_mask;
 
652
}
 
653
 
 
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])
 
657
{
 
658
    int              i;
 
659
    gx_color_index   mask = 0x1, drawn_comps = 0;
 
660
 
 
661
    for (i = 0; i < ncomps; i++, mask <<= 1) {
 
662
        if (cvals[i] != frac_0)
 
663
            drawn_comps |= mask;
 
664
    }
 
665
    return drawn_comps;
 
666
}
 
667
 
 
668
/*
 
669
 * Update the overprint-specific device parameters.
 
670
 *
 
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.
 
674
 */
 
675
static int
 
676
update_overprint_params(
 
677
    overprint_device_t *            opdev,
 
678
    const gs_overprint_params_t *   pparams )
 
679
{
 
680
    int                             ncomps = opdev->color_info.num_components;
 
681
 
 
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,
 
687
                    &no_overprint_procs,
 
688
                    sizeof(no_overprint_procs) );
 
689
        return 0;
 
690
    }
 
691
 
 
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) );
 
697
    else
 
698
        memcpy( &opdev->procs,
 
699
                &generic_overprint_procs,
 
700
                sizeof(generic_overprint_procs) );
 
701
 
 
702
    /* see if we need to determine the spot color components */
 
703
    if (!pparams->retain_spot_comps)
 
704
        opdev->drawn_comps = pparams->drawn_comps;
 
705
    else {
 
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);
 
711
 
 
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);
 
717
 
 
718
        pprocs->map_gray(dev, frac_13, cvals);
 
719
        drawn_comps |= check_drawn_comps(ncomps, cvals);
 
720
 
 
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);
 
727
 
 
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);
 
736
 
 
737
        opdev->drawn_comps = drawn_comps;
 
738
    }
 
739
 
 
740
    /* check for degenerate case */
 
741
    if (opdev->drawn_comps == ((gx_color_index)1 << ncomps) - 1) {
 
742
        memcpy( &opdev->procs,
 
743
                &no_overprint_procs,
 
744
                sizeof(no_overprint_procs) );
 
745
        return 0;
 
746
    }
 
747
 
 
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);
 
751
 
 
752
    return 0;
 
753
}
 
754
 
 
755
 
 
756
/*
 
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.
 
761
 *
 
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.
 
764
 */
 
765
static int
 
766
overprint_open_device(gx_device * dev)
 
767
{
 
768
    overprint_device_t *    opdev = (overprint_device_t *)dev;
 
769
    gx_device *             tdev = opdev->target;
 
770
    int                     code = 0;
 
771
 
 
772
    /* the overprint device must have a target */
 
773
    if (tdev == 0)
 
774
        return_error(gs_error_unknownerror);
 
775
    if ((code = gs_opendevice(tdev)) >= 0)
 
776
        gx_device_copy_params(dev, tdev);
 
777
    return code;
 
778
}
 
779
 
 
780
/*
 
781
 * The put_params method for the overprint device will check if the
 
782
 * target device has closed and, if so, close itself.
 
783
 */
 
784
static int
 
785
overprint_put_params(gx_device * dev, gs_param_list * plist)
 
786
{
 
787
    overprint_device_t *    opdev = (overprint_device_t *)dev;
 
788
    gx_device *             tdev = opdev->target;
 
789
    int                     code = 0;
 
790
 
 
791
 
 
792
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
 
793
        gx_device_decache_colors(dev);
 
794
        if (!tdev->is_open)
 
795
            code = gs_closedevice(dev);
 
796
    }
 
797
    return code;
 
798
}
 
799
 
 
800
/*
 
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.
 
803
 */
 
804
int
 
805
overprint_get_color_comp_index(gx_device * dev, const char * pname,
 
806
                                        int name_size, int component_type)
 
807
{
 
808
    overprint_device_t * opdev = (overprint_device_t *)dev;
 
809
    gx_device * tdev = opdev->target;
 
810
    int code;
 
811
 
 
812
    if (tdev == 0)
 
813
        code = gx_error_get_color_comp_index(dev, pname,
 
814
                                name_size, component_type);
 
815
    else {
 
816
        code = dev_proc(tdev, get_color_comp_index)(tdev, pname,
 
817
                                name_size, component_type);
 
818
        opdev->color_info = tdev->color_info;
 
819
    }
 
820
    return code;
 
821
}
 
822
 
 
823
/*
 
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.
 
827
 */
 
828
static gx_device *
 
829
overprint_get_page_device(gx_device * dev)
 
830
{
 
831
    overprint_device_t *    opdev = (overprint_device_t *)dev;
 
832
    gx_device *             tdev = opdev->target;
 
833
 
 
834
    return tdev == 0 ? 0 : dev_proc(tdev, get_page_device)(tdev);
 
835
}
 
836
 
 
837
/*
 
838
 * Calling create_compositor on the overprint device just updates the
 
839
 * overprint parameters; no new device is created.
 
840
 */
 
841
static int
 
842
overprint_create_compositor(
 
843
    gx_device *             dev,
 
844
    gx_device **            pcdev,
 
845
    const gs_composite_t *  pct,
 
846
    gs_imager_state *       pis,
 
847
    gs_memory_t *           memory )
 
848
{
 
849
    if (pct->type != &gs_composite_overprint_type)
 
850
        return gx_default_create_compositor(dev, pcdev, pct, pis, memory);
 
851
    else {
 
852
        gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params;
 
853
        int     code;
 
854
 
 
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,
 
859
                       &params );
 
860
        if (code >= 0)
 
861
            *pcdev = dev;
 
862
        return code;
 
863
    }
 
864
}
 
865
 
 
866
 
 
867
/*
 
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
 
872
 * target device.
 
873
 */
 
874
static int
 
875
overprint_generic_fill_rectangle(
 
876
    gx_device *     dev,
 
877
    int             x,
 
878
    int             y,
 
879
    int             width,
 
880
    int             height,
 
881
    gx_color_index  color )
 
882
{
 
883
    overprint_device_t *    opdev = (overprint_device_t *)dev;
 
884
    gx_device *             tdev = opdev->target;
 
885
 
 
886
    if (tdev == 0)
 
887
        return 0;
 
888
    else
 
889
        return gx_overprint_generic_fill_rectangle( tdev,
 
890
                                                    opdev->drawn_comps,
 
891
                                                    x, y, width, height,
 
892
                                                    color,
 
893
                                                    dev->memory );
 
894
}
 
895
 
 
896
static int
 
897
overprint_sep_fill_rectangle(
 
898
    gx_device *     dev,
 
899
    int             x,
 
900
    int             y,
 
901
    int             width,
 
902
    int             height,
 
903
    gx_color_index  color )
 
904
{
 
905
    overprint_device_t *    opdev = (overprint_device_t *)dev;
 
906
    gx_device *             tdev = opdev->target;
 
907
 
 
908
    if (tdev == 0)
 
909
        return 0;
 
910
    else {
 
911
        int     depth = tdev->color_info.depth;
 
912
 
 
913
        /*
 
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.
 
917
         */
 
918
#if !arch_is_big_endian
 
919
        if (depth > 8)
 
920
            color = swap_color_index(depth, color);
 
921
#endif
 
922
 
 
923
        /*
 
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.
 
929
         *
 
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).
 
936
         */
 
937
        if ( depth <= 8 * sizeof(mono_fill_chunk) &&
 
938
             (depth & (depth - 1)) == 0             )
 
939
            return gx_overprint_sep_fill_rectangle_1( tdev,
 
940
                                                      opdev->retain_mask,
 
941
                                                      x, y, width, height,
 
942
                                                      color,
 
943
                                                      dev->memory );
 
944
        else
 
945
            return gx_overprint_sep_fill_rectangle_2( tdev,
 
946
                                                      opdev->retain_mask,
 
947
                                                      x, y, width, height,
 
948
                                                      color,
 
949
                                                      dev->memory );
 
950
    }
 
951
}
 
952
 
 
953
 
 
954
/* complete a porcedure set */
 
955
static void
 
956
fill_in_procs(gx_device_procs * pprocs)
 
957
{
 
958
    gx_device_forward   tmpdev;
 
959
 
 
960
    /*
 
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.
 
965
     */
 
966
    memcpy( &tmpdev.color_info,
 
967
            &gs_overprint_device.color_info,
 
968
            sizeof(tmpdev.color_info) );
 
969
    /*
 
970
     * Prevent the check_device_separable routine from executing while we
 
971
     * fill in the procs.  Our tmpdev is not complete enough for it.
 
972
     */
 
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));
 
978
}
 
979
 
 
980
/*
 
981
 * Create an overprint compositor.
 
982
 *
 
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.
 
986
 *
 
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
 
993
 * procedure.
 
994
 */
 
995
static int
 
996
c_overprint_create_default_compositor(
 
997
    const gs_composite_t *  pct,
 
998
    gx_device **            popdev,
 
999
    gx_device *             tdev,
 
1000
    gs_imager_state *       pis,
 
1001
    gs_memory_t *           mem )
 
1002
{
 
1003
    const gs_overprint_t *  ovrpct = (const gs_overprint_t *)pct;
 
1004
    overprint_device_t *    opdev = 0;
 
1005
    gs_overprint_params_t params;
 
1006
 
 
1007
    /* see if there is anything to do */
 
1008
    if ( !ovrpct->params.retain_any_comps) {
 
1009
        *popdev = tdev;
 
1010
        return 0;
 
1011
    }
 
1012
    if (pct->idle) {
 
1013
        *popdev = tdev;
 
1014
        return 0;
 
1015
    }
 
1016
 
 
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);
 
1022
    }
 
1023
 
 
1024
    /* build the overprint device */
 
1025
    opdev = gs_alloc_struct_immovable( mem,
 
1026
                                       overprint_device_t,
 
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,
 
1033
                    mem,
 
1034
                    true );
 
1035
    gx_device_copy_params((gx_device *)opdev, tdev);
 
1036
    gx_device_set_target((gx_device_forward *)opdev, tdev);
 
1037
 
 
1038
    params = ovrpct->params;
 
1039
    params.idle = ovrpct->idle;
 
1040
 
 
1041
    /* set up the overprint parameters */
 
1042
    return update_overprint_params( opdev, &params);
 
1043
}