summaryrefslogtreecommitdiff
path: root/pdf/pdf_file.c
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2021-09-03 11:26:43 +0100
committerChris Liddell <chris.liddell@artifex.com>2021-09-09 12:02:08 +0100
commit245ae9816d7a970347df194d1ea9ebaedb18ee12 (patch)
treec71ad5d25ec267c737d91db43d0f955104843ad1 /pdf/pdf_file.c
parent3ccbae8583ddc2e1c53b0fdfae05e1a57e36ba01 (diff)
downloadghostpdl-245ae9816d7a970347df194d1ea9ebaedb18ee12.tar.gz
gpdf: Build and use resource search path list
Also use the genericrsourcedir to find fonts. gpdf: allow setting of FONTPATH param gpdf/gs: Populate the pdfi search paths from the PS environment
Diffstat (limited to 'pdf/pdf_file.c')
-rw-r--r--pdf/pdf_file.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/pdf/pdf_file.c b/pdf/pdf_file.c
index 2666a55ea..214d448de 100644
--- a/pdf/pdf_file.c
+++ b/pdf/pdf_file.c
@@ -25,6 +25,7 @@
#include "stream.h"
#include "strimpl.h"
#include "strmio.h"
+#include "gpmisc.h"
#include "simscale.h" /* SIMScaleDecode */
#include "szlibx.h" /* Flate */
#include "spngpx.h" /* PNG Predictor */
@@ -1561,3 +1562,139 @@ pdfi_stream_to_buffer(pdf_context *ctx, pdf_stream *stream_obj, byte **buf, int6
*bufferlen = buflen;
return code;
}
+
+int pdfi_open_resource_file(pdf_context *ctx, const char *fname, const int fnamelen, stream **s)
+{
+ int code = 0;
+ if (fname == NULL || fnamelen == 0)
+ *s = NULL;
+ else if (gp_file_name_is_absolute(fname, fnamelen) || fname[0] == '%') {
+ /* If it's an absolute path or an explicit PS style device, just try to open it */
+ *s = sfopen(fname, "r", ctx->memory);
+ }
+ else {
+ char fnametotry[gp_file_name_sizeof];
+ uint fnlen;
+ gs_parsed_file_name_t pname;
+ gp_file_name_combine_result r;
+ int i, total;
+
+ *s = NULL;
+ i = 0;
+ total = ctx->search_paths.num_resource_paths - ctx->search_paths.num_init_resource_paths - 1;
+retry:
+ for (; i < total; i++) {
+ gs_param_string *ss = &ctx->search_paths.resource_paths[i];
+
+ if (ss->data[0] == '%') {
+ code = gs_parse_file_name(&pname, (char *)ss->data, ss->size, ctx->memory);
+ if (code < 0 || (pname.len + fnamelen >= gp_file_name_sizeof)) {
+ continue;
+ }
+ memcpy(fnametotry, pname.fname, pname.len);
+ memcpy(fnametotry + pname.len, fname, fnamelen);
+ code = pname.iodev->procs.open_file(pname.iodev, fnametotry, pname.len + fnamelen, "r", s, ctx->memory);
+ if (code < 0) {
+ continue;
+ }
+ break;
+ }
+ else {
+ fnlen = gp_file_name_sizeof;
+ r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
+ if (r != gp_combine_success || fnlen > gp_file_name_sizeof - 1)
+ continue;
+ fnametotry[fnlen] = '\0';
+ *s = sfopen(fnametotry, "r", ctx->memory);
+ if (*s != NULL)
+ break;
+ }
+ }
+ if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
+ gs_param_string *ss = &ctx->search_paths.genericresourcedir;
+ fnlen = gp_file_name_sizeof;
+ r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
+ if (r == gp_combine_success || fnlen < gp_file_name_sizeof) {
+ fnametotry[fnlen] = '\0';
+ *s = sfopen(fnametotry, "r", ctx->memory);
+ }
+ }
+ if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
+ total = ctx->search_paths.num_resource_paths;
+ goto retry;
+ }
+ }
+ if (*s == NULL)
+ return_error(gs_error_invalidfileaccess);
+
+ return 0;
+}
+
+int pdfi_open_font_file(pdf_context *ctx, const char *fname, const int fnamelen, stream **s)
+{
+ int code = 0;
+ const char *fontdirstr = "Font/";
+ const int fontdirstrlen = strlen(fontdirstr);
+
+ if (fname == NULL || fnamelen == 0)
+ *s = NULL;
+ else if (gp_file_name_is_absolute(fname, fnamelen) || fname[0] == '%') {
+ /* If it's an absolute path or an explicit PS style device, just try to open it */
+ *s = sfopen(fname, "r", ctx->memory);
+ }
+ else {
+ char fnametotry[gp_file_name_sizeof];
+ uint fnlen;
+ gs_parsed_file_name_t pname;
+ gp_file_name_combine_result r;
+ int i;
+
+ *s = NULL;
+ for (i = 0; i < ctx->search_paths.num_font_paths; i++) {
+ gs_param_string *ss = &ctx->search_paths.font_paths[i];
+
+ if (ss->data[0] == '%') {
+ code = gs_parse_file_name(&pname, (char *)ss->data, ss->size, ctx->memory);
+ if (code < 0 || (pname.len + fnamelen >= gp_file_name_sizeof)) {
+ continue;
+ }
+ memcpy(fnametotry, pname.fname, pname.len);
+ memcpy(fnametotry + pname.len, fname, fnamelen);
+ code = pname.iodev->procs.open_file(pname.iodev, fnametotry, pname.len + fnamelen, "r", s, ctx->memory);
+ if (code < 0) {
+ continue;
+ }
+ break;
+ }
+ else {
+ fnlen = gp_file_name_sizeof;
+ r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
+ if (r != gp_combine_success || fnlen > gp_file_name_sizeof - 1)
+ continue;
+ fnametotry[fnlen] = '\0';
+ *s = sfopen(fnametotry, "r", ctx->memory);
+ if (*s != NULL)
+ break;
+ }
+ }
+ if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
+ gs_param_string *ss = &ctx->search_paths.genericresourcedir;
+ char fstr[gp_file_name_sizeof];
+
+ fnlen = gp_file_name_sizeof;
+
+ memcpy(fstr, fontdirstr, fontdirstrlen);
+ memcpy(fstr + fontdirstrlen, fname, fnamelen);
+
+ r = gp_file_name_combine((char *)ss->data, ss->size, fstr, fontdirstrlen + fnamelen, false, fnametotry, &fnlen);
+ if (r == gp_combine_success || fnlen < gp_file_name_sizeof) {
+ fnametotry[fnlen] = '\0';
+ *s = sfopen(fnametotry, "r", ctx->memory);
+ }
+ }
+ }
+ if (*s == NULL)
+ return pdfi_open_resource_file(ctx, fname, fnamelen, s);
+
+ return 0;
+}