Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/xps/xpscommon.c
Line
Count
Source
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
/* XPS interpreter - common parse functions */
18
19
#include "ghostxps.h"
20
21
xps_item_t *
22
xps_lookup_alternate_content(xps_item_t *node)
23
0
{
24
0
    for (node = xps_down(node); node; node = xps_next(node))
25
0
    {
26
0
        if (xps_tag(node))
27
0
        {
28
0
            if (!strcmp(xps_tag(node), "Choice"))
29
0
            {
30
0
                const char *req = xps_att(node, "Requires");
31
0
                if (req && !strcmp(req, "xps"))
32
0
                    return xps_down(node);
33
0
            }
34
0
            if (!strcmp(xps_tag(node), "Fallback"))
35
0
                return xps_down(node);
36
0
        }
37
0
    }
38
0
    return NULL;
39
0
}
40
41
int
42
xps_parse_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
43
34
{
44
34
    if (!strcmp(xps_tag(node), "SolidColorBrush"))
45
0
        return xps_parse_solid_color_brush(ctx, base_uri, dict, node);
46
34
    if (!strcmp(xps_tag(node), "ImageBrush"))
47
12
    {
48
12
        int code = xps_parse_image_brush(ctx, base_uri, dict, node);
49
12
        if (code)
50
0
            gs_catch(code, "ignoring error in image brush");
51
12
        return gs_okay;
52
12
    }
53
22
    if (!strcmp(xps_tag(node), "VisualBrush"))
54
0
        return xps_parse_visual_brush(ctx, base_uri, dict, node);
55
22
    if (!strcmp(xps_tag(node), "LinearGradientBrush"))
56
11
        return xps_parse_linear_gradient_brush(ctx, base_uri, dict, node);
57
11
    if (!strcmp(xps_tag(node), "RadialGradientBrush"))
58
11
        return xps_parse_radial_gradient_brush(ctx, base_uri, dict, node);
59
0
    return gs_throw1(-1, "unknown brush tag: %s", xps_tag(node));
60
11
}
61
62
int
63
xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
64
11.2k
{
65
11.2k
    if (!strcmp(xps_tag(node), "Path"))
66
11.1k
        return xps_parse_path(ctx, base_uri, dict, node);
67
93
    if (!strcmp(xps_tag(node), "Glyphs"))
68
57
        return xps_parse_glyphs(ctx, base_uri, dict, node);
69
36
    if (!strcmp(xps_tag(node), "Canvas"))
70
25
        return xps_parse_canvas(ctx, base_uri, dict, node);
71
11
    if (!strcmp(xps_tag(node), "AlternateContent"))
72
0
    {
73
0
        node = xps_lookup_alternate_content(node);
74
0
        if (node)
75
0
            xps_parse_element(ctx, base_uri, dict, node);
76
0
    }
77
    /* skip unknown tags (like Foo.Resources and similar) */
78
11
    return 0;
79
36
}
80
81
void
82
xps_parse_render_transform(xps_context_t *ctx, char *transform, gs_matrix *matrix)
83
11
{
84
11
    float args[6];
85
11
    char *s = transform;
86
11
    int i;
87
88
11
    args[0] = 1.0; args[1] = 0.0;
89
11
    args[2] = 0.0; args[3] = 1.0;
90
11
    args[4] = 0.0; args[5] = 0.0;
91
92
77
    for (i = 0; i < 6 && *s; i++)
93
66
    {
94
66
        args[i] = atof(s);
95
132
        while (*s && *s != ',')
96
66
            s++;
97
66
        if (*s == ',')
98
55
            s++;
99
66
    }
100
101
11
    matrix->xx = args[0]; matrix->xy = args[1];
102
11
    matrix->yx = args[2]; matrix->yy = args[3];
103
11
    matrix->tx = args[4]; matrix->ty = args[5];
104
11
}
105
106
void
107
xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, gs_matrix *matrix)
108
0
{
109
0
    char *transform;
110
111
0
    gs_make_identity(matrix);
112
113
0
    if (!strcmp(xps_tag(root), "MatrixTransform"))
114
0
    {
115
0
        transform = xps_att(root, "Matrix");
116
0
        if (transform)
117
0
            xps_parse_render_transform(ctx, transform, matrix);
118
0
    }
119
0
}
120
121
void
122
xps_parse_rectangle(xps_context_t *ctx, char *text, gs_rect *rect)
123
12
{
124
12
    float args[4];
125
12
    char *s = text;
126
12
    int i;
127
128
12
    args[0] = 0.0; args[1] = 0.0;
129
12
    args[2] = 1.0; args[3] = 1.0;
130
131
60
    for (i = 0; i < 4 && *s; i++)
132
48
    {
133
48
        args[i] = atof(s);
134
100
        while (*s && *s != ',')
135
52
            s++;
136
48
        if (*s == ',')
137
36
            s++;
138
48
    }
139
140
12
    rect->p.x = args[0];
141
12
    rect->p.y = args[1];
142
12
    rect->q.x = args[0] + args[2];
143
12
    rect->q.y = args[1] + args[3];
144
12
}