Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gximask.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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
/* Functions for masked fill optimization. */
18
#include "gx.h"
19
#include "memory_.h"
20
#include "gserrors.h"
21
#include "gsptype1.h"
22
#include "gsptype2.h"
23
#include "gxdevice.h"
24
#include "gxdcolor.h"
25
#include "gxcpath.h"
26
#include "gximask.h"
27
#include "gzacpath.h"
28
#include "gzcpath.h"
29
#include "gxdevsop.h"
30
31
/* Functions for masked fill optimization. */
32
/* Imagemask with a shading color would paint entire shading for each rectangle of the mask.
33
   These functions convert the mask into a clipping path and then render entire shading
34
   at once through it.
35
*/
36
37
int
38
gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, bool transpose,
39
                           const gx_clip_path *pcpath, gs_memory_t *mem, gs_logical_operation_t lop,
40
                           gx_device **cdev)
41
25.4M
{
42
25.4M
    if ((lop == lop_default) && (gx_dc_is_pattern2_color(pdevc) || gx_dc_is_pattern1_color_clist_based(pdevc))) {
43
834
        if (!dev_proc(dev, dev_spec_op)(dev, gxdso_pattern_can_accum, NULL, gs_no_id)) {
44
833
            extern_st(st_device_cpath_accum);
45
833
            gx_device_cpath_accum *pcdev;
46
833
            gs_fixed_rect cbox;
47
48
833
            if (pcpath == NULL)
49
0
                return_error(gs_error_nocurrentpoint);  /* close enough if no clip path */
50
833
            pcdev =  gs_alloc_struct(mem,
51
833
                    gx_device_cpath_accum, &st_device_cpath_accum, "gx_image_fill_masked_start");
52
833
            if (pcdev == NULL)
53
0
                return_error(gs_error_VMerror);
54
833
            gx_cpath_accum_begin(pcdev, mem, transpose);
55
833
            gx_cpath_outer_box(pcpath, &cbox);
56
833
            gx_cpath_accum_set_cbox(pcdev, &cbox);
57
833
            pcdev->rc.memory = mem;
58
833
            pcdev->width = dev->width;   /* For gx_default_copy_mono. */
59
833
            pcdev->height = dev->height; /* For gx_default_copy_mono. */
60
833
            gx_device_retain((gx_device *)pcdev, true);
61
833
            *cdev = (gx_device *)pcdev;
62
833
        } else{
63
1
            *cdev = dev;
64
1
        }
65
834
    } else
66
25.4M
        *cdev = dev;
67
25.4M
    return 0;
68
25.4M
}
69
70
int
71
gx_image_fill_masked_end(gx_device *dev, gx_device *tdev, const gx_device_color *pdevc)
72
822
{
73
822
    gx_device_cpath_accum *pcdev = (gx_device_cpath_accum *)dev;
74
822
    gx_clip_path cpath;
75
822
    gx_clip_path cpath_with_shading_bbox;
76
822
    const gx_clip_path *pcpath1 = &cpath;
77
822
    gx_device_clip cdev;
78
822
    int code, code1;
79
80
822
    gx_cpath_init_local(&cpath, pcdev->memory);
81
822
    code = gx_cpath_accum_end(pcdev, &cpath);
82
822
    if (code >= 0)
83
822
        code = gx_dc_pattern2_clip_with_bbox(pdevc, tdev, &cpath_with_shading_bbox, &pcpath1);
84
822
    gx_make_clip_device_on_stack(&cdev, pcpath1, tdev);
85
822
    if (code >= 0 && pcdev->bbox.p.x < pcdev->bbox.q.x) {
86
716
        code1 = gx_device_color_fill_rectangle(pdevc,
87
716
                    pcdev->bbox.p.x, pcdev->bbox.p.y,
88
716
                    pcdev->bbox.q.x - pcdev->bbox.p.x,
89
716
                    pcdev->bbox.q.y - pcdev->bbox.p.y,
90
716
                    (gx_device *)&cdev, lop_default, 0);
91
716
        if (code == 0)
92
716
            code = code1;
93
716
    }
94
822
    if (pcpath1 == &cpath_with_shading_bbox)
95
0
        gx_cpath_free(&cpath_with_shading_bbox, "s_image_cleanup");
96
822
    gx_device_retain((gx_device *)pcdev, false);
97
822
    gx_cpath_free(&cpath, "s_image_cleanup");
98
822
    return code;
99
822
}
100
101
int
102
gx_image_fill_masked(gx_device *dev,
103
    const byte *data, int data_x, int raster, gx_bitmap_id id,
104
    int x, int y, int width, int height,
105
    const gx_device_color *pdc, int depth,
106
    gs_logical_operation_t lop, const gx_clip_path *pcpath)
107
25.4M
{
108
25.4M
    gx_device *cdev = dev;
109
25.4M
    int code;
110
111
25.4M
    if ((code = gx_image_fill_masked_start(dev, pdc, false, pcpath, dev->memory, lop, &cdev)) < 0)
112
0
        return code;
113
114
25.4M
    if (cdev == dev)
115
25.4M
        code = (*dev_proc(cdev, fill_mask))(cdev, data, data_x, raster, id,
116
25.4M
                            x, y, width, height, pdc, depth, lop, pcpath);
117
743
    else {
118
        /* cdev != dev means that a cpath_accum device was inserted */
119
743
        gx_device_color dc_temp;   /* if fill_masked_start did cpath_accum, use pure color */
120
121
743
        set_nonclient_dev_color(&dc_temp, 1);    /* arbitrary color since cpath_accum doesn't use it */
122
743
        if ((code = (*dev_proc(cdev, fill_mask))(cdev, data, data_x, raster, id,
123
743
                            x, y, width, height, &dc_temp, depth, lop, pcpath)) < 0)
124
0
            return code;
125
743
        code = gx_image_fill_masked_end(cdev, dev, pdc);    /* fill with the actual device color */
126
743
    }
127
25.4M
    return code;
128
25.4M
}