Coverage Report

Created: 2026-04-01 07:17

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