diff options
Diffstat (limited to 'gs/src/zfont42.c')
-rw-r--r-- | gs/src/zfont42.c | 94 |
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, |