Coverage Report

Created: 2026-09-14 07:34

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
33
{
44
33
    if (!strcmp(xps_tag(node), "SolidColorBrush"))
45
0
        return xps_parse_solid_color_brush(ctx, base_uri, dict, node);
46
33
    if (!strcmp(xps_tag(node), "ImageBrush"))
47
13
    {
48
13
        int code = xps_parse_image_brush(ctx, base_uri, dict, node);
49
13
        if (code)
50
0
            gs_catch(code, "ignoring error in image brush");
51
13
        return gs_okay;
52
13
    }
53
20
    if (!strcmp(xps_tag(node), "VisualBrush"))
54
0
        return xps_parse_visual_brush(ctx, base_uri, dict, node);
55
20
    if (!strcmp(xps_tag(node), "LinearGradientBrush"))
56
10
        return xps_parse_linear_gradient_brush(ctx, base_uri, dict, node);
57
10
    if (!strcmp(xps_tag(node), "RadialGradientBrush"))
58
10
        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
10
}
61
62
int
63
xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
64
9.92k
{
65
9.92k
    if (!strcmp(xps_tag(node), "Path"))
66
9.84k
        return xps_parse_path(ctx, base_uri, dict, node);
67
80
    if (!strcmp(xps_tag(node), "Glyphs"))
68
47
        return xps_parse_glyphs(ctx, base_uri, dict, node);
69
33
    if (!strcmp(xps_tag(node), "Canvas"))
70
23
        return xps_parse_canvas(ctx, base_uri, dict, node);
71
10
    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
10
    return 0;
79
33
}
80
81
void
82
xps_parse_render_transform(xps_context_t *ctx, char *transform, gs_matrix *matrix)
83
10
{
84
10
    float args[6];
85
10
    char *s = transform;
86
10
    int i;
87
88
10
    args[0] = 1.0; args[1] = 0.0;
89
10
    args[2] = 0.0; args[3] = 1.0;
90
10
    args[4] = 0.0; args[5] = 0.0;
91
92
70
    for (i = 0; i < 6 && *s; i++)
93
60
    {
94
60
        args[i] = atof(s);
95
120
        while (*s && *s != ',')
96
60
            s++;
97
60
        if (*s == ',')
98
50
            s++;
99
60
    }
100
101
10
    matrix->xx = args[0]; matrix->xy = args[1];
102
10
    matrix->yx = args[2]; matrix->yy = args[3];
103
10
    matrix->tx = args[4]; matrix->ty = args[5];
104
10
}
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
13
{
124
13
    float args[4];
125
13
    char *s = text;
126
13
    int i;
127
128
13
    args[0] = 0.0; args[1] = 0.0;
129
13
    args[2] = 1.0; args[3] = 1.0;
130
131
65
    for (i = 0; i < 4 && *s; i++)
132
52
    {
133
52
        args[i] = atof(s);
134
116
        while (*s && *s != ',')
135
64
            s++;
136
52
        if (*s == ',')
137
39
            s++;
138
52
    }
139
140
13
    rect->p.x = args[0];
141
13
    rect->p.y = args[1];
142
13
    rect->q.x = args[0] + args[2];
143
13
    rect->q.y = args[1] + args[3];
144
13
}