summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2021-11-04 14:33:01 +0000
committerChris Liddell <chris.liddell@artifex.com>2021-11-09 11:12:04 +0000
commitcb4156b9545f131698026106b289a5253f295e23 (patch)
tree6fdaa396b485780a94097453346e10f16e9d04ab /pdf
parent0a1d08d91a95746f41e8c1d578a4e4af81ee5949 (diff)
downloadghostpdl-cb4156b9545f131698026106b289a5253f295e23.tar.gz
Support user specified Fontmap files in pdfi
Handle -sFONTMAP param in gpdl, and copy the relevant strings from the Postscript world when pdfi is called from Ghostscript. To make things a little simpler, there is also a tweak to the Postscript code, so the FONTMAP parameter gets split into an array of strings during initialisation, rather than at use time, which saves doing that process once for Postscript and once for pdfi.
Diffstat (limited to 'pdf')
-rw-r--r--pdf/ghostpdf.c58
-rw-r--r--pdf/ghostpdf.h4
-rw-r--r--pdf/pdf_fmap.c90
-rw-r--r--pdf/pdf_fmap.h2
-rw-r--r--pdf/pdf_font.c53
-rw-r--r--pdf/pdftop.c8
6 files changed, 159 insertions, 56 deletions
diff --git a/pdf/ghostpdf.c b/pdf/ghostpdf.c
index e71d39649..0d703d261 100644
--- a/pdf/ghostpdf.c
+++ b/pdf/ghostpdf.c
@@ -1363,7 +1363,7 @@ static size_t pdfi_grdir_path_string_match(const byte *str, size_t sl0, byte *pa
int pdfi_add_paths_to_search_paths(pdf_context *ctx, const char *ppath, int l, bool fontpath)
{
- int i, slen, npaths = (l > 0);
+ int i, slen, npaths = (l > 0) ? 1 : 0;
const char *p = ppath;
char *ps;
const char *pe = p + l + 1;
@@ -1503,6 +1503,61 @@ static void pdfi_free_search_paths(pdf_context *ctx)
gs_free_object(ctx->memory, (byte *)ctx->search_paths.font_paths, "array of font paths");
}
+static void pdfi_free_fontmapfiles(pdf_context *ctx)
+{
+ int i;
+ for (i = 0; i < ctx->num_fontmapfiles; i++) {
+ gs_free_object(ctx->memory, ctx->fontmapfiles[i].data, "fontmapfiles string body");
+ }
+ gs_free_object(ctx->memory, ctx->fontmapfiles, "fontmapfiles array");
+}
+
+/* The fontmap file list doesn't extend, later settings in the command line override earlier ones
+ (Unlike the "-I" search paths above).
+ */
+int pdfi_add_fontmapfiles(pdf_context *ctx, const char *ppath, int l)
+{
+ int i, nfilenames = (l > 0) ? 1 : 0;
+ const char *p = ppath;
+ char *ps;
+ const char *pe = p + l + 1;
+ int code = 0;
+
+ pdfi_free_fontmapfiles(ctx);
+
+ for (ps = (char *)p; ps < pe; ps++) {
+ if (*ps == gp_file_name_list_separator)
+ nfilenames++;
+ }
+ if (nfilenames > 0) {
+ ctx->fontmapfiles = (gs_string *)gs_alloc_bytes(ctx->memory, sizeof(gs_string) * nfilenames, "array of fontmap files");
+ if (ctx->fontmapfiles == NULL) {
+ return_error(gs_error_VMerror);
+ }
+ else {
+ memset(ctx->fontmapfiles, 0x00, sizeof(gs_string) * nfilenames);
+ ctx->num_fontmapfiles = nfilenames;
+
+ for (i = 0; i < nfilenames; i++) {
+ for (ps = (char *)p; ps < pe; ps++) {
+ if (*ps == gp_file_name_list_separator)
+ break;
+ }
+ ctx->fontmapfiles[i].data = gs_alloc_bytes(ctx->memory, ps - p, "fontmap file name body");
+ if (ctx->fontmapfiles[i].data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ memcpy(ctx->fontmapfiles[i].data, p, ps - p);
+ ctx->fontmapfiles[i].size = ps - p;
+ p = ps + 1;
+ }
+ }
+ }
+done:
+ return code;
+}
+
/***********************************************************************************/
/* Highest level functions. The context we create here is returned to the 'PL' */
/* implementation, in future we plan to return it to PostScript by wrapping a */
@@ -1900,6 +1955,7 @@ int pdfi_free_context(pdf_context *ctx)
}
pdfi_free_search_paths(ctx);
+ pdfi_free_fontmapfiles(ctx);
gs_free_object(ctx->memory, ctx, "pdfi_free_context");
#if PDFI_LEAK_CHECK
diff --git a/pdf/ghostpdf.h b/pdf/ghostpdf.h
index 5dd7c70bf..0ba1d8884 100644
--- a/pdf/ghostpdf.h
+++ b/pdf/ghostpdf.h
@@ -479,6 +479,9 @@ typedef struct pdf_context_s
/* A name table :-( */
pdfi_name_entry_t *name_table;
+ gs_string *fontmapfiles;
+ int num_fontmapfiles;
+
search_paths_t search_paths;
pdf_dict *pdffontmap;
pdf_dict *pdfnativefontmap; /* Explicit mappings take precedence, hence we need separate dictionaries */
@@ -511,6 +514,7 @@ typedef struct pdf_context_s
int pdfi_add_paths_to_search_paths(pdf_context *ctx, const char *ppath, int l, bool fontpath);
int pdfi_add_initial_paths_to_search_paths(pdf_context *ctx, const char *ppath, int l);
+int pdfi_add_fontmapfiles(pdf_context *ctx, const char *ppath, int l);
pdf_context *pdfi_create_context(gs_memory_t *pmem);
int pdfi_clear_context(pdf_context *ctx);
diff --git a/pdf/pdf_fmap.c b/pdf/pdf_fmap.c
index 6420910f9..71cd2480c 100644
--- a/pdf/pdf_fmap.c
+++ b/pdf/pdf_fmap.c
@@ -33,7 +33,7 @@ typedef struct
const char *mappedname;
} pdfi_custom_fmap_entry;
-pdfi_custom_fmap_entry pdfi_custom_fmap_enties[] =
+pdfi_custom_fmap_entry pdfi_custom_fmap_entries[] =
{
{"Helv", "Helvetica"},
{NULL, NULL}
@@ -103,35 +103,62 @@ pdf_fontmap_open_file(pdf_context *ctx, const char *mapfilename, byte **buf, int
}
static int
-pdf_make_fontmap(pdf_context *ctx, const char *fmapname, bool cidfmap)
+pdf_make_fontmap(pdf_context *ctx, const char *default_fmapname, int cidfmap)
{
byte *fmapbuf = NULL;
int code, fmapbuflen;
pdf_c_stream *fmapstr = NULL;
pdf_stream fakedict = {0};
- pdfi_custom_fmap_entry *pcfe = pdfi_custom_fmap_enties;
- int i;
-
+ pdfi_custom_fmap_entry *pcfe = pdfi_custom_fmap_entries;
+ int i, j = 0;
+ char fmapname[gp_file_name_sizeof];
pdf_c_stream fakemainstream = {0};
+ int stacksize = pdfi_count_stack(ctx);
- code = pdf_fontmap_open_file(ctx, (const char *)fmapname, &fmapbuf, &fmapbuflen);
+ strncpy(fmapname, default_fmapname, strlen(default_fmapname) + 1);
+
+ code = pdfi_mark_stack(ctx, PDF_DICT_MARK);
if (code < 0)
- return code;
+ goto done;
- code = pdfi_open_memory_stream_from_memory(ctx, fmapbuflen, fmapbuf, &fmapstr, true);
- if (code >= 0) {
- int stacksize = pdfi_count_stack(ctx);
+ do {
+ if (j < ctx->num_fontmapfiles) {
+ memcpy(fmapname, ctx->fontmapfiles[j].data, ctx->fontmapfiles[j].size);
+ fmapname[ctx->fontmapfiles[j].size] = '\0';
+ }
- if (ctx->main_stream == NULL) {
- ctx->main_stream = &fakemainstream;
+ code = pdf_fontmap_open_file(ctx, (const char *)fmapname, &fmapbuf, &fmapbuflen);
+ if (code < 0) {
+ if (ctx->args.QUIET != true) {
+ (void)outwrite(ctx->memory, "Warning: ", 9);
+ if (cidfmap)
+ (void)outwrite(ctx->memory, "cidfmap file ", 13);
+ else
+ (void)outwrite(ctx->memory, "Fontmap file \"", 14);
+ (void)outwrite(ctx->memory, fmapname, strlen(fmapname));
+ (void)outwrite(ctx->memory, "\" not found.\n", 13);
+ code = 0;
+ }
}
- code = pdfi_mark_stack(ctx, PDF_DICT_MARK);
- if (code < 0)
- goto done;
- code = pdfi_interpret_content_stream(ctx, fmapstr, &fakedict, NULL);
- if (ctx->main_stream == &fakemainstream) {
- ctx->main_stream = NULL;
+ else {
+ code = pdfi_open_memory_stream_from_memory(ctx, fmapbuflen, fmapbuf, &fmapstr, true);
+ if (code >= 0) {
+
+ if (ctx->main_stream == NULL) {
+ ctx->main_stream = &fakemainstream;
+ }
+
+ code = pdfi_interpret_content_stream(ctx, fmapstr, &fakedict, NULL);
+ if (ctx->main_stream == &fakemainstream) {
+ ctx->main_stream = NULL;
+ }
+ gs_free_object(ctx->memory, fmapbuf, "pdf_make_fontmap(fmapbuf)");
+ }
}
+ j++;
+ } while(j < ctx->num_fontmapfiles && cidfmap == false && code >= 0);
+
+ if (code >= 0) {
if (code >= 0 && pdfi_count_stack(ctx) > stacksize) {
code = pdfi_dict_from_stack(ctx, 0, 0, true);
if (code < 0)
@@ -173,7 +200,22 @@ pdf_make_fontmap(pdf_context *ctx, const char *fmapname, bool cidfmap)
}
}
done:
- gs_free_object(ctx->memory, fmapbuf, "pdf_make_fontmap(fmapbuf)");
+ /* We always want to leave here with a valid map dictionary
+ even if it's empty
+ */
+ if (cidfmap == true) {
+ if (ctx->pdfcidfmap == NULL) {
+ code = pdfi_dict_alloc(ctx, 0, &ctx->pdfcidfmap);
+ pdfi_countup(ctx->pdfcidfmap);
+ }
+ }
+ else {
+ if (ctx->pdffontmap == NULL) {
+ code = pdfi_dict_alloc(ctx, 0, &ctx->pdffontmap);
+ pdfi_countup(ctx->pdffontmap);
+ }
+ }
+ pdfi_clearstack(ctx);
return code;
}
@@ -536,7 +578,7 @@ static bool font_scan_skip_file(char *fname)
static int pdfi_generate_native_fontmap(pdf_context *ctx)
{
file_enum *fe;
- int i, j;
+ int i;
char *patrn= NULL;
char *result = NULL;
char *working = NULL;
@@ -688,7 +730,7 @@ static int pdfi_generate_native_fontmap(pdf_context *ctx)
int
pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname, int *findex)
{
- int code, code2 = gs_error_undefined;
+ int code;
pdf_obj *mname;
*findex = -1;
@@ -714,7 +756,6 @@ pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname, in
subsitute name -> file name
So we want to loop until we no more hits.
*/
- code2 = 0;
while(1) {
pdf_obj *mname2;
code = pdfi_dict_get_by_key(ctx, ctx->pdffontmap, (pdf_name *)mname, &mname2);
@@ -728,7 +769,6 @@ pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname, in
code = pdfi_dict_get_by_key(ctx, ctx->pdfnativefontmap, fname, &record);
if (code < 0)
return code;
- code2 = 0;
if (record->type == PDF_STRING) {
mname = record;
}
@@ -746,11 +786,11 @@ pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname, in
}
}
- if (mname->type == PDF_STRING && pdfi_fmap_file_exists(ctx, (pdf_string *)mname)) {
+ if (mname != NULL && mname->type == PDF_STRING && pdfi_fmap_file_exists(ctx, (pdf_string *)mname)) {
*mapname = mname;
code = 0;
}
- else if (mname->type == PDF_NAME) { /* If we map to a name, we assume (for now) we have the font as a "built-in" */
+ else if (mname != NULL && mname->type == PDF_NAME) { /* If we map to a name, we assume (for now) we have the font as a "built-in" */
*mapname = mname;
code = 0;
}
diff --git a/pdf/pdf_fmap.h b/pdf/pdf_fmap.h
index 73ae6aee6..c76502039 100644
--- a/pdf/pdf_fmap.h
+++ b/pdf/pdf_fmap.h
@@ -17,7 +17,7 @@
or might be a string.
*/
int
-pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname);
+pdf_fontmap_lookup_font(pdf_context *ctx, pdf_name *fname, pdf_obj **mapname, int *findex);
/* The name parameter is to allow for internally derived font names to be looked up,
like, for example, /Adobe-Japan1
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c
index 1d9c56dc7..08b78f5b6 100644
--- a/pdf/pdf_font.c
+++ b/pdf/pdf_font.c
@@ -145,12 +145,18 @@ pdfi_font_match_glyph_widths(pdf_font *pdfont)
return code;
}
-static void pdfi_emprint_font_name(pdf_context *ctx, pdf_name *n)
+/* Print a name object to stdout */
+static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
{
- int i;
- for (i = 0; i < n->length; i++) {
- dmprintf1(ctx->memory, "%c", n->data[i]);
- }
+ if (ctx->args.QUIET != true)
+ (void)outwrite(ctx->memory, (const char *)n->data, n->length);
+}
+
+/* Print a null terminated string to stdout */
+static void pdfi_print_string(pdf_context *ctx, const char *str)
+{
+ if (ctx->args.QUIET != true)
+ (void)outwrite(ctx->memory, str, strlen(str));
}
/* Call with a CIDFont name to try to find the CIDFont on disk
@@ -195,12 +201,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
}
else {
if (cidname) {
- dmprintf(ctx->memory, "Loading CIDFont ");
- pdfi_emprint_font_name(ctx, (pdf_name *)cidname);
- dmprintf(ctx->memory, " substitute from ");
+ pdfi_print_string(ctx, "Loading CIDFont ");
+ pdfi_print_font_name(ctx, (pdf_name *)cidname);
+ pdfi_print_string(ctx, " substitute from ");
}
else {
- dmprintf(ctx->memory, "Loading nameless CIDFont from ");
+ pdfi_print_string(ctx, "Loading nameless CIDFont from ");
}
sfilename(s, &fname);
if (fname.size < gp_file_name_sizeof) {
@@ -210,7 +216,9 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
else {
strcpy(fontfname, "unnamed file");
}
- dmprintf1(ctx->memory, "%s.\n", fontfname);
+ pdfi_print_string(ctx, fontfname);
+ pdfi_print_string(ctx, "\n");
+
sfseek(s, 0, SEEK_END);
*buflen = sftell(s);
@@ -234,12 +242,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
}
else {
if (cidname) {
- dmprintf(ctx->memory, "Loading CIDFont ");
- pdfi_emprint_font_name(ctx, (pdf_name *)cidname);
- dmprintf(ctx->memory, " (or substitute) from ");
+ pdfi_print_string(ctx, "Loading CIDFont ");
+ pdfi_print_font_name(ctx, (pdf_name *)cidname);
+ pdfi_print_string(ctx, " (or substitute) from ");
}
else {
- dmprintf(ctx->memory, "Loading nameless CIDFont from ");
+ pdfi_print_string(ctx, "Loading nameless CIDFont from ");
}
sfilename(s, &fname);
if (fname.size < gp_file_name_sizeof) {
@@ -249,7 +257,8 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
else {
strcpy(fontfname, "unnamed file");
}
- dmprintf1(ctx->memory, "%s.\n", fontfname);
+ pdfi_print_string(ctx, fontfname);
+ pdfi_print_string(ctx, "\n");
sfseek(s, 0, SEEK_END);
*buflen = sftell(s);
sfseek(s, 0, SEEK_SET);
@@ -425,20 +434,6 @@ static const char *pdfi_font_substitute_by_flags(unsigned int flags)
return "Helvetica"; /* Really shouldn't ever happen */
}
-/* Print a name object to stdout */
-static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
-{
- if (ctx->args.QUIET != true)
- (void)outwrite(ctx->memory, (const char *)n->data, n->length);
-}
-
-/* Print a null terminated string to stdout */
-static void pdfi_print_string(pdf_context *ctx, const char *str)
-{
- if (ctx->args.QUIET != true)
- (void)outwrite(ctx->memory, str, strlen(str));
-}
-
enum {
no_type_font = -1,
type0_font = 0,
diff --git a/pdf/pdftop.c b/pdf/pdftop.c
index 3c56ca096..0e524336f 100644
--- a/pdf/pdftop.c
+++ b/pdf/pdftop.c
@@ -711,6 +711,14 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
return code;
code = pdfi_add_paths_to_search_paths(ctx, (const char *)s, slen, true);
}
+ if (!strncmp(param, "FONTMAP", 7)) {
+ char *s = NULL;
+ int slen;
+ code = plist_value_get_string_or_name(ctx, &pvalue, &s , &slen);
+ if (code < 0)
+ return code;
+ code = pdfi_add_fontmapfiles(ctx, (const char *)s, slen);
+ }
}
exit: