Coverage Report

Created: 2025-12-31 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpdft.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 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
/* transparency processing for PDF-writing driver */
18
#include "gx.h"
19
#include "string_.h"
20
#include "gserrors.h"
21
#include "gstrans.h"
22
#include "gscolor2.h"
23
#include "gzstate.h"
24
#include "gdevpdfx.h"
25
#include "gdevpdfg.h"
26
#include "gdevpdfo.h"
27
#include "gsccolor.h"
28
29
static int
30
pdf_make_soft_mask_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams)
31
343
{
32
343
    pdf_resource_t *pres_soft_mask_dict = 0;
33
343
    cos_dict_t *soft_mask_dict;
34
343
    int code;
35
36
    /* Fixme : merge redundant objects. */
37
343
    code = pdf_alloc_resource(pdev, resourceSoftMaskDict, gs_no_id, &pres_soft_mask_dict, -1);
38
343
    if (code < 0)
39
0
        return code;
40
343
    cos_become(pres_soft_mask_dict->object, cos_type_dict);
41
343
    pdev->pres_soft_mask_dict = pres_soft_mask_dict;
42
343
    soft_mask_dict = (cos_dict_t *)pres_soft_mask_dict->object;
43
343
    code = cos_dict_put_c_key_string(soft_mask_dict, "/S",
44
343
            pparams->subtype == TRANSPARENCY_MASK_Alpha ? (byte *)"/Alpha" : (byte *)"/Luminosity",
45
343
            pparams->subtype == TRANSPARENCY_MASK_Alpha ? 6 : 11);
46
343
    if (code < 0)
47
0
        return code;
48
343
    if (pparams->Background_components) {
49
250
        cos_array_t *Background;
50
51
250
        Background = cos_array_from_floats(pdev, pparams->Background,
52
250
                    pparams->Background_components, "pdf_write_soft_mask_dict");
53
250
        if (Background == NULL)
54
0
            return_error(gs_error_VMerror);
55
250
        code = cos_dict_put_c_key_object(soft_mask_dict, "/BC", (cos_object_t *)Background);
56
250
        if (code < 0)
57
0
            return code;
58
250
    }
59
343
    if (pdev->CompatibilityLevel <= 1.7 && pparams->transfer_function != NULL && pdev->params.TransferFunctionInfo == tfi_Preserve) {
60
56
        int64_t id;
61
56
        char buf[20];
62
63
56
        code = pdf_write_function(pdev, pparams->transfer_function, &id);
64
56
        if (code < 0)
65
0
            return code;
66
56
        gs_snprintf(buf, sizeof(buf), " %"PRId64" 0 R", id);
67
56
        code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf));
68
56
        if (code < 0)
69
0
            return code;
70
56
    }
71
343
    return 0;
72
73
343
}
74
75
static int
76
pdf_make_group_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams,
77
                            const gs_gstate * pgs, cos_dict_t **pdict)
78
11.1k
{
79
11.1k
    pdf_resource_t *pres_group;
80
11.1k
    cos_dict_t *group_dict;
81
11.1k
    int code;
82
11.1k
    cos_value_t cs_value;
83
84
11.1k
    code = pdf_alloc_resource(pdev, resourceGroup, gs_no_id, &pres_group, -1);
85
11.1k
    if (code < 0)
86
0
        return code;
87
11.1k
    cos_become(pres_group->object, cos_type_dict);
88
11.1k
    group_dict = (cos_dict_t *)pres_group->object;
89
11.1k
    code = cos_dict_put_c_key_string(group_dict, "/Type", (const byte *)"/Group", 6);
90
11.1k
    if (code < 0)
91
0
        return code;
92
11.1k
    code = cos_dict_put_c_key_string(group_dict, "/S", (const byte *)"/Transparency", 13);
93
11.1k
    if (code < 0)
94
0
        return code;
95
11.1k
    if (pparams->Isolated) {
96
8.26k
        code = cos_dict_put_c_key_bool(group_dict, "/I", true);
97
8.26k
        if (code < 0)
98
0
            return code;
99
8.26k
    }
100
11.1k
    if (pparams->Knockout) {
101
3
        code = cos_dict_put_c_key_bool(group_dict, "/K", true);
102
3
        if (code < 0)
103
0
            return code;
104
3
    }
105
    /* Note that we should not add in the graphic state
106
       color space for the group color if there was not
107
       a group color specified.
108
       In this case, the parent group is inherited from
109
       the previous group or the device color space */
110
11.1k
    if (pgs != NULL && pparams->ColorSpace != NULL) {
111
3.09k
        const gs_color_space *cs = pparams->ColorSpace;
112
113
3.09k
        if (pparams->ColorSpace == NULL)
114
0
            code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, cs,
115
0
                    &pdf_color_space_names, false, NULL, 0, false);
116
3.09k
        else
117
3.09k
            code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, pparams->ColorSpace,
118
3.09k
                    &pdf_color_space_names, false, NULL, 0, false);
119
3.09k
        if (code < 0)
120
0
            return code;
121
3.09k
        code = cos_dict_put_c_key(group_dict, "/CS", &cs_value);
122
3.09k
        if (code < 0)
123
0
            return code;
124
3.09k
    }
125
11.1k
    group_dict = NULL; /* The next line invalidates it. */
126
11.1k
    code = pdf_substitute_resource(pdev, &pres_group, resourceGroup, NULL, false);
127
11.1k
    if (code < 0)
128
0
        return code;
129
11.1k
    pres_group->where_used |= pdev->used_mask;
130
11.1k
    *pdict = (cos_dict_t *)pres_group->object;
131
11.1k
    return 0;
132
11.1k
}
133
134
static int
135
pdf_make_form_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams,
136
                            const gs_gstate * pgs,
137
                            const cos_dict_t *group_dict, cos_dict_t *form_dict)
138
3.77k
{
139
3.77k
    cos_array_t *bbox_array;
140
3.77k
    float bbox[4];
141
3.77k
    gs_rect bbox_rect;
142
3.77k
    int code;
143
144
3.77k
    code = gs_bbox_transform(&pparams->bbox, &ctm_only(pgs), &bbox_rect);
145
3.77k
    if (code < 0)
146
0
        return code;
147
3.77k
    bbox[0] = bbox_rect.p.x;
148
3.77k
    bbox[1] = bbox_rect.p.y;
149
3.77k
    bbox[2] = bbox_rect.q.x;
150
3.77k
    bbox[3] = bbox_rect.q.y;
151
3.77k
    code = cos_dict_put_c_key_string(form_dict, "/Type", (const byte *)"/XObject", 8);
152
3.77k
    if (code < 0)
153
0
        return code;
154
3.77k
    code = cos_dict_put_c_key_string(form_dict, "/Subtype", (const byte *)"/Form", 5);
155
3.77k
    if (code < 0)
156
0
        return code;
157
3.77k
    code = cos_dict_put_c_key_int(form_dict, "/FormType", 1);
158
3.77k
    if (code < 0)
159
0
        return code;
160
3.77k
    code = cos_dict_put_c_key_string(form_dict, "/Matrix", (const byte *)"[1 0 0 1 0 0]", 13);
161
3.77k
    if (code < 0)
162
0
        return code;
163
3.77k
    bbox_array = cos_array_from_floats(pdev, bbox, 4, "pdf_begin_transparency_group");
164
3.77k
    if (bbox_array == NULL)
165
0
        return_error(gs_error_VMerror);
166
3.77k
    code = cos_dict_put_c_key_object(form_dict, "/BBox", (cos_object_t *)bbox_array);
167
3.77k
    if (code < 0)
168
0
        return code;
169
3.77k
    if (pdev->PendingOC != 0) {
170
40
        if (pdev->CompatibilityLevel < 1.4999) {
171
0
            if (pdev->PDFA) {
172
0
                switch (pdev->PDFACompatibilityPolicy) {
173
0
                    case 0:
174
0
                        emprintf(pdev->memory,
175
0
                                 "Optional Content not valid in this version of PDF, reverting to normal PDF output\n");
176
0
                        pdev->AbortPDFAX = true;
177
0
                        pdev->PDFA = 0;
178
0
                        break;
179
0
                    case 1:
180
0
                        emprintf(pdev->memory,
181
0
                                 "Optional Content not valid in this version of PDF. Dropping feature to preserve PDF/A compatibility\n");
182
0
                        break;
183
0
                    case 2:
184
0
                        emprintf(pdev->memory,
185
0
                                 "Optional Content not valid in this version of PDF,  aborting conversion\n");
186
0
                        return_error (gs_error_typecheck);
187
0
                        break;
188
0
                    default:
189
0
                        emprintf(pdev->memory,
190
0
                                 "Optional Content not valid in this version of PDF, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
191
0
                        pdev->AbortPDFAX = true;
192
0
                        pdev->PDFA = 0;
193
0
                        break;
194
0
                }
195
0
            } else {
196
0
                emprintf(pdev->memory,
197
0
                         "Optional Content not valid in this version of PDF. Dropping feature to preserve compatibility\n");
198
0
            }
199
40
        } else {
200
40
            char str[256];
201
40
            gs_param_string param;
202
40
            cos_object_t *pco = NULL;
203
204
40
            param.data = (const byte *)pdev->PendingOC;
205
40
            param.size = strlen(pdev->PendingOC);
206
40
            code = pdf_refer_named(pdev, &param, &pco);
207
40
            if(code < 0)
208
0
                return code;
209
210
40
            gs_snprintf(str, sizeof(str), "%"PRId64" 0 R", pco->id);
211
40
            code = cos_dict_put_string_copy(form_dict, "/OC", str);
212
40
            if (code < 0)
213
0
                return code;
214
215
40
            gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
216
40
            pdev->PendingOC = NULL;
217
40
        }
218
40
    }
219
3.77k
    return cos_dict_put_c_key_object(form_dict, "/Group", (cos_object_t *)group_dict);
220
3.77k
}
221
222
static int
223
pdf_begin_transparency_group(gs_gstate * pgs, gx_device_pdf * pdev,
224
                                const gs_pdf14trans_params_t * pparams, bool page_group)
225
11.1k
{
226
11.1k
    cos_dict_t *group_dict;
227
11.1k
    int code;
228
229
11.1k
    if (pgs == NULL)
230
0
        return_error(gs_error_unregistered); /* Must not happen. */
231
11.1k
    code = pdf_make_group_dict(pdev, pparams, pgs, &group_dict);
232
11.1k
    if (code < 0)
233
0
        return code;
234
11.1k
    code = pdf_open_page(pdev, PDF_IN_STREAM);
235
11.1k
    if (code < 0)
236
0
        return code;
237
11.1k
    code = pdf_check_soft_mask(pdev, pgs);
238
11.1k
    if (code < 0)
239
0
        return code;
240
11.1k
    if (pdf_must_put_clip_path(pdev, pgs->clip_path)) {
241
2.30k
        code = pdf_put_clip_path(pdev, pgs->clip_path);
242
2.30k
        if (code < 0)
243
0
            return code;
244
2.30k
    }
245
11.1k
    if (page_group)
246
905
        pdev->pages[pdev->next_page].group_id = group_dict->id;
247
10.2k
    else if (pparams->image_with_SMask) {
248
        /* An internal group for the image implementation.
249
           See doimagesmask in gs/lib/pdf_draw.ps .
250
           Just set a flag for skipping pdf_end_transparency_group. */
251
6.50k
        pdev->image_with_SMask |= 1 << ++pdev->FormDepth;
252
6.50k
        pdev->PatternsSinceForm = 0;
253
6.50k
    } else {
254
3.77k
        pdf_resource_t *pres, *pres_gstate = NULL;
255
3.77k
        cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
256
257
3.77k
        code = pdf_prepare_drawing(pdev, pgs, &pres_gstate, false);
258
3.77k
        if (code < 0)
259
0
            return code;
260
3.77k
        code = pdf_end_gstate(pdev, pres_gstate);
261
3.77k
        if (code < 0)
262
0
            return code;
263
3.77k
        code = pdf_enter_substream(pdev, resourceXObject,
264
3.77k
                gs_no_id, &pres, false, pdev->params.CompressPages);
265
3.77k
        if (code < 0)
266
0
            return code;
267
3.77k
        pdev->FormDepth++;
268
3.77k
        pdev->PatternsSinceForm = 0;
269
3.77k
        code = pdf_make_form_dict(pdev, pparams, pgs, group_dict, (cos_dict_t *)pres->object);
270
3.77k
        if (code < 0)
271
0
            return code;
272
273
        /* Create a Resources dictionary and add it to the form dictionary */
274
3.77k
        pcd = cos_stream_dict((cos_stream_t *)pres->object);
275
3.77k
        pcd_Resources = cos_dict_alloc(pdev, "pdf_group(Resources)");
276
3.77k
        if (pcd == NULL || pcd_Resources == NULL)
277
0
            return_error(gs_error_VMerror);
278
3.77k
        code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
279
3.77k
        pdev->substream_Resources = pcd_Resources;
280
3.77k
        return code;
281
3.77k
    }
282
7.41k
    return 0;
283
11.1k
}
284
285
static int
286
pdf_end_transparency_group(gs_gstate * pgs, gx_device_pdf * pdev)
287
10.8k
{
288
10.8k
    int bottom = (pdev->ResourcesBeforeUsage ? 1 : 0);
289
290
10.8k
    if (!is_in_page(pdev) && pdev->sbstack_depth == 0)
291
2
        return 0;  /* A Group definition at the page level, handled separately. */
292
10.8k
    if (pdev->image_with_SMask & (1 << pdev->FormDepth)) {
293
        /* An internal group for the image implementation.
294
           See pdf_begin_transparency_group. */
295
6.50k
        pdev->image_with_SMask &= ~(1 << pdev->FormDepth--);
296
6.50k
        pdev->PatternsSinceForm = 0;
297
6.50k
        return 0;
298
6.50k
    } else if (pdev->sbstack_depth == bottom) {
299
        /* We're closing the page group. */
300
903
        if (pdev->pages[pdev->next_page].group_id == 0)
301
0
            return_error(gs_error_unregistered); /* Must not happen. */
302
903
        return 0;
303
3.43k
    } else {
304
3.43k
        pdf_resource_t *pres = pdev->accumulating_substream_resource;
305
3.43k
        int code;
306
3.43k
        uint ignore;
307
308
3.43k
        if (pres == NULL)
309
0
            return_error(gs_error_unregistered);
310
3.43k
        pdev->FormDepth--;
311
3.43k
        pdev->PatternsSinceForm = 0;
312
3.43k
        code = pdf_exit_substream(pdev);
313
3.43k
        if (code < 0)
314
0
            return code;
315
3.43k
        code = pdf_substitute_resource(pdev, &pres, resourceXObject, NULL, false);
316
3.43k
        if (code < 0)
317
0
            return code;
318
        /* We need to update the 'where_used' field, in case we substituted a resource */
319
3.43k
        pres->where_used |= pdev->used_mask;
320
3.43k
        sputc(pdev->strm,'/');
321
3.43k
        sputs(pdev->strm, (const byte *)pres->rname, strlen(pres->rname), &ignore);
322
3.43k
        sputs(pdev->strm, (const byte *)" Do\n", 4, &ignore);
323
3.43k
        code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
324
3.43k
        return code;
325
3.43k
    }
326
10.8k
}
327
328
static int
329
pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
330
                                const gs_pdf14trans_params_t * pparams)
331
3.53k
{
332
3.53k
    if (pparams->subtype == TRANSPARENCY_MASK_None) {
333
3.18k
        int code;
334
3.18k
        pdf_resource_t *pres = 0L;
335
336
        /* reset the soft mask ID. Apparently this is only used by pdfwrite, if we don't
337
         * reset it, then the pdf_prepare_drawing code doesn't know that the SMask has
338
         * changed, and so doesn't write out the GState
339
         */
340
3.18k
        pgs->soft_mask_id = 0;
341
3.18k
        code = pdf_prepare_drawing(pdev, pgs, &pres, false);
342
3.18k
        if (code == gs_error_interrupt) {
343
            /* */
344
            /* Not in an appropriate context.  Do not restore the soft_mask_id.
345
               Otherwise any group push that occurs following this will use that
346
               softmask, which clearly should be NONE here.
347
             */
348
            /* ignore return code, we don't care about this graphics state as we aren't
349
             * emitting it anyway
350
             */
351
566
            pdf_end_gstate(pdev, pres);
352
566
            return 0;
353
566
        }
354
2.62k
        if (code < 0)
355
0
            return code;
356
2.62k
        code = pdf_end_gstate(pdev, pres);
357
2.62k
        if (code < 0)
358
0
            return code;
359
2.62k
        return 0;
360
2.62k
    }
361
343
    if (pparams->mask_is_image) {
362
        /* HACK :
363
            The control comes here when
364
            the PDF interpreter will make the PS interpreter
365
            to interprete the mask for filling the transparency buffer
366
            with an SMask image.
367
            Since we handle Type 3 images as a high level objects,
368
            we don't install the transparency buffer here
369
            and need to skip the image enumeration for the SMask.
370
            However we have no right method for skipping
371
            an image enumeration due to possible side effect
372
            of the image data proc in Postscript language.
373
            Therefore we do enumerate the image mask and accumulate
374
            it as a PDF stream, but don't create a reference to it.
375
            Later it will be enumerated once again as a part of SMask-ed image,
376
            and the pdfwrite image handler will recognize duplicated images
377
            and won't create the second stream for same image.
378
379
            We could make a special workaround for
380
            skipping mask images either in the graphics library or
381
            in the PS code of the PDF interpreter,
382
            but we don't want to complicate things now.
383
            The performance leak for the second enumeration
384
            shouldn't be harmful.
385
386
            So now just set a flag for pdf_end_and_do_image.
387
        */
388
0
        pdev->image_mask_skip = true;
389
0
        return 0;
390
343
    } else {
391
343
        int code;
392
393
343
        pdev->smask_construction = true;
394
343
        code = pdf_make_soft_mask_dict(pdev, pparams);
395
343
        if (code < 0)
396
0
            return code;
397
343
        code = pdf_open_page(pdev, PDF_IN_STREAM);
398
343
        if (code < 0)
399
0
            return code;
400
343
        return pdf_begin_transparency_group(pgs, pdev, pparams, 0);
401
343
    }
402
343
}
403
404
static int
405
pdf_end_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
406
                                const gs_pdf14trans_params_t * pparams)
407
343
{
408
343
    pdev->smask_construction = false;
409
343
    if (pdev->image_mask_skip)
410
0
        pdev->image_mask_skip = false;
411
343
    else {
412
343
        pdf_resource_t *pres = pdev->accumulating_substream_resource;
413
343
        int code;
414
343
        char buf[20];
415
416
343
        if (pres == NULL)
417
0
            return_error(gs_error_unregistered);
418
343
        code = pdf_exit_substream(pdev);
419
343
        if (code < 0)
420
0
            return code;
421
343
        code = pdf_substitute_resource(pdev, &pres, resourceXObject, NULL, false);
422
343
        if (code < 0)
423
0
            return 0;
424
        /* We need to update the 'where_used' field, in case we substituted a resource */
425
343
        pres->where_used |= pdev->used_mask;
426
343
        gs_snprintf(buf, sizeof(buf), "%"PRId64" 0 R", pdf_resource_id(pres));
427
343
        if (pdev->pres_soft_mask_dict == 0L) {
428
            /* something went horribly wrong, we have an 'end' wihtout a matching 'begin'
429
             * Give up, throw an error.
430
             */
431
0
            return_error(gs_error_undefined);
432
0
        }
433
343
        code = cos_dict_put_c_key_string((cos_dict_t *)pdev->pres_soft_mask_dict->object,
434
343
                "/G", (const byte *)buf, strlen(buf));
435
343
        if (code < 0)
436
0
            return code;
437
343
        code = pdf_substitute_resource(pdev, &pdev->pres_soft_mask_dict,
438
343
                                        resourceSoftMaskDict, NULL, false);
439
343
        if (code < 0)
440
0
            return code;
441
343
        pdev->pres_soft_mask_dict->where_used |= pdev->used_mask;
442
343
        pgs->soft_mask_id = pdev->pres_soft_mask_dict->object->id;
443
343
        pdev->pres_soft_mask_dict = NULL;
444
        /* We called pdf_start_trnasparency_group (see pdf_begin_transparency_mask
445
         * above) but we don't call pdf_end_transparency_group, so we must reduce
446
         * the FormDepth ourselves.
447
         */
448
343
        pdev->FormDepth--;
449
343
        pdev->PatternsSinceForm = 0;
450
343
    }
451
343
    return 0;
452
343
}
453
454
static int
455
pdf_set_blend_params(gs_gstate * pgs, gx_device_pdf * dev,
456
                                const gs_pdf14trans_params_t * pparams)
457
0
{
458
0
    return 0;
459
0
}
460
461
int
462
gdev_pdf_composite(gx_device *dev,
463
    gx_device **pcdev, const gs_composite_t *pct,
464
    gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev)
465
441k
{
466
441k
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
467
468
441k
    if (pdev->HaveTransparency && pdev->CompatibilityLevel >= 1.4 &&
469
427k
            pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS &&
470
199k
            pdev->PDFA != 1) {
471
199k
        gs_pdf14trans_t *pcte = (gs_pdf14trans_t *)pct;
472
199k
        gs_pdf14trans_params_t *params = &pcte->params;
473
474
199k
        *pcdev = dev;
475
199k
        switch(params->pdf14_op) {
476
1.87k
            case PDF14_PUSH_DEVICE:
477
1.87k
                return 0;
478
1.87k
            case PDF14_POP_DEVICE:
479
1.87k
                return 0;
480
0
            case PDF14_ABORT_DEVICE:
481
0
                return 0;
482
905
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
483
905
                return pdf_begin_transparency_group(pgs, pdev, params, 1);
484
9.93k
            case PDF14_BEGIN_TRANS_GROUP:
485
9.93k
                return pdf_begin_transparency_group(pgs, pdev, params, 0);
486
10.8k
            case PDF14_END_TRANS_GROUP:
487
10.8k
                return pdf_end_transparency_group(pgs, pdev);
488
83.0k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
489
83.0k
                return 0;
490
86.0k
            case PDF14_END_TRANS_TEXT_GROUP:
491
86.0k
                return 0;
492
3.53k
            case PDF14_BEGIN_TRANS_MASK:
493
3.53k
                return pdf_begin_transparency_mask(pgs, pdev, params);
494
343
            case PDF14_END_TRANS_MASK:
495
343
                return pdf_end_transparency_mask(pgs, pdev, params);
496
0
            case PDF14_SET_BLEND_PARAMS:
497
0
                return pdf_set_blend_params(pgs, pdev, params);
498
0
            case PDF14_PUSH_TRANS_STATE:
499
0
                return 0;
500
202
            case PDF14_POP_TRANS_STATE:
501
202
                return 0;
502
343
            case PDF14_PUSH_SMASK_COLOR:
503
343
                return 0;
504
343
            case PDF14_POP_SMASK_COLOR:
505
343
                return 0;
506
507
0
            default :
508
0
                return_error(gs_error_unregistered); /* Must not happen. */
509
199k
        }
510
0
        return 0;
511
199k
    }
512
242k
    return psdf_composite(dev, pcdev, pct, pgs, memory, cdev);
513
441k
}
514
515
/* We're not sure why the folllowing device methods are never called.
516
   Stub them for a while. */
517
518
int
519
gdev_pdf_begin_transparency_group(gx_device *dev,
520
    const gs_transparency_group_params_t *ptgp,
521
    const gs_rect *pbbox,
522
    gs_gstate *pgs, gs_memory_t *mem)
523
0
{
524
0
    return 0;
525
0
}
526
527
int
528
gdev_pdf_end_transparency_group(gx_device *dev,
529
    gs_gstate *pgs)
530
0
{
531
0
    return 0;
532
0
}
533
534
int
535
gdev_pdf_begin_transparency_mask(gx_device *dev,
536
    const gx_transparency_mask_params_t *ptmp,
537
    const gs_rect *pbbox,
538
    gs_gstate *pgs, gs_memory_t *mem)
539
0
{
540
0
    return 0;
541
0
}
542
543
int
544
gdev_pdf_end_transparency_mask(gx_device *dev,
545
    gs_gstate *pgs)
546
0
{
547
0
    return 0;
548
0
}