Coverage Report

Created: 2026-07-24 07:44

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