Coverage Report

Created: 2025-04-22 06:20

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