ztrans.c 20.5 KB
Newer Older
1
/* Copyright (C) 2001-2019 Artifex Software, Inc.
2 3 4 5 6
   All Rights Reserved.

   This software is provided AS-IS with no warranty, either express or
   implied.

7 8 9 10 11
   This software is distributed under license and may not be copied,
   modified or distributed except as expressly authorized under the terms
   of the license contained in the file LICENSE in this distribution.

   Refer to licensing information at http://www.artifex.com or contact
12 13
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14 15
*/

16

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/* Transparency operators */
#include "string_.h"
#include "memory_.h"
#include "ghost.h"
#include "oper.h"
#include "gscspace.h"		/* for gscolor2.h */
#include "gscolor2.h"
#include "gsipar3x.h"
#include "gstrans.h"
#include "gxiparam.h"		/* for image enumerator */
#include "gxcspace.h"
#include "idict.h"
#include "idparam.h"
#include "ifunc.h"
#include "igstate.h"
#include "iimage.h"
#include "iname.h"
#include "store.h"
35
#include "gspaint.h"		/* gs_erasepage prototype */
36
#include "gdevdevn.h"
37
#include "gxdevsop.h"
38 39
#include "gxblend.h"
#include "gdevp14.h"
40
#include "gsicc_cms.h"
41 42 43 44

/* ------ Utilities ------ */

static int
45
set_float_value(i_ctx_t *i_ctx_p, int (*set_value)(gs_gstate *, double))
46 47 48 49 50 51
{
    os_ptr op = osp;
    double value;
    int code;

    if (real_param(op, &value) < 0)
52
        return_op_typecheck(op);
53
    if ((code = set_value(igs, value)) < 0)
54
        return code;
55 56 57 58 59 60
    pop(1);
    return 0;
}

static int
current_float_value(i_ctx_t *i_ctx_p,
61
                    float (*current_value)(const gs_gstate *))
62 63 64 65 66 67 68 69 70 71
{
    os_ptr op = osp;

    push(1);
    make_real(op, current_value(igs));
    return 0;
}

static int
enum_param(const gs_memory_t *mem, const ref *pnref,
72
           const char *const names[])
73 74 75 76
{
    const char *const *p;
    ref nsref;

77 78
    check_type(*pnref, t_name);

79 80
    name_string_ref(mem, pnref, &nsref);
    for (p = names; *p; ++p)
81 82 83 84
        if (r_size(&nsref) == strlen(*p) &&
            !memcmp(*p, nsref.value.const_bytes, r_size(&nsref))
            )
            return p - names;
85
    return_error(gs_error_rangecheck);
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
}

/* ------ Graphics state operators ------ */

static const char *const blend_mode_names[] = {
    GS_BLEND_MODE_NAMES, 0
};

/* <modename> .setblendmode - */
static int
zsetblendmode(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;

    check_type(*op, t_name);
    if ((code = enum_param(imemory, op, blend_mode_names)) < 0 ||
103 104 105
        (code = gs_setblendmode(igs, code)) < 0
        )
        return code;
106 107 108 109 110 111 112 113 114 115 116 117 118 119
    pop(1);
    return 0;
}

/* - .currentblendmode <modename> */
static int
zcurrentblendmode(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const char *mode_name = blend_mode_names[gs_currentblendmode(igs)];
    ref nref;
    int code = name_enter_string(imemory, mode_name, &nref);

    if (code < 0)
120
        return code;
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    push(1);
    *op = nref;
    return 0;
}

/* <0..1> .setopacityalpha - */
static int
zsetopacityalpha(i_ctx_t *i_ctx_p)
{
    return set_float_value(i_ctx_p, gs_setopacityalpha);
}

/* - .currentopacityalpha <0..1> */
static int
zcurrentopacityalpha(i_ctx_t *i_ctx_p)
{
    return current_float_value(i_ctx_p, gs_currentopacityalpha);
}

/* <0..1> .setshapealpha - */
static int
zsetshapealpha(i_ctx_t *i_ctx_p)
{
    return set_float_value(i_ctx_p, gs_setshapealpha);
}

/* - .currentshapealpha <0..1> */
static int
zcurrentshapealpha(i_ctx_t *i_ctx_p)
{
    return current_float_value(i_ctx_p, gs_currentshapealpha);
}

/* <bool> .settextknockout - */
static int
zsettextknockout(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_type(*op, t_boolean);
    gs_settextknockout(igs, op->value.boolval);
    pop(1);
    return 0;
}

/* - .currenttextknockout <bool> */
static int
zcurrenttextknockout(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    push(1);
    make_bool(op, gs_currenttextknockout(igs));
    return 0;
}

/* ------ Rendering stack operators ------ */

static int
rect_param(gs_rect *prect, os_ptr op)
{
    double coords[4];
    int code = num_params(op, 4, coords);

    if (code < 0)
186
        return code;
187 188 189 190 191 192 193
    prect->p.x = coords[0], prect->p.y = coords[1];
    prect->q.x = coords[2], prect->q.y = coords[3];
    return 0;
}

static int
mask_op(i_ctx_t *i_ctx_p,
194
        int (*mask_proc)(gs_gstate *, gs_transparency_channel_selector_t))
195 196 197 198 199
{
    int csel;
    int code = int_param(osp, 1, &csel);

    if (code < 0)
200
        return code;
201 202
    code = mask_proc(igs, csel);
    if (code >= 0)
203
        pop(1);
204 205 206 207
    return code;

}

208
static int common_transparency_group(i_ctx_t *i_ctx_p, pdf14_compositor_operations group_type)
209 210 211 212 213
{
    os_ptr op = osp;
    os_ptr dop = op - 4;
    gs_transparency_group_params_t params;
    gs_rect bbox;
214
    ref *dummy;
215 216 217 218 219 220
    int code;

    check_type(*dop, t_dictionary);
    check_dict_read(*dop);
    gs_trans_group_params_init(&params);
    if ((code = dict_bool_param(dop, "Isolated", false, &params.Isolated)) < 0 ||
221 222 223 224
        (code = dict_bool_param(dop, "Knockout", false, &params.Knockout)) < 0 ||
        (code = dict_bool_param(dop, ".image_with_SMask", false, &params.image_with_SMask)) < 0
        )
        return code;
225 226
    code = rect_param(&bbox, op);
    if (code < 0)
227
        return code;
228 229 230
    /* If the CS is not given in the transparency group dict, set to NULL   */
    /* so that the transparency code knows to inherit from the parent layer */
    if (dict_find_string(dop, "CS", &dummy) <= 0) {
231
        params.ColorSpace = NULL;
232
    } else {
233
        /* the PDF interpreter sets the colorspace, so use it */
234
        params.ColorSpace = gs_currentcolorspace(igs);
235
        /* Lets make sure that it is not an ICC color space that came from
236 237 238 239 240 241 242
           a PS CIE color space or a PS color space. These are 1-way color
           spaces and cannot be used for group color spaces */
        if (gs_color_space_is_PSCIE(params.ColorSpace))
            params.ColorSpace = NULL;
        else if (gs_color_space_is_ICC(params.ColorSpace) &&
            params.ColorSpace->cmm_icc_profile_data != NULL &&
            params.ColorSpace->cmm_icc_profile_data->profile_handle != NULL) {
243 244
            if (gscms_is_input(params.ColorSpace->cmm_icc_profile_data->profile_handle,
                params.ColorSpace->cmm_icc_profile_data->memory))
245 246
                params.ColorSpace = NULL;
        }
247
    }
248
    code = gs_begin_transparency_group(igs, &params, &bbox, group_type);
249
    if (code < 0)
250
        return code;
251 252 253 254
    pop(5);
    return code;
}

255 256 257 258 259 260 261 262 263 264 265 266 267 268
/* <paramdict> <llx> <lly> <urx> <ury> .beginpagegroup - */
static int
zbegintransparencypagegroup(i_ctx_t *i_ctx_p)
{
    return common_transparency_group(i_ctx_p, PDF14_BEGIN_TRANS_PAGE_GROUP);
}

/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencygroup - */
static int
zbegintransparencygroup(i_ctx_t *i_ctx_p)
{
    return common_transparency_group(i_ctx_p, PDF14_BEGIN_TRANS_GROUP);
}

269 270 271 272 273 274 275
/* - .endtransparencygroup - */
static int
zendtransparencygroup(i_ctx_t *i_ctx_p)
{
    return gs_end_transparency_group(igs);
}

276 277 278 279 280 281 282 283 284 285 286 287 288 289
/* - .endtransparencytextgroup - */
static int
zendtransparencytextgroup(i_ctx_t *i_ctx_p)
{
    return gs_end_transparency_text_group(igs);
}

/* - .begintransparencytextgroup - */
static int
zbegintransparencytextgroup(i_ctx_t *i_ctx_p)
{
    return gs_begin_transparency_text_group(igs);
}

290 291
/* <cs_set?> <paramdict> <llx> <lly> <urx> <ury> .begintransparencymaskgroup -	*/
/*             cs_set == false if we are inheriting the colorspace		*/
292
static int tf_using_function(double, float *, void *);
293 294 295 296 297 298 299 300 301 302
static int
zbegintransparencymaskgroup(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr dop = op - 4;
    gs_transparency_mask_params_t params;
    ref *pparam;
    gs_rect bbox;
    int code;
    static const char *const subtype_names[] = {
303
        GS_TRANSPARENCY_MASK_SUBTYPE_NAMES, 0
304 305 306 307 308
    };

    check_type(*dop, t_dictionary);
    check_dict_read(*dop);
    if (dict_find_string(dop, "Subtype", &pparam) <= 0)
309
        return_error(gs_error_rangecheck);
310
    if ((code = enum_param(imemory, pparam, subtype_names)) < 0)
311
        return code;
312 313 314
    gs_trans_mask_params_init(&params, code);
    params.replacing = true;
    if ((code = dict_floats_param(imemory, dop, "Background",
315 316 317
                    cs_num_components(gs_currentcolorspace(i_ctx_p->pgs)),
                                  params.Background, NULL)) < 0)
        return code;
318
    else if (code > 0)
319
        params.Background_components = code;
320

321
    if ((code = dict_floats_param(imemory, dop, "GrayBackground",
322 323
                    1, &params.GrayBackground, NULL)) < 0)
        return code;
324
    if (dict_find_string(dop, "TransferFunction", &pparam) > 0) {
325
        gs_function_t *pfn = ref_function(pparam);
326

327
        if (pfn == 0 || pfn->params.m != 1 || pfn->params.n != 1)
328
            return_error(gs_error_rangecheck);
329 330
        params.TransferFunction = tf_using_function;
        params.TransferFunction_data = pfn;
331 332 333
    }
    code = rect_param(&bbox, op);
    if (code < 0)
334
        return code;
335 336
    check_type(op[-5], t_boolean);

337 338
    /* Is the colorspace set for this mask ? */
    if (op[-5].value.boolval) {
339
                params.ColorSpace = gs_currentcolorspace(igs);
340 341 342 343 344 345 346 347
                /* Lets make sure that it is not an ICC color space that came from
                a PS CIE color space or a PS color space. These are 1-way color
                spaces and cannot be used for group color spaces */
                if (gs_color_space_is_PSCIE(params.ColorSpace))
                    params.ColorSpace = NULL;
                else if (gs_color_space_is_ICC(params.ColorSpace) &&
                    params.ColorSpace->cmm_icc_profile_data != NULL &&
                    params.ColorSpace->cmm_icc_profile_data->profile_handle != NULL) {
348 349
                    if (gscms_is_input(params.ColorSpace->cmm_icc_profile_data->profile_handle,
                        params.ColorSpace->cmm_icc_profile_data->memory))
350 351
                        params.ColorSpace = NULL;
                }
352
    } else {
353
        params.ColorSpace = NULL;
354
    }
355 356
    code = gs_begin_transparency_mask(igs, &params, &bbox, false);
    if (code < 0)
357
        return code;
358
    pop(6);
359 360 361
    return code;
}

362
/* <paramdict> .begintransparencymaskimage <paramdict> */
363 364 365
static int
zbegintransparencymaskimage(i_ctx_t *i_ctx_p)
{
366
    os_ptr dop = osp;
367 368 369
    gs_transparency_mask_params_t params;
    gs_rect bbox = { { 0, 0} , { 1, 1} };
    int code;
370
    gs_color_space *gray_cs = gs_cspace_new_DeviceGray(imemory);
371

372 373
    check_type(*dop, t_dictionary);
    check_dict_read(*dop);
374
    if (!gray_cs)
375
        return_error(gs_error_VMerror);
376
    gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
377 378 379 380 381 382 383
    if ((code = dict_float_array_check_param(imemory, dop, "Matte",
                                  GS_CLIENT_COLOR_MAX_COMPONENTS,
                                  params.Matte, NULL, 0,
                                  gs_error_rangecheck)) < 0)
        return code;
    else if (code > 0)
        params.Matte_components = code;
384 385
    code = gs_begin_transparency_mask(igs, &params, &bbox, true);
    if (code < 0)
386
        return code;
387
    rc_decrement_cs(gray_cs, "zbegintransparencymaskimage");
388 389 390 391 392
    return code;
}

/* Implement the TransferFunction using a Function. */
static int
393
tf_using_function(double in_val, float *out, void *proc_data)
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
{
    float in = in_val;
    gs_function_t *const pfn = proc_data;

    return gs_function_evaluate(pfn, &in, out);
}

/* <mask#> .endtransparencymask - */
static int
zendtransparencymask(i_ctx_t *i_ctx_p)
{
    return mask_op(i_ctx_p, gs_end_transparency_mask);
}

/* ------ Soft-mask images ------ */

/* <dict> .image3x - */
static int mask_dict_param(const gs_memory_t *mem, os_ptr,
412 413
                            image_params *, const char *, int,
                            gs_image3x_mask_t *);
414 415 416 417 418 419 420 421
static int
zimage3x(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_image3x_t image;
    ref *pDataDict;
    image_params ip_data;
    int num_components =
422
        gs_color_space_num_components(gs_currentcolorspace(igs));
423 424 425 426 427
    int ignored;
    int code;

    check_type(*op, t_dictionary);
    check_dict_read(*op);
428
    memset(&image, 0, sizeof(gs_image3x_t));
429 430
    gs_image3x_t_init(&image, NULL);
    if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
431
        return_error(gs_error_rangecheck);
432
    check_type(*pDataDict, t_dictionary);
433
    if ((code = pixel_image_params(i_ctx_p, pDataDict,
434
                   (gs_pixel_image_t *)&image, &ip_data,
435
                   16, gs_currentcolorspace(igs))) < 0 ||
436 437 438
        (code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0
        )
        return code;
439 440 441 442 443
    /*
     * We have to process the masks in the reverse order, because they
     * insert their DataSource before the one(s) for the DataDict.
     */
    if ((code = mask_dict_param(imemory, op, &ip_data,
444 445 446 447 448 449 450
                                "ShapeMaskDict", num_components,
                                &image.Shape)) < 0 ||
        (code = mask_dict_param(imemory, op, &ip_data,
                                "OpacityMaskDict", num_components,
                                &image.Opacity)) < 0
        )
        return code;
451
    return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
452 453
                        &ip_data.DataSource[0],
                        image.CombineWithColor, 1);
454 455 456 457 458 459
}

/* Get one soft-mask dictionary parameter. */
static int
mask_dict_param(const gs_memory_t *mem, os_ptr op,
image_params *pip_data, const char *dict_name,
460
                int num_components, gs_image3x_mask_t *pixm)
461 462 463 464 465 466 467
{
    ref *pMaskDict;
    image_params ip_mask;
    int ignored;
    int code, mcode;

    if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
468
        return 1;
469 470 471
    if (!r_has_type(pMaskDict, t_dictionary))
        return gs_note_error(gs_error_typecheck);

472
    if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
473
                                          &ip_mask, false, 1, 16, false)) < 0 ||
474 475 476 477 478 479 480
        (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
        (code = dict_int_param(pMaskDict, "InterleaveType", 1, 3, -1,
                               &pixm->InterleaveType)) < 0 ||
        (code = dict_floats_param(mem, op, "Matte", num_components,
                                  pixm->Matte, NULL)) < 0
        )
        return code;
481 482 483 484 485
    pixm->has_Matte = code > 0;
    /*
     * The MaskDict must have a DataSource iff InterleaveType == 3.
     */
    if ((pip_data->MultipleDataSources && pixm->InterleaveType != 3) ||
486 487 488
        ip_mask.MultipleDataSources ||
        mcode != (pixm->InterleaveType != 3)
        )
489
        return_error(gs_error_rangecheck);
490
    if (pixm->InterleaveType == 3) {
491 492 493 494 495
        /* Insert the mask DataSource before the data DataSources. */
        memmove(&pip_data->DataSource[1], &pip_data->DataSource[0],
                (countof(pip_data->DataSource) - 1) *
                sizeof(pip_data->DataSource[0]));
        pip_data->DataSource[0] = ip_mask.DataSource[0];
496 497 498 499 500 501 502 503 504 505 506 507
    }
    return 0;
}

/* depth .pushpdf14devicefilter - */
/* this is a filter operator, but we include it here to maintain
   modularity of the pdf14 transparency support */
static int
zpushpdf14devicefilter(i_ctx_t *i_ctx_p)
{
    int code;
    os_ptr op = osp;
508
    gx_device *cdev = gs_currentdevice_inline(igs);
509 510

    check_type(*op, t_integer);
511 512 513 514 515 516 517 518 519
    /* Bug 698087: In case some program uses our .pushpdf14devicefilter  make	*/
    /*             sure that the device knows that we are using the pdf14	*/
    /*             transparency. Note this will close and re-open the device	*/
    /*             and erase the page. This should not occur with PDF files.	*/
    if (cdev->page_uses_transparency == 0) {
        gs_c_param_list list;
        bool bool_true = 1;

        gs_c_param_list_write(&list, imemory);
520 521 522 523 524
        code = param_write_bool((gs_param_list *)&list, "PageUsesTransparency", &bool_true);
        if ( code >= 0) {
            gs_c_param_list_read(&list);
            code = gs_gstate_putdeviceparams(igs, cdev, (gs_param_list *)&list);
        }
525 526 527 528 529 530
        gs_c_param_list_release(&list);
        if (code < 0)
            return code;
        if (cdev->is_open) {
            if ((code = gs_closedevice((gx_device *)cdev)) < 0)
                return code;
531 532
            if (dev_proc(cdev, dev_spec_op)(cdev, gxdso_is_pdf14_device, NULL, 0) > 0)
                pdf14_disable_device(cdev);	/* should already be disabled  (bug 698306) */
533 534 535 536 537 538
        }
        if ((code = gs_opendevice((gx_device *)cdev)) < 0)
            return code;
        if ((code = gs_erasepage(igs)) < 0)
            return code;
    }
539
    code = gs_push_pdf14trans_device(igs, false, true);
540 541 542 543 544 545 546 547 548 549 550
    if (code < 0)
        return code;
    pop(1);
    return 0;
}

/* this is a filter operator, but we include it here to maintain
   modularity of the pdf14 transparency support */
static int
zpoppdf14devicefilter(i_ctx_t *i_ctx_p)
{
551
    return gs_pop_pdf14trans_device(igs, false);
552 553
}

554 555 556 557 558 559 560
/* Something has gone terribly wrong */
static int
zabortpdf14devicefilter(i_ctx_t *i_ctx_p)
{
    return gs_abort_pdf14trans_device(igs);
}

561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
/* This is used to communicate to the transparency compositor
   when a q (save extended graphic state) occurs.  Since
   the softmask is part of the graphic state we need to know
   this to handle clist processing properly */

static int
zpushextendedgstate(i_ctx_t *i_ctx_p)
{
    int code;
    code = gs_push_transparency_state(igs);
    return(code);
}

/* This is used to communicate to the transparency compositor
   when a Q (restore extended graphic state) occurs.  Since
   the softmask is part of the graphic state we need to know
   this to handle clist processing properly */

static int
zpopextendedgstate(i_ctx_t *i_ctx_p)
{
    int code;
583
    code = gs_pop_transparency_state(igs, false);
584 585 586
    return(code);
}

587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
static int
zsetstrokeconstantalpha(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double value;

    if (real_param(op, &value) < 0)
        return_op_typecheck(op);

    gs_setstrokeconstantalpha(igs, (float)value);
    pop(1);
    return 0;
}

static int
zgetstrokeconstantalpha(i_ctx_t *i_ctx_p)
{
    return current_float_value(i_ctx_p, gs_getstrokeconstantalpha);
}

static int
zsetfillconstantalpha(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double value;

    if (real_param(op, &value) < 0)
        return_op_typecheck(op);

    gs_setfillconstantalpha(igs, (float)value);
    pop(1);
    return 0;
}

static int
zgetfillconstantalpha(i_ctx_t *i_ctx_p)
{
    return current_float_value(i_ctx_p, gs_getfillconstantalpha);
}

static int
zsetalphaisshape(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_type(*op, t_boolean);
    gs_setalphaisshape(igs, op->value.boolval);
    pop(1);

    return 0;
}

static int
zgetalphaisshape(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    push(1);
    make_bool(op, gs_getalphaisshape(igs));
    return 0;
}

static int
zsetSMask(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_op(1);

    istate->SMask = *op;
    pop(1);
    return 0;
}

static int
zcurrentSMask(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    push(1);
    *op = istate->SMask;
    return 0;
}

671 672 673 674 675 676 677 678 679 680 681 682
/* ------ Initialization procedure ------ */

/* We need to split the table because of the 16-element limit. */
const op_def ztrans1_op_defs[] = {
    {"1.setblendmode", zsetblendmode},
    {"0.currentblendmode", zcurrentblendmode},
    {"1.setopacityalpha", zsetopacityalpha},
    {"0.currentopacityalpha", zcurrentopacityalpha},
    {"1.setshapealpha", zsetshapealpha},
    {"0.currentshapealpha", zcurrentshapealpha},
    {"1.settextknockout", zsettextknockout},
    {"0.currenttextknockout", zcurrenttextknockout},
683 684
    {"0.pushextendedgstate", zpushextendedgstate},
    {"0.popextendedgstate", zpopextendedgstate},
685 686 687 688
    op_def_end(0)
};
const op_def ztrans2_op_defs[] = {
    {"5.begintransparencygroup", zbegintransparencygroup},
689
    {"5.begintransparencypagegroup", zbegintransparencypagegroup},
690
    {"0.endtransparencygroup", zendtransparencygroup},
691 692
    { "0.endtransparencytextgroup", zendtransparencytextgroup },
    { "0.begintransparencytextgroup", zbegintransparencytextgroup },
693
    {"5.begintransparencymaskgroup", zbegintransparencymaskgroup},
694
    {"1.begintransparencymaskimage", zbegintransparencymaskimage},
695 696 697 698
    {"1.endtransparencymask", zendtransparencymask},
    {"1.image3x", zimage3x},
    {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
    {"0.poppdf14devicefilter", zpoppdf14devicefilter},
699
    {"0.abortpdf14devicefilter", zabortpdf14devicefilter},
700 701
    op_def_end(0)
};
702 703 704 705 706 707 708 709 710 711 712 713

const op_def ztrans3_op_defs[] = {
    {"1.setstrokeconstantalpha", zsetstrokeconstantalpha},
    {"0.currentstrokeconstantalpha", zgetstrokeconstantalpha},
    {"1.setfillconstantalpha", zsetfillconstantalpha},
    {"0.currentfillconstantalpha", zgetfillconstantalpha},
    {"1.setalphaisshape", zsetalphaisshape},
    {"0.currentalphaisshape", zgetalphaisshape},
    {"1.setSMask", zsetSMask},
    {"0.currentSMask", zcurrentSMask},
    op_def_end(0)
};