Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevkrnlsclass.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 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
#include "gx.h"
17
#include "gxdcolor.h"
18
#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently Page, Object, and Nup filter */
19
20
/* If set to '1' ths forces all devices to be loaded, even if they won't do anything.
21
 * This is useful for cluster testing that the very presence of a device doesn't
22
 * break anything. This requires that all of these devices pass through if the params
23
 * they use are 0/NULL.
24
 */
25
#define FORCE_TESTING_SUBCLASSING 0
26
27
/* This is used to mark the various internal subclass devices as having already
28
 * been pushed, so that opening the device won't result in us trying to push
29
 * them again, which leads to trouble. Currently this is only used by the PDF14
30
 * transparency compositor but there may be more users in future. It is mainly here
31
 * so tht only one file (this one) needs to be updated if we add more internal
32
 * classes.
33
 */
34
int mark_internal_subclass_devices(gx_device *new_device)
35
6.74k
{
36
6.74k
    new_device->PageHandlerPushed = true;
37
6.74k
    new_device->ObjectHandlerPushed = true;
38
6.74k
    new_device->NupHandlerPushed = true;
39
40
6.74k
    return 0;
41
6.74k
}
42
43
/* This installs the 'kernel' device classes. If you add any devices here you should
44
 * almost certainly edit gdevp14.c, gs_pdf14_device_push() and add the new device to the list
45
 * of devices which the push of the compositor claims are already installed (to prevent
46
 * a second copy being installed by gdev_prn_open).
47
 */
48
int install_internal_subclass_devices(gx_device **ppdev, bool *devices_loaded)
49
222k
{
50
222k
    int code = 0;
51
222k
    gx_device *dev = (gx_device *)*ppdev, *saved;
52
53
    /*
54
     * NOTE: the Nup device should precede the PageHandler so the FirstPage, LastPage
55
     *       and PageList will filter pages out BEFORE they are seen by the nesting.
56
     */
57
58
#if FORCE_TESTING_SUBCLASSING
59
    if (!dev->NupHandlerPushed) {
60
#else
61
222k
    if (!dev->NupHandlerPushed && dev->NupControl != 0) {
62
0
#endif
63
0
        code = gx_device_nup_device_install(dev);
64
0
        if (code < 0)
65
0
            return code;
66
67
0
        saved = dev = dev->child;
68
69
        /* Open all devices *after* the new current device */
70
0
        do {
71
0
            dev->is_open = true;
72
0
            dev = dev->child;
73
0
        }while(dev);
74
75
0
        dev = saved;
76
77
        /* Rewind to top device in chain */
78
0
        while(dev->parent)
79
0
            dev = dev->parent;
80
81
        /* Note in all devices in chain that we have loaded the NupHandler */
82
0
        do {
83
0
            dev->NupHandlerPushed = true;
84
0
            dev = dev->child;
85
0
        }while(dev);
86
87
0
        dev = saved;
88
0
        if (devices_loaded)
89
0
            *devices_loaded = true;
90
0
    }
91
#if FORCE_TESTING_SUBCLASSING
92
    if (!dev->PageHandlerPushed) {
93
#else
94
222k
    if (!dev->PageHandlerPushed && (dev->FirstPage != 0 || dev->LastPage != 0 || dev->PageList != 0)) {
95
0
#endif
96
0
        code = gx_device_subclass(dev, (gx_device *)&gs_flp_device, sizeof(first_last_subclass_data));
97
0
        if (code < 0)
98
0
            return code;
99
100
0
        saved = dev = dev->child;
101
102
        /* Open all devices *after* the new current device */
103
0
        do {
104
0
            dev->is_open = true;
105
0
            dev = dev->child;
106
0
        }while(dev);
107
108
0
        dev = saved;
109
110
        /* Rewind to top device in chain */
111
0
        while(dev->parent)
112
0
            dev = dev->parent;
113
114
        /* Note in all devices in chain that we have loaded the PageHandler */
115
0
        do {
116
0
            dev->PageHandlerPushed = true;
117
0
            dev = dev->child;
118
0
        }while(dev);
119
120
0
        dev = saved;
121
0
        if (devices_loaded)
122
0
            *devices_loaded = true;
123
0
    }
124
#if FORCE_TESTING_SUBCLASSING
125
    if (!dev->ObjectHandlerPushed) {
126
#else
127
222k
    if (!dev->ObjectHandlerPushed && dev->ObjectFilter != 0) {
128
0
#endif
129
0
        code = gx_device_subclass(dev, (gx_device *)&gs_obj_filter_device, sizeof(obj_filter_subclass_data));
130
0
        if (code < 0)
131
0
            return code;
132
133
0
        saved = dev = dev->child;
134
135
        /* Open all devices *after* the new current device */
136
0
        do {
137
0
            dev->is_open = true;
138
0
            dev = dev->child;
139
0
        }while(dev);
140
141
0
        dev = saved;
142
143
        /* Rewind to top device in chain */
144
0
        while(dev->parent)
145
0
            dev = dev->parent;
146
147
        /* Note in all devices in chain that we have loaded the ObjectHandler */
148
0
        do {
149
0
            dev->ObjectHandlerPushed = true;
150
0
            dev = dev->child;
151
0
        }while(dev);
152
153
0
        dev = saved;
154
0
        if (devices_loaded)
155
0
            *devices_loaded = true;
156
0
    }
157
222k
    *ppdev = dev;
158
222k
    return code;
159
222k
}