Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gsclipsr.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
/* clipsave/cliprestore */
18
#include "gx.h"
19
#include "gserrors.h"
20
#include "gsclipsr.h"
21
#include "gsstruct.h"
22
#include "gxclipsr.h"
23
#include "gxfixed.h"    /* for gxpath.h */
24
#include "gxpath.h"
25
#include "gzstate.h"
26
27
/* Structure descriptors */
28
private_st_clip_stack();
29
30
/*
31
 * When we free a clip stack entry and the associated clip path.
32
 */
33
static void
34
rc_free_clip_stack(gs_memory_t * mem, void *vstack, client_name_t cname)
35
1
{
36
1
    gx_clip_stack_t *stack = (gx_clip_stack_t *)vstack;
37
38
1
    if (stack->rc.ref_count <= 1 ) {
39
1
        gx_clip_path *pcpath = stack->clip_path;
40
41
1
        gs_free_object(stack->rc.memory, stack, cname);
42
1
        gx_cpath_free(pcpath, "rc_free_clip_stack");
43
1
    }
44
1
}
45
46
/* clipsave */
47
int
48
gs_clipsave(gs_gstate *pgs)
49
1
{
50
1
    gs_memory_t *mem = pgs->memory;
51
1
    gx_clip_path *copy =
52
1
        gx_cpath_alloc_shared(pgs->clip_path, mem, "gs_clipsave(clip_path)");
53
1
    gx_clip_stack_t *stack =
54
1
        gs_alloc_struct(mem, gx_clip_stack_t, &st_clip_stack,
55
1
                        "gs_clipsave(stack)");
56
57
1
    if (copy == 0 || stack == 0) {
58
0
        gs_free_object(mem, stack, "gs_clipsave(stack)");
59
0
        gs_free_object(mem, copy, "gs_clipsave(clip_path)");
60
0
        return_error(gs_error_VMerror);
61
0
    }
62
1
    rc_init_free(stack, mem, 1, rc_free_clip_stack);
63
1
    stack->clip_path = copy;
64
1
    stack->next = pgs->clip_stack;
65
1
    pgs->clip_stack = stack;
66
1
    return 0;
67
1
}
68
69
/* cliprestore */
70
int
71
gs_cliprestore(gs_gstate *pgs)
72
3
{
73
3
    gx_clip_stack_t *stack = pgs->clip_stack;
74
75
3
    if (stack) {
76
0
        gx_clip_stack_t *next = stack->next;
77
0
        gx_clip_path *pcpath = stack->clip_path;
78
0
        int code;
79
80
0
        if (stack->rc.ref_count == 1) {
81
            /* Use assign_free rather than assign_preserve. */
82
0
            gs_free_object(stack->rc.memory, stack, "cliprestore");
83
0
            code = gx_cpath_assign_free(pgs->clip_path, pcpath);
84
0
        } else {
85
0
            code = gx_cpath_assign_preserve(pgs->clip_path, pcpath);
86
0
            if (code < 0)
87
0
                return code;
88
0
            --(stack->rc.ref_count);
89
0
        }
90
0
        pgs->clip_stack = next;
91
0
        return code;
92
3
    } else {
93
3
        return gx_cpath_assign_preserve(pgs->clip_path, pgs->saved->clip_path);
94
3
    }
95
3
}