Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7639 views
1
#include "mupdf/xps.h"
2
3
static fz_xml *
4
xps_lookup_resource(fz_context *ctx, xps_document *doc, xps_resource *dict, char *name, char **urip)
5
{
6
xps_resource *head, *node;
7
for (head = dict; head; head = head->parent)
8
{
9
for (node = head; node; node = node->next)
10
{
11
if (!strcmp(node->name, name))
12
{
13
if (urip && head->base_uri)
14
*urip = head->base_uri;
15
return node->data;
16
}
17
}
18
}
19
return NULL;
20
}
21
22
static fz_xml *
23
xps_parse_resource_reference(fz_context *ctx, xps_document *doc, xps_resource *dict, char *att, char **urip)
24
{
25
char name[1024];
26
char *s;
27
28
if (strstr(att, "{StaticResource ") != att)
29
return NULL;
30
31
fz_strlcpy(name, att + 16, sizeof name);
32
s = strrchr(name, '}');
33
if (s)
34
*s = 0;
35
36
return xps_lookup_resource(ctx, doc, dict, name, urip);
37
}
38
39
void
40
xps_resolve_resource_reference(fz_context *ctx, xps_document *doc, xps_resource *dict,
41
char **attp, fz_xml **tagp, char **urip)
42
{
43
if (*attp)
44
{
45
fz_xml *rsrc = xps_parse_resource_reference(ctx, doc, dict, *attp, urip);
46
if (rsrc)
47
{
48
*attp = NULL;
49
*tagp = rsrc;
50
}
51
}
52
}
53
54
static xps_resource *
55
xps_parse_remote_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, char *source_att)
56
{
57
char part_name[1024];
58
char part_uri[1024];
59
xps_resource *dict;
60
xps_part *part;
61
fz_xml *xml;
62
char *s;
63
64
/* External resource dictionaries MUST NOT reference other resource dictionaries */
65
xps_resolve_url(ctx, doc, part_name, base_uri, source_att, sizeof part_name);
66
part = xps_read_part(ctx, doc, part_name);
67
fz_try(ctx)
68
{
69
xml = fz_parse_xml(ctx, part->data, part->size, 0);
70
}
71
fz_always(ctx)
72
{
73
xps_drop_part(ctx, doc, part);
74
}
75
fz_catch(ctx)
76
{
77
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
78
xml = NULL;
79
}
80
81
if (!xml)
82
return NULL;
83
84
if (strcmp(fz_xml_tag(xml), "ResourceDictionary"))
85
{
86
fz_drop_xml(ctx, xml);
87
fz_throw(ctx, FZ_ERROR_GENERIC, "expected ResourceDictionary element");
88
}
89
90
fz_strlcpy(part_uri, part_name, sizeof part_uri);
91
s = strrchr(part_uri, '/');
92
if (s)
93
s[1] = 0;
94
95
dict = xps_parse_resource_dictionary(ctx, doc, part_uri, xml);
96
if (dict)
97
dict->base_xml = xml; /* pass on ownership */
98
99
return dict;
100
}
101
102
xps_resource *
103
xps_parse_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, fz_xml *root)
104
{
105
xps_resource *head;
106
xps_resource *entry;
107
fz_xml *node;
108
char *source;
109
char *key;
110
111
source = fz_xml_att(root, "Source");
112
if (source)
113
return xps_parse_remote_resource_dictionary(ctx, doc, base_uri, source);
114
115
head = NULL;
116
117
for (node = fz_xml_down(root); node; node = fz_xml_next(node))
118
{
119
key = fz_xml_att(node, "x:Key");
120
if (key)
121
{
122
entry = fz_malloc_struct(ctx, xps_resource);
123
entry->name = key;
124
entry->base_uri = NULL;
125
entry->base_xml = NULL;
126
entry->data = node;
127
entry->next = head;
128
entry->parent = NULL;
129
head = entry;
130
}
131
}
132
133
if (head)
134
head->base_uri = fz_strdup(ctx, base_uri);
135
136
return head;
137
}
138
139
void
140
xps_drop_resource_dictionary(fz_context *ctx, xps_document *doc, xps_resource *dict)
141
{
142
xps_resource *next;
143
while (dict)
144
{
145
next = dict->next;
146
if (dict->base_xml)
147
fz_drop_xml(ctx, dict->base_xml);
148
if (dict->base_uri)
149
fz_free(ctx, dict->base_uri);
150
fz_free(ctx, dict);
151
dict = next;
152
}
153
}
154
155
void
156
xps_print_resource_dictionary(fz_context *ctx, xps_document *doc, xps_resource *dict)
157
{
158
while (dict)
159
{
160
if (dict->base_uri)
161
printf("URI = '%s'\n", dict->base_uri);
162
printf("KEY = '%s' VAL = %p\n", dict->name, dict->data);
163
if (dict->parent)
164
{
165
printf("PARENT = {\n");
166
xps_print_resource_dictionary(ctx, doc, dict->parent);
167
printf("}\n");
168
}
169
dict = dict->next;
170
}
171
}
172
173