Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/source/xps/xps-resource.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/source/xps/xps-resource.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,183 @@ +// Copyright (C) 2004-2021 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see <https://www.artifex.com/> or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +#include "mupdf/fitz.h" +#include "xps-imp.h" + +#include <string.h> + +static fz_xml * +xps_lookup_resource(fz_context *ctx, xps_document *doc, xps_resource *dict, char *name, char **urip) +{ + xps_resource *head, *node; + for (head = dict; head; head = head->parent) + { + for (node = head; node; node = node->next) + { + if (!strcmp(node->name, name)) + { + if (urip && head->base_uri) + *urip = head->base_uri; + return node->data; + } + } + } + return NULL; +} + +static fz_xml * +xps_parse_resource_reference(fz_context *ctx, xps_document *doc, xps_resource *dict, char *att, char **urip) +{ + char name[1024]; + char *s; + + if (strstr(att, "{StaticResource ") != att) + return NULL; + + fz_strlcpy(name, att + 16, sizeof name); + s = strrchr(name, '}'); + if (s) + *s = 0; + + return xps_lookup_resource(ctx, doc, dict, name, urip); +} + +void +xps_resolve_resource_reference(fz_context *ctx, xps_document *doc, xps_resource *dict, + char **attp, fz_xml **tagp, char **urip) +{ + if (*attp) + { + fz_xml *rsrc = xps_parse_resource_reference(ctx, doc, dict, *attp, urip); + if (rsrc) + { + *attp = NULL; + *tagp = rsrc; + } + } +} + +static xps_resource * +xps_parse_remote_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, char *source_att) +{ + char part_name[1024]; + char part_uri[1024]; + xps_part *part; + xps_resource *dict = NULL; + fz_xml_doc *xml = NULL; + char *s; + + fz_var(xml); + + /* External resource dictionaries MUST NOT reference other resource dictionaries */ + xps_resolve_url(ctx, doc, part_name, base_uri, source_att, sizeof part_name); + + part = xps_read_part(ctx, doc, part_name); + fz_try(ctx) + { + xml = fz_parse_xml(ctx, part->data, 0); + if (!fz_xml_is_tag(fz_xml_root(xml), "ResourceDictionary")) + fz_throw(ctx, FZ_ERROR_FORMAT, "expected ResourceDictionary element"); + + fz_strlcpy(part_uri, part_name, sizeof part_uri); + s = strrchr(part_uri, '/'); + if (s) + s[1] = 0; + + dict = xps_parse_resource_dictionary(ctx, doc, part_uri, fz_xml_root(xml)); + if (dict) + { + dict->base_xml = xml; /* pass on ownership */ + xml = NULL; + } + } + fz_always(ctx) + { + xps_drop_part(ctx, doc, part); + fz_drop_xml(ctx, xml); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } + + return dict; +} + +xps_resource * +xps_parse_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, fz_xml *root) +{ + xps_resource *head; + xps_resource *entry; + fz_xml *node; + char *source; + char *key; + + source = fz_xml_att(root, "Source"); + if (source) + return xps_parse_remote_resource_dictionary(ctx, doc, base_uri, source); + + head = NULL; + + for (node = fz_xml_down(root); node; node = fz_xml_next(node)) + { + key = fz_xml_att(node, "x:Key"); + if (key) + { + entry = fz_malloc_struct(ctx, xps_resource); + entry->name = key; + entry->base_uri = NULL; + entry->base_xml = NULL; + entry->data = node; + entry->next = head; + entry->parent = NULL; + head = entry; + } + } + + if (head) + { + fz_try(ctx) + head->base_uri = fz_strdup(ctx, base_uri); + fz_catch(ctx) + { + fz_free(ctx, entry); + fz_rethrow(ctx); + } + } + + return head; +} + +void +xps_drop_resource_dictionary(fz_context *ctx, xps_document *doc, xps_resource *dict) +{ + xps_resource *next; + while (dict) + { + next = dict->next; + fz_drop_xml(ctx, dict->base_xml); + fz_free(ctx, dict->base_uri); + fz_free(ctx, dict); + dict = next; + } +}
