summaryrefslogtreecommitdiff
path: root/gs/src/zfont42.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/zfont42.c')
-rw-r--r--gs/src/zfont42.c94
1 files changed, 78 insertions, 16 deletions
diff --git a/gs/src/zfont42.c b/gs/src/zfont42.c
index c5afc068b..9652d8b2a 100644
--- a/gs/src/zfont42.c
+++ b/gs/src/zfont42.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1996, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -16,10 +16,10 @@
all copies.
*/
-/* zfont42.c */
+/*Id: zfont42.c */
/* Type 42 font creation operator */
+#include "memory_.h"
#include "ghost.h"
-#include "errors.h"
#include "oper.h"
#include "gsccode.h"
#include "gsmatrix.h"
@@ -32,18 +32,16 @@
/* Forward references */
private int z42_string_proc(P4(gs_font_type42 *, ulong, uint, const byte **));
+private int z42_gdir_get_outline(P3(gs_font_type42 *, uint, gs_const_string *));
/* <string|name> <font_dict> .buildfont11/42 <string|name> <font> */
/* Build a type 11 (TrueType CID-keyed) or 42 (TrueType) font. */
int
-build_gs_TrueType_font(os_ptr op, font_type ftype, const char _ds * bcstr,
- const char _ds * bgstr, build_font_options_t options)
+build_gs_TrueType_font(os_ptr op, font_type ftype, const char *bcstr,
+ const char *bgstr, build_font_options_t options)
{
build_proc_refs build;
- ref *psfnts;
- ref sfnts0;
-
-#define sfd (sfnts0.value.const_bytes)
+ ref sfnts, sfnts0, GlyphDirectory;
gs_font_type42 *pfont;
font_data *pdata;
int code;
@@ -52,23 +50,64 @@ build_gs_TrueType_font(os_ptr op, font_type ftype, const char _ds * bcstr,
if (code < 0)
return code;
check_type(*op, t_dictionary);
- if (dict_find_string(op, "sfnts", &psfnts) <= 0)
- return_error(e_invalidfont);
- if ((code = array_get(psfnts, 0L, &sfnts0)) < 0)
- return code;
- if (!r_has_type(&sfnts0, t_string))
- return_error(e_typecheck);
+ {
+ ref *psfnts;
+ ref *pGlyphDirectory;
+
+ if (dict_find_string(op, "sfnts", &psfnts) <= 0)
+ return_error(e_invalidfont);
+ if ((code = array_get(psfnts, 0L, &sfnts0)) < 0)
+ return code;
+ if (!r_has_type(&sfnts0, t_string))
+ return_error(e_typecheck);
+ if (dict_find_string(op, "GlyphDirectory", &pGlyphDirectory) <= 0)
+ make_null(&GlyphDirectory);
+ else if (!r_has_type(pGlyphDirectory, t_dictionary))
+ return_error(e_typecheck);
+ else
+ GlyphDirectory = *pGlyphDirectory;
+ /*
+ * Since build_gs_primitive_font may resize the dictionary and cause
+ * pointers to become invalid, save sfnts.
+ */
+ sfnts = *psfnts;
+ }
code = build_gs_primitive_font(op, (gs_font_base **) & pfont, ftype,
&st_gs_font_type42, &build, options);
if (code != 0)
return code;
pdata = pfont_data(pfont);
- ref_assign(&pdata->u.type42.sfnts, psfnts);
+ ref_assign(&pdata->u.type42.sfnts, &sfnts);
+ ref_assign(&pdata->u.type42.GlyphDirectory, &GlyphDirectory);
pfont->data.string_proc = z42_string_proc;
pfont->data.proc_data = (char *)pdata;
code = gs_type42_font_init(pfont);
if (code < 0)
return code;
+ /*
+ * Some versions of the Adobe PostScript Windows driver have a bug
+ * that causes them to output the FontBBox for Type 42 fonts in the
+ * 2048- or 4096-unit character space rather than a 1-unit space.
+ * Work around this here.
+ */
+ if (pfont->FontBBox.q.x - pfont->FontBBox.p.x > 100 ||
+ pfont->FontBBox.q.y - pfont->FontBBox.p.y > 100
+ ) {
+ float upem = pfont->data.unitsPerEm;
+
+ pfont->FontBBox.p.x /= upem;
+ pfont->FontBBox.p.y /= upem;
+ pfont->FontBBox.q.x /= upem;
+ pfont->FontBBox.q.y /= upem;
+ }
+ /*
+ * Apparently Adobe versions 2015 and later use an alternate
+ * method of accessing character outlines: instead of loca and glyf,
+ * they use a dictionary called GlyphDirectory. In this case,
+ * we use an alternate get_outline procedure.
+ */
+ if (!r_has_type(&GlyphDirectory, t_null))
+ pfont->data.get_outline = z42_gdir_get_outline;
return define_gs_font((gs_font *) pfont);
}
private int
@@ -86,6 +125,29 @@ const op_def zfont42_op_defs[] =
op_def_end(0)
};
+/* Get an outline from GlyphDirectory instead of loca / glyf. */
+private int
+z42_gdir_get_outline(gs_font_type42 * pfont, uint glyph_index,
+ gs_const_string * pgstr)
+{
+ const font_data *pfdata = pfont_data(pfont);
+ const ref *pgdir = &pfdata->u.type42.GlyphDirectory;
+ ref iglyph;
+ ref *pgdef;
+
+ make_int(&iglyph, glyph_index);
+ if (dict_find(pgdir, &iglyph, &pgdef) <= 0) {
+ pgstr->data = 0;
+ pgstr->size = 0;
+ } else if (!r_has_type(pgdef, t_string)) {
+ return_error(e_typecheck);
+ } else {
+ pgstr->data = pgdef->value.const_bytes;
+ pgstr->size = r_size(pgdef);
+ }
+ return 0;
+}
+
/* Procedure for accessing the sfnts array. */
private int
z42_string_proc(gs_font_type42 * pfont, ulong offset, uint length,