Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/ztrans.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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 operators */
18
#include "string_.h"
19
#include "memory_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gscspace.h"   /* for gscolor2.h */
23
#include "gscolor2.h"
24
#include "gsipar3x.h"
25
#include "gstrans.h"
26
#include "gxiparam.h"   /* for image enumerator */
27
#include "gxcspace.h"
28
#include "idict.h"
29
#include "idstack.h"
30
#include "idparam.h"
31
#include "ifunc.h"
32
#include "igstate.h"
33
#include "iimage.h"
34
#include "iname.h"
35
#include "store.h"
36
#include "gspaint.h"    /* gs_erasepage prototype */
37
#include "gdevdevn.h"
38
#include "gxdevsop.h"
39
#include "gxblend.h"
40
#include "gdevp14.h"
41
#include "gsicc_cms.h"
42
43
/* ------ Utilities ------ */
44
45
46
static int
47
current_float_value(i_ctx_t *i_ctx_p,
48
                    float (*current_value)(const gs_gstate *))
49
12
{
50
12
    os_ptr op = osp;
51
52
12
    push(1);
53
12
    make_real(op, current_value(igs));
54
12
    return 0;
55
12
}
56
57
static int
58
enum_param(const gs_memory_t *mem, const ref *pnref,
59
           const char *const names[])
60
7
{
61
7
    const char *const *p;
62
7
    ref nsref;
63
64
7
    check_type(*pnref, t_name);
65
66
7
    name_string_ref(mem, pnref, &nsref);
67
133
    for (p = names; *p; ++p)
68
126
        if (r_size(&nsref) == strlen(*p) &&
69
126
            !memcmp(*p, nsref.value.const_bytes, r_size(&nsref))
70
126
            )
71
0
            return p - names;
72
7
    return_error(gs_error_rangecheck);
73
7
}
74
75
/* ------ Graphics state operators ------ */
76
77
static const char *const blend_mode_names[] = {
78
    GS_BLEND_MODE_NAMES, 0
79
};
80
81
/* <modename> .setblendmode - */
82
static int
83
zsetblendmode(i_ctx_t *i_ctx_p)
84
10
{
85
10
    os_ptr op = osp;
86
10
    int code;
87
88
10
    check_op(1);
89
7
    check_type(*op, t_name);
90
7
    if ((code = enum_param(imemory, op, blend_mode_names)) < 0 ||
91
7
        (code = gs_setblendmode(igs, code)) < 0
92
7
        )
93
7
        return code;
94
0
    pop(1);
95
0
    return 0;
96
7
}
97
98
/* - .currentblendmode <modename> */
99
static int
100
zcurrentblendmode(i_ctx_t *i_ctx_p)
101
0
{
102
0
    os_ptr op = osp;
103
0
    const char *mode_name = blend_mode_names[gs_currentblendmode(igs)];
104
0
    ref nref;
105
0
    int code = name_enter_string(imemory, mode_name, &nref);
106
107
0
    if (code < 0)
108
0
        return code;
109
0
    push(1);
110
0
    *op = nref;
111
0
    return 0;
112
0
}
113
114
/* <bool> .settextknockout - */
115
static int
116
zsettextknockout(i_ctx_t *i_ctx_p)
117
4
{
118
4
    os_ptr op = osp;
119
120
4
    check_op(1);
121
0
    check_type(*op, t_boolean);
122
0
    gs_settextknockout(igs, op->value.boolval);
123
0
    pop(1);
124
0
    return 0;
125
0
}
126
127
/* - .currenttextknockout <bool> */
128
static int
129
zcurrenttextknockout(i_ctx_t *i_ctx_p)
130
0
{
131
0
    os_ptr op = osp;
132
133
0
    push(1);
134
0
    make_bool(op, gs_currenttextknockout(igs));
135
0
    return 0;
136
0
}
137
138
/* ------ Rendering stack operators ------ */
139
140
static int
141
rect_param(gs_rect *prect, os_ptr op)
142
2
{
143
2
    double coords[4];
144
2
    int code = num_params(op, 4, coords);
145
146
2
    if (code < 0)
147
0
        return code;
148
2
    prect->p.x = coords[0], prect->p.y = coords[1];
149
2
    prect->q.x = coords[2], prect->q.y = coords[3];
150
2
    return 0;
151
2
}
152
153
static int
154
mask_op(i_ctx_t *i_ctx_p,
155
        int (*mask_proc)(gs_gstate *, gs_transparency_channel_selector_t))
156
0
{
157
0
    int csel;
158
0
    int code = int_param(osp, 1, &csel);
159
160
0
    if (code < 0)
161
0
        return code;
162
0
    code = mask_proc(igs, csel);
163
0
    if (code >= 0)
164
0
        pop(1);
165
0
    return code;
166
167
0
}
168
169
static int common_transparency_group(i_ctx_t *i_ctx_p, pdf14_compositor_operations group_type)
170
10
{
171
10
    os_ptr op = osp;
172
10
    os_ptr dop = op - 4;
173
10
    gs_transparency_group_params_t params;
174
10
    gs_rect bbox;
175
10
    ref *dummy;
176
10
    int code;
177
178
10
    check_op(5);
179
2
    check_type(*dop, t_dictionary);
180
2
    check_dict_read(*dop);
181
2
    gs_trans_group_params_init(&params, 1.0);
182
2
    if ((code = dict_bool_param(dop, "Isolated", false, &params.Isolated)) < 0 ||
183
2
        (code = dict_bool_param(dop, "Knockout", false, &params.Knockout)) < 0 ||
184
2
        (code = dict_bool_param(dop, ".image_with_SMask", false, &params.image_with_SMask)) < 0
185
2
        )
186
0
        return code;
187
2
    code = rect_param(&bbox, op);
188
2
    if (code < 0)
189
0
        return code;
190
    /* If the CS is not given in the transparency group dict, set to NULL   */
191
    /* so that the transparency code knows to inherit from the parent layer */
192
2
    if (dict_find_string(dop, "CS", &dummy) <= 0) {
193
2
        params.ColorSpace = NULL;
194
2
    } else {
195
        /* the PDF interpreter sets the colorspace, so use it */
196
0
        params.ColorSpace = gs_currentcolorspace(igs);
197
        /* Lets make sure that it is not an ICC color space that came from
198
           a PS CIE color space or a PS color space. These are 1-way color
199
           spaces and cannot be used for group color spaces */
200
0
        if (gs_color_space_is_PSCIE(params.ColorSpace))
201
0
            params.ColorSpace = NULL;
202
0
        else if (gs_color_space_is_ICC(params.ColorSpace) &&
203
0
            params.ColorSpace->cmm_icc_profile_data != NULL &&
204
0
            params.ColorSpace->cmm_icc_profile_data->profile_handle != NULL) {
205
0
            if (gscms_is_input(params.ColorSpace->cmm_icc_profile_data->profile_handle,
206
0
                params.ColorSpace->cmm_icc_profile_data->memory))
207
0
                params.ColorSpace = NULL;
208
0
        }
209
0
    }
210
211
2
    if (gs_getalphaisshape(igs)) {
212
0
        params.group_shape = gs_getfillconstantalpha(igs);
213
0
        params.group_opacity = 1.0;
214
2
    } else {
215
2
        params.group_opacity = gs_getfillconstantalpha(igs);
216
2
        params.group_shape = 1.0;
217
2
    }
218
219
2
    code = gs_begin_transparency_group(igs, &params, &bbox, group_type);
220
2
    if (code < 0)
221
2
        return code;
222
0
    pop(5);
223
0
    return code;
224
2
}
225
226
/* <paramdict> <llx> <lly> <urx> <ury> .beginpagegroup - */
227
static int
228
zbegintransparencypagegroup(i_ctx_t *i_ctx_p)
229
0
{
230
0
    return common_transparency_group(i_ctx_p, PDF14_BEGIN_TRANS_PAGE_GROUP);
231
0
}
232
233
/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencygroup - */
234
static int
235
zbegintransparencygroup(i_ctx_t *i_ctx_p)
236
10
{
237
10
    return common_transparency_group(i_ctx_p, PDF14_BEGIN_TRANS_GROUP);
238
10
}
239
240
/* - .endtransparencygroup - */
241
static int
242
zendtransparencygroup(i_ctx_t *i_ctx_p)
243
0
{
244
0
    return gs_end_transparency_group(igs);
245
0
}
246
247
/* - .endtransparencytextgroup - */
248
static int
249
zendtransparencytextgroup(i_ctx_t *i_ctx_p)
250
0
{
251
0
    return gs_end_transparency_text_group(igs);
252
0
}
253
254
/* - .begintransparencytextgroup - */
255
static int
256
zbegintransparencytextgroup(i_ctx_t *i_ctx_p)
257
0
{
258
0
    return gs_begin_transparency_text_group(igs);
259
0
}
260
261
/* <cs_set?> <paramdict> <llx> <lly> <urx> <ury> .begintransparencymaskgroup -  */
262
/*             cs_set == false if we are inheriting the colorspace    */
263
static int tf_using_function(double, float *, void *);
264
static int
265
zbegintransparencymaskgroup(i_ctx_t *i_ctx_p)
266
0
{
267
0
    os_ptr op = osp;
268
0
    os_ptr dop = op - 4;
269
0
    gs_transparency_mask_params_t params;
270
0
    ref *pparam;
271
0
    gs_rect bbox;
272
0
    int code;
273
0
    static const char *const subtype_names[] = {
274
0
        GS_TRANSPARENCY_MASK_SUBTYPE_NAMES, 0
275
0
    };
276
277
0
    check_op(6);
278
0
    check_type(*dop, t_dictionary);
279
0
    check_dict_read(*dop);
280
0
    if (dict_find_string(dop, "Subtype", &pparam) <= 0)
281
0
        return_error(gs_error_rangecheck);
282
0
    if ((code = enum_param(imemory, pparam, subtype_names)) < 0)
283
0
        return code;
284
0
    gs_trans_mask_params_init(&params, code);
285
0
    params.replacing = true;
286
0
    if ((code = dict_floats_param(imemory, dop, "Background",
287
0
                    cs_num_components(gs_currentcolorspace(i_ctx_p->pgs)),
288
0
                                  params.Background, NULL)) < 0)
289
0
        return code;
290
0
    else if (code > 0)
291
0
        params.Background_components = code;
292
293
0
    if ((code = dict_floats_param(imemory, dop, "GrayBackground",
294
0
                    1, &params.GrayBackground, NULL)) < 0)
295
0
        return code;
296
0
    if (dict_find_string(dop, "TransferFunction", &pparam) > 0) {
297
0
        gs_function_t *pfn = ref_function(pparam);
298
299
0
        if (pfn == 0 || pfn->params.m != 1 || pfn->params.n != 1)
300
0
            return_error(gs_error_rangecheck);
301
0
        params.TransferFunction = tf_using_function;
302
0
        params.TransferFunction_data = pfn;
303
0
    }
304
0
    code = rect_param(&bbox, op);
305
0
    if (code < 0)
306
0
        return code;
307
0
    check_type(op[-5], t_boolean);
308
309
    /* Is the colorspace set for this mask ? */
310
0
    if (op[-5].value.boolval) {
311
0
                params.ColorSpace = gs_currentcolorspace(igs);
312
                /* Lets make sure that it is not an ICC color space that came from
313
                a PS CIE color space or a PS color space. These are 1-way color
314
                spaces and cannot be used for group color spaces */
315
0
                if (gs_color_space_is_PSCIE(params.ColorSpace))
316
0
                    params.ColorSpace = NULL;
317
0
                else if (gs_color_space_is_ICC(params.ColorSpace) &&
318
0
                    params.ColorSpace->cmm_icc_profile_data != NULL &&
319
0
                    params.ColorSpace->cmm_icc_profile_data->profile_handle != NULL) {
320
0
                    if (gscms_is_input(params.ColorSpace->cmm_icc_profile_data->profile_handle,
321
0
                        params.ColorSpace->cmm_icc_profile_data->memory))
322
0
                        params.ColorSpace = NULL;
323
0
                }
324
0
    } else {
325
0
        params.ColorSpace = NULL;
326
0
    }
327
0
    code = gs_begin_transparency_mask(igs, &params, &bbox, false);
328
0
    if (code < 0)
329
0
        return code;
330
0
    pop(6);
331
0
    return code;
332
0
}
333
334
/* <paramdict> .begintransparencymaskimage <paramdict> */
335
static int
336
zbegintransparencymaskimage(i_ctx_t *i_ctx_p)
337
0
{
338
0
    os_ptr dop = osp;
339
0
    os_ptr op = osp;
340
0
    gs_transparency_mask_params_t params;
341
0
    gs_rect bbox = { { 0, 0} , { 1, 1} };
342
0
    int code;
343
0
    gs_color_space *gray_cs = gs_cspace_new_DeviceGray(imemory);
344
345
0
    check_op(1);
346
0
    check_type(*dop, t_dictionary);
347
0
    check_dict_read(*dop);
348
0
    if (!gray_cs)
349
0
        return_error(gs_error_VMerror);
350
0
    gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
351
0
    if ((code = dict_float_array_check_param(imemory, dop, "Matte",
352
0
                                  GS_CLIENT_COLOR_MAX_COMPONENTS,
353
0
                                  params.Matte, NULL, 0,
354
0
                                  gs_error_rangecheck)) < 0)
355
0
        return code;
356
0
    else if (code > 0)
357
0
        params.Matte_components = code;
358
0
    code = gs_begin_transparency_mask(igs, &params, &bbox, true);
359
0
    if (code < 0)
360
0
        return code;
361
0
    rc_decrement_cs(gray_cs, "zbegintransparencymaskimage");
362
0
    return code;
363
0
}
364
365
/* Implement the TransferFunction using a Function. */
366
static int
367
tf_using_function(double in_val, float *out, void *proc_data)
368
0
{
369
0
    float in = in_val;
370
0
    gs_function_t *const pfn = proc_data;
371
372
0
    return gs_function_evaluate(pfn, &in, out);
373
0
}
374
375
/* <mask#> .endtransparencymask - */
376
static int
377
zendtransparencymask(i_ctx_t *i_ctx_p)
378
0
{
379
0
    return mask_op(i_ctx_p, gs_end_transparency_mask);
380
0
}
381
382
/* ------ Soft-mask images ------ */
383
384
/* <dict> .image3x - */
385
static int mask_dict_param(const gs_memory_t *mem, os_ptr,
386
                            image_params *, const char *, int,
387
                            gs_image3x_mask_t *);
388
static int
389
zimage3x(i_ctx_t *i_ctx_p)
390
0
{
391
0
    os_ptr op = osp;
392
0
    gs_image3x_t image;
393
0
    ref *pDataDict;
394
0
    image_params ip_data;
395
0
    int num_components =
396
0
        gs_color_space_num_components(gs_currentcolorspace(igs));
397
0
    int ignored;
398
0
    int code;
399
400
0
    check_type(*op, t_dictionary);
401
0
    check_dict_read(*op);
402
0
    memset(&image, 0, sizeof(gs_image3x_t));
403
0
    gs_image3x_t_init(&image, NULL);
404
0
    if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
405
0
        return_error(gs_error_rangecheck);
406
0
    check_type(*pDataDict, t_dictionary);
407
0
    if ((code = pixel_image_params(i_ctx_p, pDataDict,
408
0
                   (gs_pixel_image_t *)&image, &ip_data,
409
0
                   16, gs_currentcolorspace(igs))) < 0 ||
410
0
        (code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0
411
0
        )
412
0
        return code;
413
    /*
414
     * We have to process the masks in the reverse order, because they
415
     * insert their DataSource before the one(s) for the DataDict.
416
     */
417
0
    if ((code = mask_dict_param(imemory, op, &ip_data,
418
0
                                "ShapeMaskDict", num_components,
419
0
                                &image.Shape)) < 0 ||
420
0
        (code = mask_dict_param(imemory, op, &ip_data,
421
0
                                "OpacityMaskDict", num_components,
422
0
                                &image.Opacity)) < 0
423
0
        )
424
0
        return code;
425
0
    return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
426
0
                        &ip_data.DataSource[0],
427
0
                        image.CombineWithColor, 1);
428
0
}
429
430
/* Get one soft-mask dictionary parameter. */
431
static int
432
mask_dict_param(const gs_memory_t *mem, os_ptr op,
433
image_params *pip_data, const char *dict_name,
434
                int num_components, gs_image3x_mask_t *pixm)
435
0
{
436
0
    ref *pMaskDict;
437
0
    image_params ip_mask;
438
0
    int ignored;
439
0
    int code, mcode;
440
441
0
    if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
442
0
        return 1;
443
0
    if (!r_has_type(pMaskDict, t_dictionary))
444
0
        return gs_note_error(gs_error_typecheck);
445
446
0
    if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
447
0
                                          &ip_mask, false, 1, 16, false)) < 0 ||
448
0
        (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
449
0
        (code = dict_int_param(pMaskDict, "InterleaveType", 1, 3, -1,
450
0
                               &pixm->InterleaveType)) < 0 ||
451
0
        (code = dict_floats_param(mem, op, "Matte", num_components,
452
0
                                  pixm->Matte, NULL)) < 0
453
0
        )
454
0
        return code;
455
0
    pixm->has_Matte = code > 0;
456
    /*
457
     * The MaskDict must have a DataSource iff InterleaveType == 3.
458
     */
459
0
    if ((pip_data->MultipleDataSources && pixm->InterleaveType != 3) ||
460
0
        ip_mask.MultipleDataSources ||
461
0
        mcode != (pixm->InterleaveType != 3)
462
0
        )
463
0
        return_error(gs_error_rangecheck);
464
0
    if (pixm->InterleaveType == 3) {
465
        /* Insert the mask DataSource before the data DataSources. */
466
0
        memmove(&pip_data->DataSource[1], &pip_data->DataSource[0],
467
0
                (countof(pip_data->DataSource) - 1) *
468
0
                sizeof(pip_data->DataSource[0]));
469
0
        pip_data->DataSource[0] = ip_mask.DataSource[0];
470
0
    }
471
0
    return 0;
472
0
}
473
474
/* depth .pushpdf14devicefilter - */
475
/* this is a filter operator, but we include it here to maintain
476
   modularity of the pdf14 transparency support */
477
static int
478
zpushpdf14devicefilter(i_ctx_t *i_ctx_p)
479
0
{
480
0
    int code;
481
0
    int depth;
482
0
    int spot_color_count = -1;    /* default is 'unknown' spot color count */
483
0
    os_ptr op = osp;
484
0
    gx_device *cdev = gs_currentdevice_inline(igs);
485
0
    dict_stack_t *dstack = &(i_ctx_p->dict_stack);
486
0
    ref_stack_t *rdstack = &dstack->stack;
487
0
    const ref *puserdict = ref_stack_index(rdstack, ref_stack_count(rdstack) - 1 -
488
0
                            dstack->userdict_index);
489
490
0
    check_op(1);
491
0
    check_type(*op, t_integer);
492
0
    depth = (int)op->value.intval;
493
494
0
    if (dev_proc(cdev, dev_spec_op)(cdev, gxdso_is_pdf14_device, NULL, 0) > 0)
495
0
        return 0;   /* ignore push_device if already is pdf14 device */
496
497
    /* Bug 698087: In case some program uses our .pushpdf14devicefilter  make */
498
    /*             sure that the device knows that we are using the pdf14 */
499
    /*             transparency. Note this will close and re-open the device  */
500
    /*             and erase the page. This should not occur with PDF files.  */
501
    /* We don't do this if this is a push for the overprint_sim mode    */
502
0
    if (depth >= 0 && cdev->page_uses_transparency == 0) {
503
0
        gs_c_param_list list;
504
0
        bool bool_true = 1;
505
506
0
        gs_c_param_list_write(&list, imemory);
507
0
        code = param_write_bool((gs_param_list *)&list, "PageUsesTransparency", &bool_true);
508
0
        if ( code >= 0) {
509
0
            gs_c_param_list_read(&list);
510
0
            code = gs_gstate_putdeviceparams(igs, cdev, (gs_param_list *)&list);
511
0
        }
512
0
        gs_c_param_list_release(&list);
513
0
        if (code < 0)
514
0
            return code;
515
0
        if (cdev->is_open) {
516
0
            if ((code = gs_closedevice((gx_device *)cdev)) < 0)
517
0
                return code;
518
0
        }
519
0
        if ((code = gs_opendevice((gx_device *)cdev)) < 0)
520
0
            return code;
521
0
        if ((code = gs_erasepage(igs)) < 0)
522
0
            return code;
523
0
    }
524
    /* Get the PageSpotColors value from the userdict, if it is defined */
525
0
    code = dict_int_param(puserdict, "PageSpotColors", -1, max_int, -1, &spot_color_count);
526
0
    if (code < 0)
527
0
        return code;
528
    /* and finally actually push the compositor device */
529
0
    code = gs_push_pdf14trans_device(igs, false, true, depth, spot_color_count);
530
0
    if (code < 0)
531
0
        return code;
532
0
    pop(1);
533
0
    return 0;
534
0
}
535
536
/* this is a filter operator, but we include it here to maintain
537
   modularity of the pdf14 transparency support */
538
static int
539
zpoppdf14devicefilter(i_ctx_t *i_ctx_p)
540
0
{
541
0
    return gs_pop_pdf14trans_device(igs, false);
542
0
}
543
544
/* Something has gone terribly wrong */
545
static int
546
zabortpdf14devicefilter(i_ctx_t *i_ctx_p)
547
0
{
548
0
    return gs_abort_pdf14trans_device(igs);
549
0
}
550
551
/* This is used to communicate to the transparency compositor
552
   when a q (save extended graphic state) occurs.  Since
553
   the softmask is part of the graphic state we need to know
554
   this to handle clist processing properly */
555
556
static int
557
zpushextendedgstate(i_ctx_t *i_ctx_p)
558
0
{
559
0
    int code;
560
0
    code = gs_push_transparency_state(igs);
561
0
    return(code);
562
0
}
563
564
/* This is used to communicate to the transparency compositor
565
   when a Q (restore extended graphic state) occurs.  Since
566
   the softmask is part of the graphic state we need to know
567
   this to handle clist processing properly */
568
569
static int
570
zpopextendedgstate(i_ctx_t *i_ctx_p)
571
0
{
572
0
    int code;
573
0
    code = gs_pop_transparency_state(igs, false);
574
0
    return(code);
575
0
}
576
577
static int
578
zsetstrokeconstantalpha(i_ctx_t *i_ctx_p)
579
0
{
580
0
    os_ptr op = osp;
581
0
    double value;
582
583
0
    if (real_param(op, &value) < 0)
584
0
        return_op_typecheck(op);
585
586
0
    gs_setstrokeconstantalpha(igs, (float)value);
587
0
    pop(1);
588
0
    return 0;
589
0
}
590
591
static int
592
zgetstrokeconstantalpha(i_ctx_t *i_ctx_p)
593
5
{
594
5
    return current_float_value(i_ctx_p, gs_getstrokeconstantalpha);
595
5
}
596
597
static int
598
zsetfillconstantalpha(i_ctx_t *i_ctx_p)
599
0
{
600
0
    os_ptr op = osp;
601
0
    double value;
602
603
0
    if (real_param(op, &value) < 0)
604
0
        return_op_typecheck(op);
605
606
0
    gs_setfillconstantalpha(igs, (float)value);
607
0
    pop(1);
608
0
    return 0;
609
0
}
610
611
static int
612
zgetfillconstantalpha(i_ctx_t *i_ctx_p)
613
7
{
614
7
    return current_float_value(i_ctx_p, gs_getfillconstantalpha);
615
7
}
616
617
static int
618
zsetalphaisshape(i_ctx_t *i_ctx_p)
619
0
{
620
0
    os_ptr op = osp;
621
622
0
    check_type(*op, t_boolean);
623
0
    gs_setalphaisshape(igs, op->value.boolval);
624
0
    pop(1);
625
626
0
    return 0;
627
0
}
628
629
static int
630
zgetalphaisshape(i_ctx_t *i_ctx_p)
631
0
{
632
0
    os_ptr op = osp;
633
634
0
    push(1);
635
0
    make_bool(op, gs_getalphaisshape(igs));
636
0
    return 0;
637
0
}
638
639
static int
640
zsetSMask(i_ctx_t *i_ctx_p)
641
0
{
642
0
    os_ptr op = osp;
643
644
0
    check_op(1);
645
646
0
    istate->SMask = *op;
647
0
    pop(1);
648
0
    return 0;
649
0
}
650
651
static int
652
zcurrentSMask(i_ctx_t *i_ctx_p)
653
0
{
654
0
    os_ptr op = osp;
655
656
0
    push(1);
657
0
    *op = istate->SMask;
658
0
    return 0;
659
0
}
660
661
/* ------ Initialization procedure ------ */
662
663
/* We need to split the table because of the 16-element limit. */
664
const op_def ztrans1_op_defs[] = {
665
    {"1.setblendmode", zsetblendmode},
666
    {"0.currentblendmode", zcurrentblendmode},
667
    {"1.settextknockout", zsettextknockout},
668
    {"0.currenttextknockout", zcurrenttextknockout},
669
    {"0.pushextendedgstate", zpushextendedgstate},
670
    {"0.popextendedgstate", zpopextendedgstate},
671
    op_def_end(0)
672
};
673
const op_def ztrans2_op_defs[] = {
674
    {"5.begintransparencygroup", zbegintransparencygroup},
675
    {"5.begintransparencypagegroup", zbegintransparencypagegroup},
676
    {"0.endtransparencygroup", zendtransparencygroup},
677
    { "0.endtransparencytextgroup", zendtransparencytextgroup },
678
    { "0.begintransparencytextgroup", zbegintransparencytextgroup },
679
    {"5.begintransparencymaskgroup", zbegintransparencymaskgroup},
680
    {"1.begintransparencymaskimage", zbegintransparencymaskimage},
681
    {"1.endtransparencymask", zendtransparencymask},
682
    {"1.image3x", zimage3x},
683
    {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
684
    {"0.poppdf14devicefilter", zpoppdf14devicefilter},
685
    {"0.abortpdf14devicefilter", zabortpdf14devicefilter},
686
    op_def_end(0)
687
};
688
689
const op_def ztrans3_op_defs[] = {
690
    {"1.setstrokeconstantalpha", zsetstrokeconstantalpha},
691
    {"0.currentstrokeconstantalpha", zgetstrokeconstantalpha},
692
    {"1.setfillconstantalpha", zsetfillconstantalpha},
693
    {"0.currentfillconstantalpha", zgetfillconstantalpha},
694
    {"1.setalphaisshape", zsetalphaisshape},
695
    {"0.currentalphaisshape", zgetalphaisshape},
696
    {"1.setSMask", zsetSMask},
697
    {"0.currentSMask", zcurrentSMask},
698
    op_def_end(0)
699
};