Coverage Report

Created: 2026-02-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gsovrc.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 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,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* overprint/overprint mode compositor implementation */
18
19
#include "assert_.h"
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 "gxgstate.h"
33
#include "gxdevsop.h"
34
#include "gxcldev.h"
35
36
/* GC descriptor for gs_overprint_t */
37
private_st_gs_overprint_t();
38
39
/*
40
 * Utility routine for encoding or decoding a color index. We cannot use
41
 * the general integer encoding routins for these, as they may be 64 bits
42
 * in length (the general routines are only designed for 32 bits). We also
43
 * cannot use the color-specific routines, as we do not have the required
44
 * device color information available.
45
 *
46
 * The scheme employed is the potentially 64-bit analog of the 32-bit
47
 * routines: the low order seven bits of each bytes represents a base-128
48
 * digit, and the high order bit is set if there is another digit. The
49
 * encoding order is little-endian.
50
 *
51
 * The write routine returns 0 on success, with *psize set to the number
52
 * of bytes used. Alternatively, the return value will be gs_error_rangecheck,
53
 * with *psize set to the number of bytes required, if there was insufficient
54
 * space.
55
 *
56
 * The read routine returns the number of bytes read on success, or < 0 in
57
 * the event of an error.
58
 */
59
static int
60
write_color_index(gx_color_index cindex, byte * data, uint * psize)
61
22.3k
{
62
22.3k
    int             num_bytes = 0;
63
22.3k
    gx_color_index  ctmp = cindex;
64
65
22.3k
    for (num_bytes = 1; (ctmp >>= 7) != 0; ++num_bytes)
66
0
        ;
67
22.3k
    if (num_bytes > *psize) {
68
11.1k
        *psize = num_bytes;
69
11.1k
        return_error(gs_error_rangecheck);
70
11.1k
    }
71
11.1k
    ctmp = cindex;
72
11.1k
    *psize = num_bytes;
73
11.1k
    for (; num_bytes > 1; ctmp >>= 7, --num_bytes)
74
0
        *data++ = 0x80 | (ctmp & 0x7f);
75
11.1k
    *data = ctmp & 0x7f;
76
11.1k
    return 0;
77
22.3k
}
78
79
static int
80
read_color_index(gx_color_index * pcindex, const byte * data, uint size)
81
58.0k
{
82
58.0k
    gx_color_index  cindex = 0;
83
58.0k
    int             nbytes = 0, shift = 0;
84
85
58.0k
    for (;; shift += 7, data++) {
86
58.0k
        if (++nbytes > size)
87
0
            return_error(gs_error_rangecheck);
88
58.0k
        else {
89
58.0k
            unsigned char byte = *data;
90
58.0k
            gx_color_index c = byte;
91
92
58.0k
            cindex += (c & 0x7f) << shift;
93
58.0k
            if ((c & 0x80) == 0)
94
58.0k
                break;
95
58.0k
        }
96
58.0k
    }
97
58.0k
    *pcindex = cindex;
98
58.0k
    return nbytes;
99
58.0k
}
100
101
/*
102
 * Check for equality of two overprint compositor objects.
103
 *
104
 * This is fairly simple.
105
 */
106
static bool
107
c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
108
0
{
109
0
    if (pct0->type == pct1->type) {
110
0
        const gs_overprint_params_t *    pparams0;
111
0
        const gs_overprint_params_t *    pparams1;
112
113
0
        pparams0 = &((const gs_overprint_t *)(pct0))->params;
114
0
        pparams1 = &((const gs_overprint_t *)(pct1))->params;
115
116
0
        if (pparams0->is_fill_color != pparams1->is_fill_color)
117
0
            return true;   /* this changed */
118
0
        if (!pparams0->retain_any_comps)
119
0
            return !pparams1->retain_any_comps;
120
0
        else
121
0
            return pparams0->drawn_comps == pparams1->drawn_comps;
122
0
    } else
123
0
        return false;
124
0
}
125
126
/*
127
 * Bits corresponding to boolean values in the first byte of the string
128
 * representation of an overprint compositor.
129
 */
130
90.0M
#define OVERPRINT_ANY_COMPS           1
131
90.4M
#define OVERPRINT_IS_FILL_COLOR       2
132
91.1M
#define OVERPRINT_SET_FILL_COLOR      0xc
133
89.9M
#define OVERPRINT_EOPM                0x10
134
135
/*
136
 * Convert an overprint compositor to string form for use by the command
137
 * list device.
138
 */
139
static int
140
c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
141
1.34M
{
142
1.34M
    const gs_overprint_params_t *   pparams = &((const gs_overprint_t *)pct)->params;
143
1.34M
    byte                            flags = 0;
144
1.34M
    int                             used = 1, avail = *psize;
145
146
    /* Clist writer needs to store active state of op device so that
147
       we know when to send compositor actions to disable it */
148
1.34M
    if (pparams->op_state == OP_STATE_NONE) {
149
673k
        if (pparams->is_fill_color) {
150
512k
            if (pparams->retain_any_comps)
151
21.6k
                cdev->op_fill_active = true;
152
490k
            else
153
490k
                cdev->op_fill_active = false;
154
512k
        } else {
155
161k
            if (pparams->retain_any_comps)
156
702
                cdev->op_stroke_active = true;
157
160k
            else
158
160k
                cdev->op_stroke_active = false;
159
161k
        }
160
673k
    }
161
162
    /* encoded the booleans in a single byte */
163
1.34M
    if (pparams->retain_any_comps || pparams->is_fill_color || pparams->op_state != OP_STATE_NONE) {
164
1.18M
        flags |= (pparams->retain_any_comps) ? OVERPRINT_ANY_COMPS : 0;
165
1.18M
        flags |= (pparams->is_fill_color) ? OVERPRINT_IS_FILL_COLOR : 0;
166
1.18M
        flags |= OVERPRINT_SET_FILL_COLOR & ((pparams->op_state) << 2);
167
1.18M
        flags |= (pparams->effective_opm) << 4;
168
169
        /* write out the component bits */
170
1.18M
        if (pparams->retain_any_comps) {
171
22.3k
            uint tmp_size = (avail > 0 ? avail - 1 : 0);
172
22.3k
            int code = write_color_index(pparams->drawn_comps, data + 1,
173
22.3k
                &tmp_size);
174
22.3k
            if (code < 0 && code != gs_error_rangecheck)
175
0
                return code;
176
22.3k
            used += tmp_size;
177
22.3k
            if_debug0m('v', ((const gx_device*)cdev)->memory, "[v] drawn_comps stored\n");
178
179
22.3k
        }
180
1.18M
    }
181
182
    /* check for overflow */
183
1.34M
    *psize = used;
184
1.34M
    if (used > avail) {
185
673k
        if (avail != 0)
186
0
            return_error(gs_error_rangecheck);
187
673k
        return gs_error_rangecheck;
188
673k
    }
189
673k
    data[0] = flags;
190
673k
    if_debug2m('v', ((const gx_device *)cdev)->memory, "[v]c_overprint_write(%d), drawn_comps=0x%"PRIx64"\n",
191
673k
               flags, (uint64_t)pparams->drawn_comps);
192
673k
    return 0;
193
1.34M
}
194
195
/*
196
 * Convert the string representation of the overprint parameter into the
197
 * full compositor.
198
 */
199
static int
200
c_overprint_read(
201
    gs_composite_t **       ppct,
202
    const byte *            data,
203
    uint                    size,
204
    gs_memory_t *           mem )
205
89.9M
{
206
89.9M
    gs_overprint_params_t   params;
207
89.9M
    byte                    flags = 0;
208
89.9M
    int                     code = 0, nbytes = 1;
209
210
89.9M
    if (size < 1)
211
0
        return_error(gs_error_rangecheck);
212
89.9M
    flags = *data;
213
89.9M
    if_debug1m('v', mem, "[v]c_overprint_read(%d)", flags);
214
89.9M
    params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0;
215
89.9M
    params.is_fill_color = (flags & OVERPRINT_IS_FILL_COLOR) != 0;
216
89.9M
    params.op_state = (flags & OVERPRINT_SET_FILL_COLOR) >> 2;
217
89.9M
    params.effective_opm = (flags & OVERPRINT_EOPM) >> 4;
218
89.9M
    params.idle = 0;
219
89.9M
    params.drawn_comps = 0;
220
221
    /* check if the drawn_comps array is present */
222
89.9M
    if (params.retain_any_comps) {
223
58.0k
        code = read_color_index(&params.drawn_comps, data + 1, size - 1);
224
58.0k
        if (code < 0)
225
0
            return code;
226
58.0k
        nbytes += code;
227
58.0k
        if_debug0m('v', mem, ", drawn_comps read");
228
58.0k
    }
229
89.9M
    if_debug1m('v', mem, ", retain_any_comps=%d", params.retain_any_comps);
230
89.9M
    if_debug1m('v', mem, ", is_fill_color=%d", params.is_fill_color);
231
89.9M
    if_debug1m('v', mem, ", drawn_comps=0x%"PRIx64, (uint64_t)params.drawn_comps);
232
89.9M
    if_debug1m('v', mem, ", op_state=%d", params.op_state);
233
89.9M
    if_debug0m('v', mem, "\n");
234
89.9M
    code = gs_create_overprint(ppct, &params, mem);
235
89.9M
    return code < 0 ? code : nbytes;
236
89.9M
}
237
238
/*
239
 * Check for closing compositor.
240
 */
241
static gs_compositor_closing_state
242
c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev)
243
89.9M
{
244
89.9M
    return COMP_ENQUEUE;  /* maybe extra work, but these actions are fast */
245
89.9M
}
246
247
static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
248
static composite_equal_proc(c_overprint_equal);
249
static composite_write_proc(c_overprint_write);
250
static composite_is_closing_proc(c_overprint_is_closing);
251
static composite_read_proc(c_overprint_read);
252
253
/* methods for the overprint compositor */
254
const gs_composite_type_t   gs_composite_overprint_type = {
255
    GX_COMPOSITOR_OVERPRINT,
256
    {
257
        c_overprint_create_default_compositor,  /* procs.create_default_compositor */
258
        c_overprint_equal,                      /* procs.equal */
259
        c_overprint_write,                      /* procs.write */
260
        c_overprint_read,                       /* procs.read */
261
        gx_default_composite_adjust_ctm,
262
        c_overprint_is_closing,
263
        gx_default_composite_is_friendly,
264
        gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
265
        gx_default_composite_clist_read_update, /* procs.composite_clist_reade_update */
266
        gx_default_composite_get_cropping /* procs.composite_get_cropping */
267
    }                                           /* procs */
268
};
269
270
/*
271
 * Create an overprint compositor data structure.
272
 *
273
 * Currently this just a stub.
274
 */
275
int
276
gs_create_overprint(
277
    gs_composite_t **               ppct,
278
    const gs_overprint_params_t *   pparams,
279
    gs_memory_t *                   mem )
280
90.9M
{
281
90.9M
    gs_overprint_t *                pct;
282
283
90.9M
    pct = gs_alloc_struct(mem, gs_overprint_t, &st_overprint,
284
90.9M
                              "gs_create_overprint");
285
90.9M
    if (pct == NULL)
286
0
        return_error(gs_error_VMerror);
287
90.9M
    pct->type = &gs_composite_overprint_type;
288
90.9M
    pct->id = gs_next_ids(mem, 1);
289
90.9M
    pct->params = *pparams;
290
90.9M
    pct->idle = false;
291
90.9M
    *ppct = (gs_composite_t *)pct;
292
90.9M
    return 0;
293
90.9M
}
294
295
/*
296
 * Verify that a compositor data structure is for the overprint compositor.
297
 * This is used by the gs_pdf1.4_device (and eventually the PDFWrite
298
 * device), which implements overprint and overprint mode directly.
299
 */
300
bool
301
gs_is_overprint_compositor(const gs_composite_t * pct)
302
78.9M
{
303
78.9M
    return pct->type == &gs_composite_overprint_type;
304
78.9M
}
305
306
/*
307
 * The overprint device.
308
 *
309
 * In principle there are two versions of this device: one if the traget
310
 * device is separable and linear, the other if it is not. The two have
311
 * slightly different data structures, but differ primarily in terms of
312
 * the standard set of methods. Because methods are non-static in
313
 * GhostScript, we make use of the same data structure and handle the
314
 * distinction during initialization.
315
 *
316
 * The data fields reflect entries in the gs_overprint_params_t
317
 * structure. There is no explicit retain_any_comps field, as the current
318
 * setting of this field can be determined by checking the fill_rectangle
319
 * method.
320
 */
321
typedef struct overprint_device_s {
322
    gx_device_forward_common;
323
324
    /*
325
     * The set of components to be drawn. This field is used only if the
326
     * target color space is not separable and linear.  It is also used
327
     * for the devn color values since we may need more than 8 components
328
     */
329
    OP_FS_STATE op_state;         /* used to select drawn_comps, fill or stroke */
330
    gx_color_index  drawn_comps_fill;
331
    gx_color_index  drawn_comps_stroke;   /* pparams->is_fill_color determines which to set */
332
    bool retain_none_stroke;                /* These are used to know when we can set the procs to forward */
333
    bool retain_none_fill;
334
335
    /*
336
     * The mask of gx_color_index bits to be retained during a drawing
337
     * operation. A bit in this mask is 1 if the corresponding bit or
338
     * the color index is to be retained; otherwise it is 0.
339
     *
340
     * The "non-drawn" region of the drawing gx_color_index is assumed
341
     * to have the value zero, so for a separable and linear color
342
     * encoding, the per-pixel drawing operation is:
343
     *
344
     *  output = (output & retain_mask) | src
345
     *
346
     * (For the fully general case, replace src by (src & ~retain_mask).)
347
     * Because of byte-alignment, byte-order and performance consideration,
348
     * the actually implement operation may be more complex, but this does
349
     * not change the overall effect.
350
     *
351
     * The actual value of retain_mask will be byte swap if this is
352
     * required. It will be required if depth > 8 and the host processor
353
     * is little-endian.
354
     */
355
    gx_color_index  retain_mask_fill;
356
    gx_color_index  retain_mask_stroke;
357
358
    bool copy_alpha_hl;
359
360
    /* We hold 3 sets of device procedures here. These are initialised from
361
     * the equivalently named globals when the device is created, but are
362
     * then used from here as we fiddle with them. This ensures that the
363
     * globals are only ever read, and as such are safe in multithreaded
364
     * environments. */
365
    gx_device_procs generic_overprint_procs;
366
    gx_device_procs no_overprint_procs;
367
    gx_device_procs sep_overprint_procs;
368
369
    /* Due to the setting of stroke and fill overprint we can get in
370
       a situation where one makes the device idle.  We need to know
371
       if that is the case when doing a compositor push even when
372
       no parameters have changed */
373
    bool is_idle;
374
375
} overprint_device_t;
376
377
gs_private_st_suffix_add0_final( st_overprint_device_t,
378
                                 overprint_device_t,
379
                                 "overprint_device_t",
380
                                 overprint_device_t_enum_ptrs,
381
                                 overprint_device_t_reloc_ptrs,
382
                                 gx_device_finalize,
383
                                 st_device_forward);
384
385
/*
386
 * In the default (overprint false) case, the overprint device is almost
387
 * a pure forwarding device: only the open_device and composite
388
 * methods are not pure-forwarding methods. The
389
 * gx_device_foward_fill_in_procs procedure does not fill in all of the
390
 * necessary procedures, so some of them are provided explicitly below.
391
 * The put_params procedure also requires a small modification, so that
392
 * the open/close state of this device always reflects that of its
393
 * target.
394
 *
395
 * This and other method arrays are not declared const so that they may
396
 * be initialized once via gx_device_forward_fill_in_procs. They are
397
 * constant once this initialization is complete.
398
 */
399
static dev_proc_open_device(overprint_open_device);
400
static dev_proc_put_params(overprint_put_params);
401
static dev_proc_get_page_device(overprint_get_page_device);
402
static dev_proc_composite(overprint_composite);
403
static dev_proc_get_color_comp_index(overprint_get_color_comp_index);
404
static dev_proc_fill_stroke_path(overprint_fill_stroke_path);
405
static dev_proc_fill_path(overprint_fill_path);
406
static dev_proc_stroke_path(overprint_stroke_path);
407
static dev_proc_text_begin(overprint_text_begin);
408
static  dev_proc_dev_spec_op(overprint_dev_spec_op);
409
410
static void
411
nooverprint_initialize_device_procs(gx_device *dev)
412
407
{
413
407
    set_dev_proc(dev, open_device, overprint_open_device);
414
407
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
415
407
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
416
407
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
417
407
    set_dev_proc(dev, put_params, overprint_put_params);
418
407
    set_dev_proc(dev, get_page_device, overprint_get_page_device);
419
407
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
420
407
    set_dev_proc(dev, composite, overprint_composite);
421
407
    set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index);
422
407
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
423
407
    set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op);
424
407
    set_dev_proc(dev, copy_planes, gx_forward_copy_planes);
425
407
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
426
407
    set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path);
427
407
    set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern);
428
407
}
429
430
/*
431
 * If overprint is set, the high and mid-level rendering methods are
432
 * replaced by the default routines. The low-level color rendering methods
433
 * are replaced with one of two sets of functions, depending on whether or
434
 * not the target device has a separable and linear color encoding.
435
 *
436
 *  1. If the target device does not have a separable and linear
437
 *     encoding, an overprint-specific fill_rectangle method is used,
438
 *     and the default methods are used for all other low-level rendering
439
 *     methods. There is no way to achieve good rendering performance
440
 *     when overprint is true and the color encoding is not separable
441
 *     and linear, so there is little reason to use more elaborate
442
 *     methods int this case.
443
 *
444
 *  2. If the target device does have a separable and linear color
445
 *     model, at least the fill_rectangle method and potentially other
446
 *     methods will be replaced by overprint-specific methods. Those
447
 *     methods not replaced will have their default values. The number
448
 *     of methods replaced is dependent on the desired level of
449
 *     performance: the more methods, the better the performance.
450
 *
451
 *     Note that certain procedures, such as copy_alpha and copy_rop,
452
 *     are likely to always be given their default values, as the concepts
453
 *     of alpha-compositing and raster operations are not compatible in
454
 *     a strict sense.
455
 */
456
static dev_proc_fill_rectangle(overprint_generic_fill_rectangle);
457
static dev_proc_fill_rectangle(overprint_sep_fill_rectangle);
458
static dev_proc_fill_rectangle_hl_color(overprint_fill_rectangle_hl_color);
459
static dev_proc_copy_planes(overprint_copy_planes);
460
static dev_proc_copy_alpha_hl_color(overprint_copy_alpha_hl_color);
461
462
/* other low-level overprint_sep_* rendering methods prototypes go here */
463
464
static void
465
generic_overprint_initialize_device_procs(gx_device *dev)
466
407
{
467
    /* Note that we set lots of things to 'default' here. You can't
468
     * omit them, because the caller for this particular initialization
469
     * proc fills them in with 'forward' ones, rather than 'default'
470
     * ones, and that doesn't work. Maybe look into this in future. */
471
407
    set_dev_proc(dev, open_device, overprint_open_device);
472
407
    set_dev_proc(dev, fill_rectangle, overprint_generic_fill_rectangle);
473
407
    set_dev_proc(dev, copy_mono, gx_default_copy_mono);
474
407
    set_dev_proc(dev, copy_color, gx_default_copy_color);
475
407
    set_dev_proc(dev, put_params, overprint_put_params);
476
407
    set_dev_proc(dev, get_page_device, overprint_get_page_device);
477
407
    set_dev_proc(dev, copy_alpha, gx_default_copy_alpha);
478
407
    set_dev_proc(dev, fill_path, overprint_fill_path);
479
407
    set_dev_proc(dev, stroke_path, overprint_stroke_path);
480
407
    set_dev_proc(dev, fill_mask, gx_default_fill_mask);
481
407
    set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
482
407
    set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
483
407
    set_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
484
407
    set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
485
407
    set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle);
486
407
    set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2);
487
407
    set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
488
407
    set_dev_proc(dev, composite, overprint_composite);
489
407
    set_dev_proc(dev, text_begin, overprint_text_begin);
490
407
    set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index);
491
407
    set_dev_proc(dev, fill_rectangle_hl_color, overprint_fill_rectangle_hl_color);
492
407
    set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op);
493
407
    set_dev_proc(dev, copy_planes, gx_forward_copy_planes);
494
407
    set_dev_proc(dev, copy_alpha_hl_color, dev->num_planar_planes ?
495
407
                                               overprint_copy_alpha_hl_color :
496
407
                                               gx_forward_copy_alpha_hl_color);
497
407
    set_dev_proc(dev, fill_stroke_path, overprint_fill_stroke_path);
498
407
}
499
500
static void
501
sep_overprint_initialize_device_procs(gx_device *dev)
502
407
{
503
    /* Note that we set lots of things to 'default' here. You can't
504
     * omit them, because the caller for this particular initialization
505
     * proc fills them in with 'forward' ones, rather than 'default'
506
     * ones, and that doesn't work. Maybe look into this in future. */
507
407
    set_dev_proc(dev, open_device, overprint_open_device);
508
407
    set_dev_proc(dev, fill_rectangle, overprint_sep_fill_rectangle);
509
407
    set_dev_proc(dev, copy_mono, gx_default_copy_mono);
510
407
    set_dev_proc(dev, copy_color, gx_default_copy_color);
511
407
    set_dev_proc(dev, put_params, overprint_put_params);
512
407
    set_dev_proc(dev, get_page_device, overprint_get_page_device);
513
407
    set_dev_proc(dev, copy_alpha, gx_default_copy_alpha);
514
407
    set_dev_proc(dev, fill_path, overprint_fill_path);
515
407
    set_dev_proc(dev, stroke_path, overprint_stroke_path);
516
407
    set_dev_proc(dev, fill_mask, gx_default_fill_mask);
517
407
    set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
518
407
    set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
519
407
    set_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
520
407
    set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
521
407
    set_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle);
522
407
    set_dev_proc(dev, strip_copy_rop2, gx_default_strip_copy_rop2);
523
407
    set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
524
407
    set_dev_proc(dev, composite, overprint_composite);
525
407
    set_dev_proc(dev, text_begin, overprint_text_begin);
526
407
    set_dev_proc(dev, get_color_comp_index, overprint_get_color_comp_index);
527
407
    set_dev_proc(dev, fill_rectangle_hl_color, overprint_fill_rectangle_hl_color);
528
407
    set_dev_proc(dev, dev_spec_op, overprint_dev_spec_op);
529
407
    set_dev_proc(dev, copy_planes, overprint_copy_planes);
530
407
    set_dev_proc(dev, copy_alpha_hl_color, overprint_copy_alpha_hl_color);
531
407
    set_dev_proc(dev, fill_stroke_path, overprint_fill_stroke_path);
532
407
}
533
534
/*
535
 * The prototype for the overprint device does not provide much
536
 * information; it exists primarily to facilitate use gx_init_device
537
 * and sundry other device utility routines.
538
 */
539
const overprint_device_t    gs_overprint_device = {
540
    std_device_std_body_open( overprint_device_t,   /* device type */
541
                              NULL,                 /* initialize */
542
                              "overprint_device",   /* dname */
543
                              0, 0,                 /* width, height */
544
                              1, 1 ),               /* HWResolution */
545
    { 0 }                                           /* procs */
546
};
547
548
/*
549
 * Utility to reorder bytes in a color or mask based on the endianness of
550
 * the current device. This is required on little-endian machines if the
551
 * depth is larger 8. The resulting value is also replicated to fill the
552
 * entire gx_color_index if the depth is a divisor of the color index
553
 * size. If this is not the case, the result will be in the low-order
554
 * bytes of the color index.
555
 *
556
 * Though this process can be handled in full generality, the code below
557
 * takes advantage of the fact that depths that are > 8 must be a multiple
558
 * of 8 and <= 64
559
 */
560
#if !ARCH_IS_BIG_ENDIAN
561
562
static gx_color_index
563
swap_color_index(int depth, gx_color_index color)
564
134
{
565
134
    int             shift = depth - 8;
566
134
    gx_color_index  mask = 0xff;
567
568
134
    color =  ((color >> shift) & mask)
569
134
           | ((color & mask) << shift)
570
134
           | (color & ~((mask << shift) | mask));
571
134
    if (depth > 24) {
572
134
        shift -= 16;
573
134
        mask <<= 8;
574
134
        color =  ((color >> shift) & mask)
575
134
               | ((color & mask) << shift)
576
134
               | (color & ~((mask << shift) | mask));
577
578
134
        if (depth > 40) {
579
0
            shift -= 16;
580
0
            mask <<= 8;
581
0
            color =  ((color >> shift) & mask)
582
0
                   | ((color & mask) << shift)
583
0
                   | (color & ~((mask << shift) | mask));
584
585
0
            if (depth > 56) {
586
0
                shift -= 16;
587
0
                mask <<= 8;
588
0
                color =  ((color >> shift) & mask)
589
0
                       | ((color & mask) << shift)
590
0
                       | (color & ~((mask << shift) | mask));
591
0
            }
592
0
        }
593
134
    }
594
595
134
    return color;
596
134
}
597
598
#endif  /* !ARCH_IS_BIG_ENDIAN */
599
600
/*
601
 * Update the retain_mask field to reflect the information in the
602
 * drawn_comps field. This is useful only if the device color model
603
 * is separable.
604
 */
605
static void
606
set_retain_mask(overprint_device_t * opdev, bool is_fill_color)
607
940
{
608
940
    uchar i, ncomps = opdev->color_info.num_components;
609
940
    gx_color_index  drawn_comps = is_fill_color ?
610
849
                                  opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
611
940
    gx_color_index retain_mask = 0;
612
940
#if !ARCH_IS_BIG_ENDIAN
613
940
    int depth = opdev->color_info.depth;
614
940
#endif
615
616
4.82k
    for (i = 0; i < ncomps; i++, drawn_comps >>= 1) {
617
3.88k
        if ((drawn_comps & 0x1) == 0)
618
1.63k
            retain_mask |= opdev->color_info.comp_mask[i];
619
3.88k
    }
620
940
#if !ARCH_IS_BIG_ENDIAN
621
940
    if (depth > 8)
622
134
        retain_mask = swap_color_index(depth, retain_mask);
623
940
#endif
624
940
    if (is_fill_color)
625
849
        opdev->retain_mask_fill = retain_mask;
626
91
    else
627
91
        opdev->retain_mask_stroke = retain_mask;
628
940
}
629
630
/*
631
 * Update the overprint-specific device parameters.
632
 *
633
 * If spot colors are to be retain, the set of process (non-spot) colors is
634
 * determined by mapping through the standard color spaces and check which
635
 * components assume non-zero values.
636
 */
637
static int
638
update_overprint_params(
639
    overprint_device_t* opdev,
640
    const gs_overprint_params_t* pparams)
641
29.7k
{
642
    /* We can only turn off the overprint compositor if
643
       BOTH the stroke and fill op are false.  Otherwise
644
       we will turn it off when setting one and turn on
645
       when setting the other (or vice versa) */
646
647
    /* Note if pparams->op_state is not NONE, set the opdev fill/stroke state. */
648
29.7k
    if (pparams->op_state != OP_STATE_NONE) {
649
21.1k
        opdev->op_state = pparams->op_state;
650
21.1k
        return 0;
651
21.1k
    }
652
653
29.7k
    if_debug4m(gs_debug_flag_overprint, opdev->memory,
654
8.62k
        "[overprint] update_overprint_params enter. retain_any_comps = %d, idle = %d, drawn_comps = 0x%"PRIx64", is_fill_color = %d\n",
655
8.62k
               pparams->retain_any_comps, pparams->idle,
656
8.62k
               (uint64_t)pparams->drawn_comps, pparams->is_fill_color);
657
658
    /* check if overprint is to be turned off */
659
8.62k
    if (!pparams->retain_any_comps || pparams->idle) {
660
7.68k
        if (pparams->is_fill_color) {
661
5.68k
            opdev->retain_none_fill = true;
662
5.68k
            opdev->drawn_comps_fill =
663
5.68k
                ((gx_color_index)1 << (opdev->color_info.num_components)) - (gx_color_index)1;
664
5.68k
        } else {
665
2.00k
            opdev->retain_none_stroke = true;
666
2.00k
            opdev->drawn_comps_stroke =
667
2.00k
                ((gx_color_index)1 << (opdev->color_info.num_components)) - (gx_color_index)1;
668
2.00k
        }
669
670
        /* Set to forward only if both stroke and fill are not retaining any
671
           and if we have not already set it to forward */
672
7.68k
        if (dev_proc(opdev, fill_rectangle) != gx_forward_fill_rectangle &&
673
1.12k
            opdev->retain_none_fill && opdev->retain_none_stroke) {
674
838
            memcpy(&opdev->procs,
675
838
                &opdev->no_overprint_procs,
676
838
                sizeof(opdev->no_overprint_procs));
677
838
            opdev->is_idle = true;
678
838
            if_debug0m(gs_debug_flag_overprint, opdev->memory,
679
838
                "[overprint] overprint fill_rectangle set to forward\n");
680
838
        }
681
682
7.68k
        if_debug4m(gs_debug_flag_overprint, opdev->memory,
683
7.68k
            "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%"PRIx64", drawn_comps_stroke = 0x%"PRIx64", retain_none_fill = %d, retain_none_stroke = %d \n",
684
7.68k
                   (uint64_t)opdev->drawn_comps_fill,
685
7.68k
                   (uint64_t)opdev->drawn_comps_stroke,
686
7.68k
                   opdev->retain_none_fill, opdev->retain_none_stroke);
687
7.68k
        return 0;
688
7.68k
    }
689
690
940
    opdev->is_idle = false;
691
    /* set the procedures according to the color model */
692
940
    if (colors_are_separable_and_linear(&opdev->color_info)) {
693
940
        memcpy(&opdev->procs, &opdev->sep_overprint_procs,
694
940
            sizeof(opdev->sep_overprint_procs));
695
940
        if_debug0m(gs_debug_flag_overprint, opdev->memory,
696
940
            "[overprint] overprint procs set to sep\n");
697
940
    } else {
698
0
        memcpy(&opdev->procs, &opdev->generic_overprint_procs,
699
0
            sizeof(opdev->generic_overprint_procs));
700
0
        if_debug0m(gs_debug_flag_overprint, opdev->memory,
701
0
            "[overprint] overprint procs set to generic\n");
702
0
    }
703
704
940
    if (pparams->is_fill_color) {
705
849
        opdev->retain_none_fill = false;
706
849
        opdev->drawn_comps_fill = pparams->drawn_comps;
707
849
    } else {
708
91
        opdev->retain_none_stroke = false;
709
91
        opdev->drawn_comps_stroke = pparams->drawn_comps;
710
91
    }
711
712
940
    if_debug4m(gs_debug_flag_overprint, opdev->memory,
713
940
        "[overprint] update_overprint_params exit. drawn_comps_fill = 0x%"PRIx64", drawn_comps_stroke = 0x%"PRIx64", retain_none_fill = %d, retain_none_stroke = %d \n",
714
940
               (uint64_t)opdev->drawn_comps_fill,
715
940
               (uint64_t)opdev->drawn_comps_stroke,
716
940
               opdev->retain_none_fill, opdev->retain_none_stroke);
717
718
    /* if appropriate, update the retain_mask field */
719
940
    if (colors_are_separable_and_linear(&opdev->color_info))
720
940
        set_retain_mask(opdev, pparams->is_fill_color);
721
722
940
    return 0;
723
8.62k
}
724
725
/*
726
 * The open_device method for the overprint device is about as close to
727
 * a pure "forwarding" open_device operation as is possible. Its only
728
 * significant function is to ensure that the is_open field of the
729
 * overprint device matches that of the target device.
730
 *
731
 * We assume this procedure is called only if the device is not already
732
 * open, and that gs_opendevice will take care of the is_open flag.
733
 */
734
static int
735
overprint_open_device(gx_device * dev)
736
0
{
737
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
738
0
    gx_device *             tdev = opdev->target;
739
0
    int                     code = 0;
740
741
    /* the overprint device must have a target */
742
0
    if (tdev == 0)
743
0
        return_error(gs_error_unknownerror);
744
0
    if ((code = gs_opendevice(tdev)) >= 0) {
745
0
        gx_device_copy_params(dev, tdev);
746
0
        opdev->copy_alpha_hl = false;
747
0
        opdev->is_idle = false;
748
0
    }
749
0
    return code;
750
0
}
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
static int
757
overprint_put_params(gx_device * dev, gs_param_list * plist)
758
0
{
759
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
760
0
    gx_device *             tdev = opdev->target;
761
0
    int                     code = 0;
762
763
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
764
0
        gx_device_decache_colors(dev);
765
0
        if (!tdev->is_open)
766
0
            code = gs_closedevice(dev);
767
0
    }
768
0
    return code;
769
0
}
770
771
/*
772
 * If the target device 'auto detects' new spot colors, then it will
773
 * change its color_info data.  Make sure that we have a current copy.
774
 */
775
int
776
overprint_get_color_comp_index(gx_device * dev, const char * pname,
777
                                        int name_size, int component_type)
778
0
{
779
0
    overprint_device_t * opdev = (overprint_device_t *)dev;
780
0
    gx_device * tdev = opdev->target;
781
0
    int code;
782
783
0
    if (tdev == 0)
784
0
        code = gx_error_get_color_comp_index(dev, pname,
785
0
                                name_size, component_type);
786
0
    else {
787
0
        code = dev_proc(tdev, get_color_comp_index)(tdev, pname,
788
0
                                name_size, component_type);
789
0
        opdev->color_info = tdev->color_info;
790
0
    }
791
0
    return code;
792
0
}
793
794
/*
795
 * The overprint device must never be confused with a page device.
796
 * Thus, we always forward the request for the page device to the
797
 * target, as should all forwarding devices.
798
 */
799
static gx_device *
800
overprint_get_page_device(gx_device * dev)
801
0
{
802
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
803
0
    gx_device *             tdev = opdev->target;
804
805
0
    return tdev == 0 ? 0 : dev_proc(tdev, get_page_device)(tdev);
806
0
}
807
808
/*
809
 * Calling composite on the overprint device just updates the
810
 * overprint parameters; no new device is created.
811
 */
812
static int
813
overprint_composite(
814
    gx_device *             dev,
815
    gx_device **            pcdev,
816
    const gs_composite_t *  pct,
817
    gs_gstate *             pgs,
818
    gs_memory_t *           memory,
819
    gx_device *             cdev)
820
41.8k
{
821
41.8k
    if (pct->type != &gs_composite_overprint_type)
822
0
        return gx_default_composite(dev, pcdev, pct, pgs, memory, cdev);
823
41.8k
    else {
824
41.8k
        gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params;
825
41.8k
        overprint_device_t *opdev = (overprint_device_t *)dev;
826
41.8k
        int     code = 0;
827
41.8k
        bool update;
828
829
41.8k
        if (params.is_fill_color)
830
17.8k
            update = (params.drawn_comps != opdev->drawn_comps_fill) ||
831
13.0k
            ((params.retain_any_comps == 0) != opdev->retain_none_fill);
832
23.9k
        else
833
23.9k
            update = (params.drawn_comps != opdev->drawn_comps_stroke) ||
834
19.2k
            ((params.retain_any_comps == 0) != opdev->retain_none_stroke);
835
836
41.8k
        params.idle = pct->idle;
837
        /* device must already exist, so just update the parameters if settings change */
838
41.8k
        if_debug6m(gs_debug_flag_overprint, opdev->memory,
839
41.8k
            "[overprint] overprint_composite test for change. params.idle = %d vs. opdev->is_idle = %d \n  params.is_fill_color = %d: params.drawn_comps = 0x%"PRIx64" vs. opdev->drawn_comps_fill =  0x%"PRIx64" OR opdev->drawn_comps_stroke = 0x%"PRIx64"\n",
840
41.8k
            params.idle, opdev->is_idle, params.is_fill_color,
841
41.8k
                   (uint64_t)params.drawn_comps,
842
41.8k
                   (uint64_t)opdev->drawn_comps_fill,
843
41.8k
                   (uint64_t)opdev->drawn_comps_stroke);
844
845
41.8k
        if (update || params.idle != opdev->is_idle || params.op_state != OP_STATE_NONE)
846
29.3k
            code = update_overprint_params(opdev, &params);
847
41.8k
        if (code >= 0)
848
41.8k
            *pcdev = dev;
849
41.8k
        return code;
850
41.8k
    }
851
41.8k
}
852
853
/*
854
 * The two rectangle-filling routines (which do the actual work) are just
855
 * stubbs for the time being. The actual routines would allocate a buffer,
856
 * use get_bits_rectangle to build a buffer of the existing data, modify
857
 * the appropriate components, then invoke the copy_color procedure on the
858
 * target device.
859
 */
860
static int
861
overprint_generic_fill_rectangle(
862
    gx_device *     dev,
863
    int             x,
864
    int             y,
865
    int             width,
866
    int             height,
867
    gx_color_index  color )
868
0
{
869
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
870
0
    gx_device *             tdev = opdev->target;
871
872
0
    if (tdev == 0)
873
0
        return 0;
874
0
    else {
875
876
0
        assert(opdev->op_state != OP_STATE_NONE);
877
878
        /* See if we even need to do any overprinting.  We have to maintain
879
           the compositor active for fill/stroke cases even if we are only
880
           doing a fill or a stroke */
881
0
        if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
882
0
            (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
883
0
            return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, width, height, color);
884
885
0
        return gx_overprint_generic_fill_rectangle(tdev,
886
0
            opdev->op_state == OP_STATE_FILL ?
887
0
            opdev->drawn_comps_fill : opdev->drawn_comps_stroke,
888
0
            x, y, width, height, color, dev->memory);
889
0
    }
890
0
}
891
892
static int
893
overprint_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
894
           int raster, gx_bitmap_id id, int x, int y, int width, int height,
895
                      const gx_drawing_color *pdcolor, int depth)
896
0
{
897
    /* copy_alpha_hl_color will end up calling copy_planes which for the
898
       copy alpha case we need to make sure we do in a proper overprint
899
       fashion.  Other calls of copy_alpha for example from the pattern
900
       tiling call are not done with overprint control.  So we set an
901
       appopriate flag so that we know to handle this properly when we
902
       get to copy_alpha */
903
904
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
905
0
    int code;
906
907
0
    if ((opdev->op_state == OP_STATE_FILL && !opdev->retain_none_fill) ||
908
0
        (opdev->op_state == OP_STATE_STROKE && !opdev->retain_none_stroke))
909
0
        opdev->copy_alpha_hl = true;
910
0
    code = gx_default_copy_alpha_hl_color(dev, data, data_x, raster, id, x, y,
911
0
                                          width, height, pdcolor, depth);
912
0
    opdev->copy_alpha_hl = false;
913
0
    return code;
914
0
}
915
916
/* Currently we really should only be here if the target device is planar
917
   AND it supports devn colors AND is 8 (or 16) bit.  This could use a
918
   rewrite to make if more efficient but I had to get something in place
919
   that would work */
920
static int
921
overprint_copy_planes(gx_device * dev, const byte * data, int data_x, int raster_in,
922
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
923
0
{
924
0
    overprint_device_t *    opdev = (overprint_device_t *)dev;
925
0
    gx_device *             tdev = opdev->target;
926
0
    byte *                  gb_buff = 0;
927
0
    gs_get_bits_params_t    gb_params;
928
0
    gs_int_rect             gb_rect;
929
0
    int                     code = 0;
930
0
    int64_t                raster;
931
0
    int                     byte_depth;
932
0
    int                     depth;
933
0
    uchar                   num_comps;
934
0
    uchar                   k,j;
935
0
    gs_memory_t *           mem = dev->memory;
936
0
    gx_color_index          comps_orig = opdev->op_state == OP_STATE_FILL ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
937
0
    byte                    *curr_data = (byte *) data + data_x;
938
0
    int                     row, offset;
939
940
0
    if (tdev == 0)
941
0
        return 0;
942
943
0
    if (opdev->copy_alpha_hl) {
944
        /* We are coming here via copy_alpha_hl_color due to the use of AA.
945
           We will want to handle the overprinting here */
946
0
        int bytespercomp;
947
0
        int has_tags = device_encodes_tags(dev);
948
949
0
        depth = tdev->color_info.depth;
950
0
        num_comps = tdev->color_info.num_components;
951
0
        if (has_tags)
952
0
            comps_orig |= 1<<(num_comps-1);
953
954
0
        fit_fill(tdev, x, y, w, h);
955
0
        byte_depth = depth / num_comps;
956
0
        bytespercomp = byte_depth>>3;
957
958
        /* allocate a buffer for the returned data */
959
0
        if (check_64bit_multiply(w, byte_depth, &raster) != 0)
960
0
            return gs_note_error(gs_error_undefinedresult);
961
962
0
        gb_buff = gs_alloc_bytes(mem, raster * num_comps , "overprint_copy_planes");
963
0
        if (gb_buff == 0)
964
0
            return gs_note_error(gs_error_VMerror);
965
966
        /* Initialize the get_bits parameters. Here we just get a plane at a  time. */
967
0
        gb_params.options =  GB_COLORS_NATIVE
968
0
                           | GB_ALPHA_NONE
969
0
                           | GB_DEPTH_ALL
970
0
                           | GB_PACKING_PLANAR
971
0
                           | GB_RETURN_COPY
972
0
                           | GB_ALIGN_STANDARD
973
0
                           | GB_OFFSET_0
974
0
                           | GB_RASTER_STANDARD
975
0
                           | GB_SELECT_PLANES;
976
977
0
        gb_params.x_offset = 0;
978
0
        gb_params.raster = raster;
979
0
        gb_rect.p.x = x;
980
0
        gb_rect.q.x = x + w;
981
982
        /* step through the height */
983
0
        row = 0;
984
0
        while (h-- > 0 && code >= 0) {
985
0
            gx_color_index comps = comps_orig;
986
0
            gb_rect.p.y = y++;
987
0
            gb_rect.q.y = y;
988
0
            offset = row * raster_in + data_x * bytespercomp;
989
0
            row++;
990
0
            curr_data = (byte *) data + offset; /* start us at the start of row */
991
            /* And now through each plane */
992
0
            for (k = 0; k < tdev->color_info.num_components; k++) {
993
                /* First set the params to zero for all planes except the one we want */
994
0
                for (j = 0; j < tdev->color_info.num_components; j++)
995
0
                    gb_params.data[j] = 0;
996
0
                gb_params.data[k] = gb_buff + k * raster;
997
0
                code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect,
998
0
                                                           &gb_params);
999
0
                if (code < 0) {
1000
0
                    gs_free_object(mem, gb_buff, "overprint_copy_planes" );
1001
0
                    return code;
1002
0
                }
1003
                /* Skip the plane if this component is not to be drawn.  If
1004
                   its the one that we want to draw, replace it with our
1005
                   buffer data */
1006
0
                if ((comps & 0x01) == 1) {
1007
0
                    memcpy(gb_params.data[k], curr_data, w * bytespercomp);
1008
0
                }
1009
                /* Next plane */
1010
0
                curr_data += plane_height * raster_in;
1011
0
                comps >>= 1;
1012
0
            }
1013
0
            code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster,
1014
0
                                               gs_no_bitmap_id, x, y - 1, w, 1, 1);
1015
0
        }
1016
0
        gs_free_object(mem, gb_buff, "overprint_copy_planes" );
1017
0
        return code;
1018
0
    } else {
1019
        /* This is not a case where copy planes should be doing overprinting.
1020
           For example, if we came here via the pattern tiling code, so just
1021
           pass this along to the target */
1022
0
        return (*dev_proc(tdev, copy_planes)) (tdev, data, data_x, raster_in, id,
1023
0
                                               x, y, w, h, plane_height);
1024
0
    }
1025
0
}
1026
static void
1027
my_memset16_be(uint16_t *dst, uint16_t col, size_t w)
1028
0
{
1029
0
#if !ARCH_IS_BIG_ENDIAN
1030
0
    col = (col>>8) | (col<<8);
1031
0
#endif
1032
0
    while (w--) {
1033
0
        *dst++ = col;
1034
0
    }
1035
0
}
1036
1037
/* Currently we really should only be here if the target device is planar
1038
   AND it supports devn colors AND is 8 or 16 bit. */
1039
static int
1040
overprint_fill_rectangle_hl_color(gx_device *dev,
1041
    const gs_fixed_rect *rect, const gs_gstate *pgs,
1042
    const gx_drawing_color *pdcolor, const gx_clip_path *pcpath)
1043
232
{
1044
232
    overprint_device_t *    opdev = (overprint_device_t *)dev;
1045
232
    gx_device *             tdev = opdev->target;
1046
232
    byte *                  gb_buff = 0;
1047
232
    gs_get_bits_params_t    gb_params;
1048
232
    gs_int_rect             gb_rect;
1049
232
    int                     code = 0;
1050
232
    int64_t                raster;
1051
232
    int                     byte_depth;
1052
232
    int                     depth;
1053
232
    uchar                   num_comps;
1054
232
    int                     x, y, w, h;
1055
232
    uchar                   k, j;
1056
232
    gs_memory_t *           mem = dev->memory;
1057
232
    gx_color_index          comps, comps2;
1058
232
    gx_color_index          mask;
1059
232
    int                     shift;
1060
232
    int                     deep;
1061
232
    int                     tag_plane = -1;
1062
1063
232
    if (tdev == 0)
1064
0
        return 0;
1065
1066
232
    assert(opdev->op_state != OP_STATE_NONE);
1067
1068
    /* See if we even need to do any overprinting.  We have to maintain
1069
       the compositor active for fill/stroke cases even if we are only
1070
       doing a fill or a stroke */
1071
232
    if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
1072
232
        (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
1073
0
        return (*dev_proc(tdev, fill_rectangle_hl_color)) (tdev, rect, pgs, pdcolor, pcpath);
1074
1075
232
    depth = tdev->color_info.depth;
1076
232
    num_comps = tdev->color_info.num_components;
1077
232
    if (device_encodes_tags(dev))
1078
0
        tag_plane = tdev->num_planar_planes - 1;
1079
1080
232
    x = fixed2int(rect->p.x);
1081
232
    y = fixed2int(rect->p.y);
1082
232
    w = fixed2int(rect->q.x) - x;
1083
232
    h = fixed2int(rect->q.y) - y;
1084
1085
232
    fit_fill(tdev, x, y, w, h);
1086
229
    byte_depth = depth / num_comps;
1087
229
    mask = ((gx_color_index)1 << byte_depth) - 1;
1088
229
    shift = 16 - byte_depth;
1089
229
    deep = byte_depth == 16;
1090
1091
    /* allocate a buffer for the returned data */
1092
229
    if (check_64bit_multiply(w, byte_depth, &raster) != 0)
1093
0
        return gs_note_error(gs_error_undefinedresult);
1094
229
    gb_buff = gs_alloc_bytes(mem, raster * num_comps , "overprint_fill_rectangle_hl_color");
1095
229
    if (gb_buff == 0)
1096
0
        return gs_note_error(gs_error_VMerror);
1097
1098
    /* Initialize the get_bits parameters. Here we just get a plane at a  time. */
1099
229
    gb_params.options =  GB_COLORS_NATIVE
1100
229
                       | GB_ALPHA_NONE
1101
229
                       | GB_DEPTH_ALL
1102
229
                       | GB_PACKING_PLANAR
1103
229
                       | GB_RETURN_COPY
1104
229
                       | GB_ALIGN_STANDARD
1105
229
                       | GB_OFFSET_0
1106
229
                       | GB_RASTER_STANDARD
1107
229
                       | GB_SELECT_PLANES;
1108
1109
229
    gb_params.x_offset = 0;     /* for consistency */
1110
229
    gb_params.raster = raster;
1111
229
    gb_rect.p.x = x;
1112
229
    gb_rect.q.x = x + w;
1113
1114
    /* step through the height */
1115
229
    comps2 = opdev->op_state == OP_STATE_FILL ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
1116
    /* If we are dealing with tags, and we are writing ANY components, then we want to write the
1117
     * tag plane too. */
1118
229
    if (comps2 != 0 && device_encodes_tags(dev)) {
1119
        /* Careful to allow for gx_color_index being larger than an int here! */
1120
0
        comps2 |= ((gx_color_index)1)<<(tdev->color_info.num_components-1);
1121
0
    }
1122
797
    while (h-- > 0 && code >= 0) {
1123
568
        gb_rect.p.y = y++;
1124
568
        gb_rect.q.y = y;
1125
568
        comps = comps2;
1126
        /* And now through each plane */
1127
2.85k
        for (k = 0; k < tdev->color_info.num_components; k++) {
1128
            /* First set the params to zero for all planes except the one we want */
1129
11.5k
            for (j = 0; j < tdev->color_info.num_components; j++)
1130
9.25k
                gb_params.data[j] = 0;
1131
2.29k
            gb_params.data[k] = gb_buff + k * raster;
1132
2.29k
            code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect,
1133
2.29k
                                                       &gb_params);
1134
2.29k
            if (code < 0) {
1135
0
                gs_free_object(mem, gb_buff,
1136
0
                               "overprint_fill_rectangle_hl_color" );
1137
0
                return code;
1138
0
            }
1139
            /* Skip the plane if this component is not to be drawn.  We have
1140
                to do a get bits for each plane due to the fact that we have
1141
                to do a copy_planes at the end.  If we had a copy_plane
1142
                operation we would just get the ones needed and set those. */
1143
2.29k
            if ((comps & 0x01) == 1) {
1144
                /* Not sure if a loop or a memset is better here */
1145
1.69k
                if (deep)
1146
0
                    my_memset16_be((uint16_t *)(gb_params.data[k]),
1147
0
                                   pdcolor->colors.devn.values[k], w);
1148
1.69k
                else {
1149
1.69k
                    int v = pdcolor->colors.devn.values[k];
1150
1.69k
                    if (k != tag_plane)
1151
1.69k
                        v = (v>>shift) & mask;
1152
1.69k
                    memset(gb_params.data[k], v, w);
1153
1.69k
                }
1154
1.69k
            }
1155
2.29k
            comps >>= 1;
1156
2.29k
        }
1157
568
        code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster,
1158
568
                                           gs_no_bitmap_id, x, y - 1, w, 1, 1);
1159
568
    }
1160
229
    gs_free_object(mem, gb_buff,
1161
229
                    "overprint_fill_rectangle_hl_color" );
1162
229
    return code;
1163
229
}
1164
1165
static int
1166
overprint_sep_fill_rectangle(
1167
    gx_device *     dev,
1168
    int             x,
1169
    int             y,
1170
    int             width,
1171
    int             height,
1172
    gx_color_index  color )
1173
766k
{
1174
766k
    overprint_device_t *    opdev = (overprint_device_t *)dev;
1175
766k
    gx_device *             tdev = opdev->target;
1176
1177
766k
    if (tdev == 0)
1178
0
        return 0;
1179
766k
    else {
1180
766k
        int     depth = tdev->color_info.depth;
1181
1182
766k
        assert(opdev->op_state != OP_STATE_NONE);
1183
1184
        /* See if we even need to do any overprinting.  We have to maintain
1185
           the compositor active for fill/stroke cases even if we are only
1186
           doing a fill or a stroke */
1187
766k
        if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
1188
766k
            (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
1189
0
            return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, width, height, color);
1190
1191
        /*
1192
         * Swap the color index into the order required by a byte-oriented
1193
         * bitmap. This is required only for littl-endian processors, and
1194
         * then only if the depth > 8.
1195
         */
1196
766k
#if !ARCH_IS_BIG_ENDIAN
1197
766k
        if (depth > 8)
1198
0
            color = swap_color_index(depth, color);
1199
766k
#endif
1200
1201
        /*
1202
         * We can handle rectangle filling via bits_fill_rectangle_masked
1203
         * if the depth is a divisor of 8 * sizeof(mono_fill_chunk). The
1204
         * non-masked fill_rectangle code uses a byte-oriented routine
1205
         * if depth > 8, but there is not much advantage to doing so if
1206
         * masking is required.
1207
         *
1208
         * Directly testing (8 * sizeof(mono_fill_chunk)) % depth is
1209
         * potentially expensive, since many rectangles are small. We
1210
         * can avoid the modulus operation by noting that
1211
         * 8 * sizeof(mono_fill_chunk) will be a power of 2, and so
1212
         * we need only check that depth is a power of 2 and
1213
         * depth < 8 * sizeof(mono_fill_chunk).
1214
         */
1215
766k
        if ( depth <= 8 * sizeof(mono_fill_chunk) && (depth & (depth - 1)) == 0)
1216
766k
            return gx_overprint_sep_fill_rectangle_1(tdev, opdev->op_state == OP_STATE_FILL ?
1217
712k
                                                     opdev->retain_mask_fill : opdev->retain_mask_stroke,
1218
766k
                                                     x, y, width, height,
1219
766k
                                                     color, dev->memory);
1220
0
        else
1221
0
            return gx_overprint_sep_fill_rectangle_2(tdev, opdev->op_state == OP_STATE_FILL ?
1222
0
                                                     opdev->retain_mask_fill : opdev->retain_mask_stroke,
1223
0
                                                     x, y, width, height,
1224
0
                                                     color, dev->memory);
1225
766k
    }
1226
766k
}
1227
1228
/* We need this to ensure the device knows we are doing a fill */
1229
static int
1230
overprint_fill_path(gx_device* pdev, const gs_gstate* pgs,
1231
    gx_path* ppath, const gx_fill_params* params_fill,
1232
    const gx_device_color* pdcolor, const gx_clip_path* pcpath)
1233
133
{
1234
133
    overprint_device_t* opdev = (overprint_device_t*)pdev;
1235
133
    OP_FS_STATE save_op_state = opdev->op_state;
1236
133
    int code;
1237
1238
133
    opdev->op_state = OP_STATE_FILL;
1239
133
    code = gx_default_fill_path(pdev, pgs, ppath, params_fill, pdcolor, pcpath);
1240
133
    opdev->op_state = save_op_state;
1241
133
    return code;
1242
133
}
1243
1244
/* We need this to ensure the device knows we are doing a stroke */
1245
static int
1246
overprint_stroke_path(gx_device* pdev, const gs_gstate* pgs,
1247
    gx_path* ppath, const gx_stroke_params* params_stroke,
1248
    const gx_device_color* pdcolor, const gx_clip_path* pcpath)
1249
326
{
1250
326
    overprint_device_t* opdev = (overprint_device_t*)pdev;
1251
326
    OP_FS_STATE save_op_state = opdev->op_state;
1252
326
    int code;
1253
1254
326
    opdev->op_state = OP_STATE_STROKE;
1255
1256
    /* Stroke methods use fill path so set that to default to
1257
       avoid mix up of is_fill_color */
1258
326
    opdev->procs.fill_path = gx_default_fill_path;
1259
326
    code = gx_default_stroke_path(pdev, pgs, ppath, params_stroke, pdcolor, pcpath);
1260
326
    opdev->procs.fill_path = overprint_fill_path;
1261
326
    opdev->op_state = save_op_state;
1262
1263
326
    return code;
1264
326
}
1265
1266
/*
1267
 *  Cannot use default_fill_stroke_path because we need to set the is_fill_color
1268
 */
1269
static int
1270
overprint_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs,
1271
                           gx_path * ppath,
1272
                           const gx_fill_params * params_fill,
1273
                           const gx_device_color * pdevc_fill,
1274
                           const gx_stroke_params * params_stroke,
1275
                           const gx_device_color * pdevc_stroke,
1276
                           const gx_clip_path * pcpath)
1277
0
{
1278
0
    int code;
1279
0
    overprint_device_t *opdev = (overprint_device_t *)pdev;
1280
0
    OP_FS_STATE save_op_state = opdev->op_state;
1281
1282
0
    opdev->op_state = OP_STATE_FILL;
1283
0
    code = dev_proc(pdev, fill_path)(pdev, pgs, ppath, params_fill, pdevc_fill, pcpath);
1284
0
    if (code < 0)
1285
0
        return code;
1286
1287
    /* Set up for stroke */
1288
0
    opdev->op_state = OP_STATE_STROKE;
1289
0
    code = dev_proc(pdev, stroke_path)(pdev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
1290
0
    opdev->op_state = save_op_state;
1291
0
    return code;
1292
0
}
1293
1294
/* We need to make sure we are set up properly based upon the text mode */
1295
static int
1296
overprint_text_begin(gx_device* dev, gs_gstate* pgs,
1297
    const gs_text_params_t* text, gs_font* font,
1298
    const gx_clip_path* pcpath,
1299
    gs_text_enum_t** ppte)
1300
0
{
1301
0
    overprint_device_t* opdev = (overprint_device_t*)dev;
1302
0
    OP_FS_STATE save_op_state = opdev->op_state;
1303
0
    int code = 0;
1304
1305
0
    if (pgs->text_rendering_mode == 0)
1306
0
        opdev->op_state = OP_STATE_FILL;
1307
0
    else if (pgs->text_rendering_mode == 1)
1308
0
        opdev->op_state = OP_STATE_STROKE;
1309
1310
0
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, ppte);
1311
0
    opdev->op_state = save_op_state;
1312
0
    return code;
1313
0
}
1314
1315
static int
1316
overprint_dev_spec_op(gx_device* pdev, int dev_spec_op,
1317
    void* data, int size)
1318
147k
{
1319
147k
    overprint_device_t* opdev = (overprint_device_t*)pdev;
1320
147k
    gx_device* tdev = opdev->target;
1321
1322
147k
    if (tdev == 0)
1323
0
        return 0;
1324
1325
147k
    if (dev_spec_op == gxdso_overprint_active)
1326
0
        return !opdev->is_idle;
1327
1328
147k
    if (dev_spec_op == gxdso_abuf_optrans)
1329
0
    {
1330
0
        overprint_abuf_state_t *state = (overprint_abuf_state_t *)data;
1331
0
        switch (state->op_trans)
1332
0
        {
1333
0
        case OP_FS_TRANS_PREFILL:
1334
0
            state->storage[0] = opdev->op_state;
1335
0
            opdev->op_state = OP_STATE_FILL;
1336
0
            break;
1337
0
        case OP_FS_TRANS_PRESTROKE:
1338
0
            opdev->op_state = OP_STATE_STROKE;
1339
0
            break;
1340
0
        default:
1341
0
        case OP_FS_TRANS_POSTSTROKE:
1342
0
        case OP_FS_TRANS_CLEANUP:
1343
0
            opdev->op_state = (OP_FS_STATE)state->storage[0];
1344
0
            break;
1345
0
        }
1346
0
        return 0;
1347
0
    }
1348
1349
147k
    if (dev_spec_op == gxdso_device_child) {
1350
0
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
1351
0
        if (d->target == pdev) {
1352
0
            d->target = tdev;
1353
0
            return 1;
1354
0
        }
1355
0
    }
1356
147k
    if (dev_spec_op == gxdso_device_insert_child) {
1357
0
        opdev->target = (gx_device *)data;
1358
0
        rc_increment(opdev->target);
1359
0
        rc_decrement_only(tdev, "overprint_dev_spec_op");
1360
0
        return 0;
1361
0
    }
1362
147k
    return dev_proc(tdev, dev_spec_op)(tdev, dev_spec_op, data, size);
1363
147k
}
1364
1365
/* complete a procedure set */
1366
static int
1367
fill_in_procs(gx_device_procs * pprocs,
1368
              dev_proc_initialize_device_procs(initialize_device_procs),
1369
              int num_planar_planes)
1370
1.22k
{
1371
1.22k
    gx_device_forward tmpdev;
1372
1373
    /*
1374
     * gx_device_forward_fill_in_procs calls gx_device_fill_in_procs, which
1375
     * requires the color_info field of the device be set to "reasonable"
1376
     * values. Which values is irrelevant in this case, but they must not
1377
     * contain dangling pointers, excessive numbers of components, etc.
1378
     */
1379
1.22k
    memcpy( &tmpdev.color_info,
1380
1.22k
            &gs_overprint_device.color_info,
1381
1.22k
            sizeof(tmpdev.color_info) );
1382
1.22k
    tmpdev.num_planar_planes = num_planar_planes;
1383
1384
    /*
1385
     * Prevent the check_device_separable routine from executing while we
1386
     * fill in the procs.  Our tmpdev is not complete enough for it.
1387
     */
1388
1.22k
    tmpdev.color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
1389
1.22k
    memset(&tmpdev.procs, 0, sizeof(tmpdev.procs));
1390
1.22k
    tmpdev.initialize_device_procs = initialize_device_procs;
1391
1.22k
    initialize_device_procs((gx_device *)&tmpdev);
1392
1.22k
    gx_device_forward_fill_in_procs(&tmpdev);
1393
1.22k
    memcpy(pprocs, &tmpdev.procs, sizeof(tmpdev.procs));
1394
1395
1.22k
    return 0;
1396
1.22k
}
1397
1398
/*
1399
 * Create an overprint compositor.
1400
 *
1401
 * Note that this routine will be called only if the device is not already
1402
 * an overprint compositor. Hence, if pct->params.retain_any_comps is
1403
 * false, we can just return.
1404
 */
1405
static int
1406
c_overprint_create_default_compositor(
1407
    const gs_composite_t *  pct,
1408
    gx_device **            popdev,
1409
    gx_device *             tdev,
1410
    gs_gstate *             pgs,
1411
    gs_memory_t *           mem )
1412
11.3M
{
1413
11.3M
    const gs_overprint_t *  ovrpct = (const gs_overprint_t *)pct;
1414
11.3M
    overprint_device_t *    opdev = 0;
1415
11.3M
    gs_overprint_params_t params;
1416
11.3M
    int code;
1417
1418
    /* see if there is anything to do */
1419
11.3M
    if ( !ovrpct->params.retain_any_comps) {
1420
11.3M
        *popdev = tdev;
1421
11.3M
        return 0;
1422
11.3M
    }
1423
7.91k
    if (pct->idle) {
1424
7.50k
        *popdev = tdev;
1425
7.50k
        return 0;
1426
7.50k
    }
1427
1428
    /* build the overprint device */
1429
407
    opdev = gs_alloc_struct_immovable(mem,
1430
407
                                      overprint_device_t,
1431
407
                                      &st_overprint_device_t,
1432
407
                                      "create overprint compositor" );
1433
407
    *popdev = (gx_device *)opdev;
1434
407
    if (opdev == NULL)
1435
0
        return_error(gs_error_VMerror);
1436
407
    code = gx_device_init((gx_device *)opdev,
1437
407
                          (const gx_device *)&gs_overprint_device,
1438
407
                          mem,
1439
407
                          false);
1440
407
    if (code < 0)
1441
0
        return code;
1442
407
    code = fill_in_procs(&opdev->no_overprint_procs,
1443
407
                         nooverprint_initialize_device_procs,
1444
407
                         tdev->num_planar_planes);
1445
407
    if (code < 0)
1446
0
        return code;
1447
407
    code = fill_in_procs(&opdev->generic_overprint_procs,
1448
407
                         generic_overprint_initialize_device_procs,
1449
407
                         tdev->num_planar_planes);
1450
407
    if (code < 0)
1451
0
        return code;
1452
407
    code = fill_in_procs(&opdev->sep_overprint_procs,
1453
407
                         sep_overprint_initialize_device_procs,
1454
407
                         tdev->num_planar_planes);
1455
407
    if (code < 0)
1456
0
        return code;
1457
1458
407
    gx_device_copy_params((gx_device *)opdev, tdev);
1459
407
    gx_device_set_target((gx_device_forward *)opdev, tdev);
1460
407
    opdev->pad = tdev->pad;
1461
407
    opdev->log2_align_mod = tdev->log2_align_mod;
1462
407
    opdev->num_planar_planes = tdev->num_planar_planes;
1463
1464
407
    params = ovrpct->params;
1465
407
    params.idle = ovrpct->idle;
1466
1467
    /* Initialize the stroke and fill states */
1468
407
    opdev->retain_none_fill = true;
1469
407
    opdev->retain_none_stroke = true;
1470
1471
    /* set up the overprint parameters */
1472
407
    code = update_overprint_params(opdev, &params);
1473
407
    if (code < 0)
1474
0
        return code;
1475
407
    return 1;
1476
407
}