summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Resource/Init/gs_fonts.ps7
-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
-rw-r--r--psi/zpdfops.c55
8 files changed, 220 insertions, 57 deletions
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
index f1e26b093..aaee616f4 100644
--- a/Resource/Init/gs_fonts.ps
+++ b/Resource/Init/gs_fonts.ps
@@ -429,6 +429,11 @@ FONTPATH
%END FONTPATH
+/FONTMAP where
+{
+ dup /FONTMAP get /FONTMAP exch [ exch //.pathlist exec] put
+} if
+
% Try to enumerate native fonts registered with the os
% and add them to the fontmap. This relies on a custom
% operator which calls platform-specific C code. It
@@ -1315,7 +1320,7 @@ FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined
/.loadinitialfonts
{ NOFONTMAP not
{ /FONTMAP where
- { pop [ FONTMAP //.pathlist exec]
+ { pop FONTMAP
{ dup VMDEBUG findlibfile
{ exch pop //.loadFontmap exec }
{ /undefinedfilename signalerror }
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:
diff --git a/psi/zpdfops.c b/psi/zpdfops.c
index 20ac81ea9..abd1a3da0 100644
--- a/psi/zpdfops.c
+++ b/psi/zpdfops.c
@@ -338,6 +338,56 @@ done:
return code >= 0 ? 0 : code;
}
+static int zpdfi_populate_fontmap_files(i_ctx_t *i_ctx_p, pdf_context *ctx)
+{
+ int code, i;
+ ref *fontmaps;
+
+ code = dict_find_string(systemdict, "FONTMAP", &fontmaps);
+ if (code >= 0 && r_has_type(fontmaps, t_array)) {
+ ctx->fontmapfiles = (gs_string *)gs_alloc_bytes(ctx->memory, sizeof(gs_string) * r_size(fontmaps), "array of fontmap files");
+ if (ctx->fontmapfiles != 0) {
+ memset(ctx->fontmapfiles, 0x00, sizeof(gs_string) * r_size(fontmaps));
+ ctx->num_fontmapfiles = r_size(fontmaps);
+ for (i = 0; i < r_size(fontmaps); i++) {
+ const ref *fmapfile = fontmaps->value.refs + i; /* By nature, this cannot be a short/mixed array, only a "normal" array */
+ ctx->fontmapfiles[i].data = gs_alloc_bytes(ctx->memory, r_size(fmapfile), "zpdfi_populate_fontmap_files");
+ if (ctx->fontmapfiles[i].data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ memcpy((char *)ctx->fontmapfiles[i].data, fmapfile->value.const_bytes, r_size(fmapfile));
+ ctx->fontmapfiles[i].size = r_size(fmapfile);
+ }
+ }
+ else {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ }
+ else if (code >= 0 && r_has_type(fontmaps, t_string)) {
+ ctx->fontmapfiles = (gs_string *)gs_alloc_bytes(ctx->memory, sizeof(gs_string), "array of fontmap files");
+ if (ctx->fontmapfiles != 0) {
+ ctx->num_fontmapfiles = 1;
+ ctx->fontmapfiles[0].data = gs_alloc_bytes(ctx->memory, r_size(fontmaps), "zpdfi_populate_fontmap_files");
+ if (ctx->fontmapfiles[0].data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ memcpy((char *)ctx->fontmapfiles[0].data, fontmaps->value.const_bytes, r_size(fontmaps));
+ ctx->fontmapfiles[0].size = r_size(fontmaps);
+ }
+ else {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ }
+ else
+ code = 0;
+done:
+ return code;
+}
+
/*
* Declare the structure we use to represent an instance of the PDF parser
* as a t_struct.
@@ -1129,6 +1179,11 @@ static int zPDFInit(i_ctx_t *i_ctx_p)
code = zpdfi_populate_search_paths(i_ctx_p, ctx);
if (code < 0)
goto error;
+
+ code = zpdfi_populate_fontmap_files(i_ctx_p, ctx);
+ if (code < 0)
+ goto error;
+
op = osp;
push(1);
make_tav(op, t_pdfctx, icurrent_space | a_all, pstruct, (obj_header_t *)(pdfctx));