summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/pdf_font.c')
-rw-r--r--pdf/pdf_font.c938
1 files changed, 592 insertions, 346 deletions
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c
index fa716056..28ebe96e 100644
--- a/pdf/pdf_font.c
+++ b/pdf/pdf_font.c
@@ -34,11 +34,14 @@
#include "pdf_font0.h"
#include "pdf_fmap.h"
#include "gscencs.h" /* For gs_c_known_encode and gs_c_glyph_name */
+#include "gsagl.h"
#include "strmio.h"
#include "stream.h"
#include "gsstate.h" /* For gs_setPDFfontsize() */
+extern single_glyph_list_t SingleGlyphList[];
+
static int pdfi_gs_setfont(pdf_context *ctx, gs_font *pfont)
{
int code = 0;
@@ -78,7 +81,7 @@ bool pdfi_font_known_symbolic(pdf_obj *basefont)
int i;
pdf_name *nm = (pdf_name *)basefont;
- if (basefont != NULL && basefont->type == PDF_NAME) {
+ if (basefont != NULL && pdfi_type_of(basefont) == PDF_NAME) {
for (i = 0; known_symbolic_font_names[i].name != NULL; i++) {
if (nm->length == known_symbolic_font_names[i].namelen
&& !strncmp((char *)nm->data, known_symbolic_font_names[i].name, nm->length)) {
@@ -104,7 +107,7 @@ pdfi_font_match_glyph_widths(pdf_font *pdfont)
/* For "best" results, restrict to what we *hope* are A-Z,a-z */
sindex = pdfont->FirstChar < 96 ? 96 : pdfont->FirstChar;
- lindex = pdfont->LastChar > 122 ? 122 : pdfont->LastChar;
+ lindex = pdfont->LastChar > 122 ? 123 : pdfont->LastChar + 1;
for (i = sindex; i < lindex; i++) {
gs_glyph_info_t ginfo = {0};
@@ -156,8 +159,14 @@ static void pdfi_print_font_name(pdf_context *ctx, pdf_name *n)
(void)outwrite(ctx->memory, (const char *)n->data, n->length);
}
+static void pdfi_print_font_string(pdf_context *ctx, pdf_string *s)
+{
+ if (ctx->args.QUIET != true)
+ (void)outwrite(ctx->memory, (const char *)s->data, s->length);
+}
+
/* Print a null terminated string to stdout */
-static void pdfi_print_string(pdf_context *ctx, const char *str)
+static void pdfi_print_cstring(pdf_context *ctx, const char *str)
{
if (ctx->args.QUIET != true)
(void)outwrite(ctx->memory, str, strlen(str));
@@ -169,7 +178,7 @@ static void pdfi_print_string(pdf_context *ctx, const char *str)
Currently only loads subsitute - DroidSansFallback
*/
static int
-pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte ** buf, int64_t * buflen, int *findex)
+pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte ** buf, int64_t * buflen, int *findex)
{
int code = 0;
char fontfname[gp_file_name_sizeof];
@@ -184,12 +193,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
pdf_dict *csi = NULL;
code = pdfi_dict_get(ctx, font_dict, "CIDSystemInfo", (pdf_obj **)&csi);
- if (code >= 0 && csi->type == PDF_DICT) {
+ if (code >= 0 && pdfi_type_of(csi) == PDF_DICT) {
pdf_string *csi_reg = NULL, *csi_ord = NULL;
if (pdfi_dict_get(ctx, csi, "Registry", (pdf_obj **)&csi_reg) >= 0
&& pdfi_dict_get(ctx, csi, "Ordering", (pdf_obj **)&csi_ord) >= 0
- && csi_reg->type == PDF_STRING && csi_ord->type == PDF_STRING
+ && pdfi_type_of(csi_reg) == PDF_STRING && pdfi_type_of(csi_ord) == PDF_STRING
&& csi_reg->length + csi_ord->length + 1 < gp_file_name_sizeof - 1) {
pdf_name *reg_ord;
memcpy(fontfname, csi_reg->data, csi_reg->length);
@@ -209,10 +218,10 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
}
pdfi_countdown(csi);
- if (mname == NULL || mname->type != PDF_STRING)
+ if (mname == NULL || pdfi_type_of(mname) != PDF_STRING)
code = pdf_fontmap_lookup_cidfont(ctx, font_dict, NULL, (pdf_obj **)&mname, findex);
- if (code < 0 || mname->type != PDF_STRING) {
+ if (code < 0 || pdfi_type_of(mname) != PDF_STRING) {
const char *fsprefix = "CIDFSubst/";
int fsprefixlen = strlen(fsprefix);
const char *defcidfallack = "DroidSansFallback.ttf";
@@ -224,26 +233,26 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
code = gs_note_error(gs_error_invalidfont);
}
else {
- if (ctx->args.cidsubstpath.data == NULL) {
+ if (ctx->args.cidfsubstpath.data == NULL) {
memcpy(fontfname, fsprefix, fsprefixlen);
}
else {
- memcpy(fontfname, ctx->args.cidsubstpath.data, ctx->args.cidsubstpath.size);
- fsprefixlen = ctx->args.cidsubstpath.size;
+ memcpy(fontfname, ctx->args.cidfsubstpath.data, ctx->args.cidfsubstpath.size);
+ fsprefixlen = ctx->args.cidfsubstpath.size;
}
- if (ctx->args.cidsubstfont.data == NULL) {
+ if (ctx->args.cidfsubstfont.data == NULL) {
int len = 0;
- if (gp_getenv("CIDSUBSTFONT", (char *)0, &len) < 0 && len + fsprefixlen + 1 < gp_file_name_sizeof) {
- (void)gp_getenv("CIDSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
+ if (gp_getenv("CIDFSUBSTFONT", (char *)0, &len) < 0 && len + fsprefixlen + 1 < gp_file_name_sizeof) {
+ (void)gp_getenv("CIDFSUBSTFONT", (char *)(fontfname + fsprefixlen), &defcidfallacklen);
}
else {
memcpy(fontfname + fsprefixlen, defcidfallack, defcidfallacklen);
}
}
else {
- memcpy(fontfname, ctx->args.cidsubstfont.data, ctx->args.cidsubstfont.size);
- defcidfallacklen = ctx->args.cidsubstfont.size;
+ memcpy(fontfname, ctx->args.cidfsubstfont.data, ctx->args.cidfsubstfont.size);
+ defcidfallacklen = ctx->args.cidfsubstfont.size;
}
fontfname[fsprefixlen + defcidfallacklen] = '\0';
@@ -253,12 +262,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
}
else {
if (cidname) {
- pdfi_print_string(ctx, "Loading CIDFont ");
+ pdfi_print_cstring(ctx, "Loading CIDFont ");
pdfi_print_font_name(ctx, (pdf_name *)cidname);
- pdfi_print_string(ctx, " substitute from ");
+ pdfi_print_cstring(ctx, " substitute from ");
}
else {
- pdfi_print_string(ctx, "Loading nameless CIDFont from ");
+ pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
}
sfilename(s, &fname);
if (fname.size < gp_file_name_sizeof) {
@@ -268,8 +277,8 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
else {
strcpy(fontfname, "unnamed file");
}
- pdfi_print_string(ctx, fontfname);
- pdfi_print_string(ctx, "\n");
+ pdfi_print_cstring(ctx, fontfname);
+ pdfi_print_cstring(ctx, "\n");
sfseek(s, 0, SEEK_END);
@@ -287,19 +296,25 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
}
}
else {
- code = pdfi_open_resource_file(ctx, (const char *)mname->data, mname->length, &s);
+ if (mname->length + 1 > gp_file_name_sizeof) {
+ pdfi_countdown(mname);
+ return_error(gs_error_invalidfont);
+ }
+ memcpy(fontfname, mname->data, mname->length);
+ fontfname[mname->length] = '\0';
+ code = pdfi_open_resource_file(ctx, (const char *)fontfname, mname->length, &s);
pdfi_countdown(mname);
if (code < 0) {
code = gs_note_error(gs_error_invalidfont);
}
else {
if (cidname) {
- pdfi_print_string(ctx, "Loading CIDFont ");
+ pdfi_print_cstring(ctx, "Loading CIDFont ");
pdfi_print_font_name(ctx, (pdf_name *)cidname);
- pdfi_print_string(ctx, " (or substitute) from ");
+ pdfi_print_cstring(ctx, " (or substitute) from ");
}
else {
- pdfi_print_string(ctx, "Loading nameless CIDFont from ");
+ pdfi_print_cstring(ctx, "Loading nameless CIDFont from ");
}
sfilename(s, &fname);
if (fname.size < gp_file_name_sizeof) {
@@ -309,8 +324,8 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
else {
strcpy(fontfname, "unnamed file");
}
- pdfi_print_string(ctx, fontfname);
- pdfi_print_string(ctx, "\n");
+ pdfi_print_cstring(ctx, fontfname);
+ pdfi_print_cstring(ctx, "\n");
sfseek(s, 0, SEEK_END);
*buflen = sftell(s);
sfseek(s, 0, SEEK_SET);
@@ -329,9 +344,11 @@ pdfi_open_CIDFont_substitute_file(pdf_context * ctx, pdf_dict *font_dict, pdf_di
const char *fsprefix = "CIDFont/";
const int fsprefixlen = strlen(fsprefix);
- if (cidname == NULL || cidname->type != PDF_NAME
- || fsprefixlen + cidname->length >= gp_file_name_sizeof)
+ if (cidname == NULL || pdfi_type_of(cidname) != PDF_NAME
+ || fsprefixlen + cidname->length >= gp_file_name_sizeof) {
+ code = gs_note_error(gs_error_invalidfont);
goto exit;
+ }
memcpy(fontfname, fsprefix, fsprefixlen);
memcpy(fontfname + fsprefixlen, cidname->data, cidname->length);
@@ -428,64 +445,90 @@ static const char *pdfi_clean_font_name(const char *fontname)
return NULL;
}
-static const char *pdfi_font_substitute_by_flags(unsigned int flags)
+static int pdfi_font_substitute_by_flags(pdf_context *ctx, unsigned int flags, char **name, int *namelen)
{
bool fixed = ((flags & pdfi_font_flag_fixed) != 0);
bool serif = ((flags & pdfi_font_flag_serif) != 0);
bool italic = ((flags & pdfi_font_flag_italic) != 0);
bool bold = ((flags & pdfi_font_flag_forcebold) != 0);
+ int code = 0;
- if (fixed) {
+ if (ctx->args.defaultfont_is_name == true && ctx->args.defaultfont.size == 4
+ && !memcmp(ctx->args.defaultfont.data, "None", 4)) {
+ *name = NULL;
+ *namelen = 0;
+ code = gs_error_invalidfont;
+ }
+ else if (ctx->args.defaultfont.data != NULL && ctx->args.defaultfont.size > 0) {
+ *name = (char *)ctx->args.defaultfont.data;
+ *namelen = ctx->args.defaultfont.size;
+ }
+ else if (fixed) {
if (bold) {
if (italic) {
- return "Courier-BoldOblique";
+ *name = (char *)pdfi_base_font_names[3][0];
+ *namelen = strlen(*name);
}
else {
- return "Courier-Bold";
+ *name = (char *)pdfi_base_font_names[1][0];
+ *namelen = strlen(*name);
}
}
else {
if (italic) {
- return "Courier-Oblique";
+ *name = (char *)pdfi_base_font_names[2][0];
+ *namelen = strlen(*name);
}
else {
- return "Courier";
+ *name = (char *)pdfi_base_font_names[0][0];
+ *namelen = strlen(*name);
}
}
}
else if (serif) {
if (bold) {
if (italic) {
- return "Times-BoldItalic";
+ *name = (char *)pdfi_base_font_names[11][0];
+ *namelen = strlen(*name);
}
else {
- return "Times-Bold";
+ *name = (char *)pdfi_base_font_names[9][0];
+ *namelen = strlen(*name);
}
}
else {
if (italic) {
- return "Times-Italic";
+ *name = (char *)pdfi_base_font_names[10][0];
+ *namelen = strlen(*name);
}
else {
- return "Times-Roman";
+ *name = (char *)pdfi_base_font_names[8][0];
+ *namelen = strlen(*name);
}
}
} else {
if (bold) {
if (italic) {
- return "Helvetica-BoldOblique";
+ *name = (char *)pdfi_base_font_names[7][0];
+ *namelen = strlen(*name);
}
else {
- return "Helvetica-Bold";
+ *name = (char *)pdfi_base_font_names[5][0];
+ *namelen = strlen(*name);
}
}
else {
if (italic) {
- return "Helvetica-Oblique";
+ *name = (char *)pdfi_base_font_names[6][0];
+ *namelen = strlen(*name);
+ }
+ else {
+ *name = (char *)pdfi_base_font_names[4][0];
+ *namelen = strlen(*name);
}
}
}
- return "Helvetica"; /* Really shouldn't ever happen */
+ return code;
}
enum {
@@ -524,27 +567,112 @@ static int pdfi_fonttype_picker(byte *buf, int64_t buflen)
#undef MAKEMAGIC
}
-static int
-pdfi_open_font_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *fontdesc, bool fallback, byte **buf, int64_t *buflen, int *findex)
+static int pdfi_copy_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
+{
+ int code;
+ if (pdfi_type_of(spdffont) != PDF_FONT)
+ return_error(gs_error_typecheck);
+
+ switch(spdffont->pdfi_font_type) {
+ case e_pdf_font_type1:
+ code = pdfi_copy_type1_font(ctx, spdffont, font_dict, tpdffont);
+ break;
+ case e_pdf_font_cff:
+ code = pdfi_copy_cff_font(ctx, spdffont, font_dict, tpdffont);
+ break;
+ case e_pdf_font_truetype:
+ code = pdfi_copy_truetype_font(ctx, spdffont, font_dict, tpdffont);
+ break;
+ default:
+ return_error(gs_error_invalidfont);
+ }
+ return code;
+}
+
+enum {
+ font_embedded = 0,
+ font_from_file = 1,
+ font_substitute = 2
+};
+
+static int pdfi_load_font_buffer(pdf_context *ctx, byte *fbuf, int fbuflen, int fftype, pdf_name *Subtype, int findex, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, pdf_font **ppdffont, bool cidfont)
+{
+ int code = gs_error_invalidfont;
+ if (fbuf != NULL) {
+ /* First, see if we can glean the type from the magic number */
+ int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
+ if (sftype == no_type_font) {
+ if (fftype != no_type_font)
+ sftype = fftype;
+ else {
+ /* If we don't have a Subtype, can't work it out, try Type 1 */
+ if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
+ sftype = type1_font;
+ else if (pdfi_name_is(Subtype, "Type1C"))
+ sftype = cff_font;
+ else if (pdfi_name_is(Subtype, "TrueType"))
+ sftype = tt_font;
+ }
+ }
+ /* fbuf ownership passes to the font loader */
+ switch (sftype) {
+ case type1_font:
+ code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, ppdffont);
+ fbuf = NULL;
+ break;
+ case cff_font:
+ code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, ppdffont);
+ fbuf = NULL;
+ break;
+ case tt_font:
+ {
+ if (cidfont)
+ code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
+ else
+ code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, ppdffont);
+ fbuf = NULL;
+ }
+ break;
+ default:
+ gs_free_object(ctx->memory, fbuf, "pdfi_load_font_buffer(fbuf)");
+ code = gs_note_error(gs_error_invalidfont);
+ }
+ }
+ return code;
+}
+
+static int pdfi_load_font_file(pdf_context *ctx, int fftype, pdf_name *Subtype, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, pdf_dict *fontdesc, bool substitute, pdf_font **ppdffont)
{
int code;
char fontfname[gp_file_name_sizeof];
- pdf_obj *basefont = NULL, *mapname;
+ pdf_obj *basefont = NULL, *mapname = NULL;
pdf_obj *fontname = NULL;
stream *s;
const char *fn;
+ int findex = 0;
+ byte *buf;
+ int buflen;
+ pdf_font *pdffont = NULL;
+ pdf_font *substpdffont = NULL;
+ bool f_retry = true;
code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
- if (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)
- fallback = true;
+ if (substitute == false && (code < 0 || basefont == NULL || ((pdf_name *)basefont)->length == 0)) {
+ pdfi_countdown(basefont);
+ return_error(gs_error_invalidfont);
+ }
- if (fallback == true) {
- const char *fbname;
+ if (substitute == true) {
+ char *fbname;
+ int fbnamelen;
int64_t flags = 0;
if (fontdesc != NULL) {
(void)pdfi_dict_get_int(ctx, fontdesc, "Flags", &flags);
}
- fbname = pdfi_font_substitute_by_flags((int)flags);
+ code = pdfi_font_substitute_by_flags(ctx, (int)flags, &fbname, &fbnamelen);
+ if (code < 0)
+ return code;
+
code = pdfi_name_alloc(ctx, (byte *)fbname, strlen(fbname), (pdf_obj **) &fontname);
if (code < 0)
return code;
@@ -558,87 +686,166 @@ pdfi_open_font_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *
if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
fontfname[((pdf_name *)fontname)->length] = '\0';
- fn = pdfi_clean_font_name(fontfname);
- if (fn != NULL) {
- pdfi_countdown(fontname);
+ pdfi_countdown(fontname);
- code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
- if (code < 0)
- return code;
- pdfi_countup(fontname);
- }
- }
- code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, findex);
- if (code < 0) {
- mapname = fontname;
- pdfi_countup(mapname);
- code = 0;
+ code = pdfi_name_alloc(ctx, (byte *)fontfname, strlen(fontfname), (pdf_obj **) &fontname);
+ if (code < 0)
+ return code;
+ pdfi_countup(fontname);
}
- if (mapname->type == PDF_NAME || mapname->type == PDF_STRING) {
- pdf_name *mname = (pdf_name *) mapname;
- if (mname->length + 1 < gp_file_name_sizeof) {
- memcpy(fontfname, mname->data, mname->length);
- fontfname[mname->length] = '\0';
+
+ do {
+ code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, &findex);
+ if (code < 0) {
+ if (((pdf_name *)fontname)->length < gp_file_name_sizeof) {
+ memcpy(fontfname, ((pdf_name *)fontname)->data, ((pdf_name *)fontname)->length);
+ fontfname[((pdf_name *)fontname)->length] = '\0';
+ fn = pdfi_clean_font_name(fontfname);
+ if (fn != NULL) {
+ pdfi_countdown(fontname);
+
+ code = pdfi_name_alloc(ctx, (byte *)fn, strlen(fn), (pdf_obj **) &fontname);
+ if (code < 0)
+ return code;
+ pdfi_countup(fontname);
+ }
+ }
+ code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, &findex);
+ if (code < 0) {
+ mapname = fontname;
+ pdfi_countup(mapname);
+ code = 0;
+ }
+ }
+ if (pdfi_type_of(mapname) == PDF_NAME || pdfi_type_of(mapname) == PDF_STRING) {
+ pdf_name *mname = (pdf_name *) mapname;
+ if (mname->length + 1 < gp_file_name_sizeof) {
+ memcpy(fontfname, mname->data, mname->length);
+ fontfname[mname->length] = '\0';
+ }
+ else {
+ pdfi_countdown(mapname);
+ pdfi_countdown(fontname);
+ return_error(gs_error_invalidfileaccess);
+ }
}
else {
pdfi_countdown(mapname);
pdfi_countdown(fontname);
return_error(gs_error_invalidfileaccess);
}
- }
- else {
- pdfi_countdown(mapname);
- pdfi_countdown(fontname);
- return_error(gs_error_invalidfileaccess);
- }
- code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
+ if (ctx->pdf_substitute_fonts != NULL) {
+ code = pdfi_dict_knownget_type(ctx, ctx->pdf_substitute_fonts, fontfname, PDF_FONT, (pdf_obj **)&pdffont);
+ if (code == 1 && pdffont->filename == NULL) {
+ pdfi_countdown(pdffont);
+ pdffont = NULL;
+ code = 0;
+ }
+ }
+ else
+ code = 0;
+
+ if (code != 1) {
+ code = pdfi_open_font_file(ctx, fontfname, strlen(fontfname), &s);
+ if (code < 0 && f_retry && pdfi_type_of(mapname) == PDF_NAME) {
+ pdfi_countdown(fontname);
+ fontname = mapname;
+ mapname = NULL;
+ f_retry = false;
+ continue;
+ }
+ if (code >= 0) {
+ gs_const_string fname;
+
+ sfilename(s, &fname);
+ if (fname.size < gp_file_name_sizeof) {
+ memcpy(fontfname, fname.data, fname.size);
+ fontfname[fname.size] = '\0';
+ }
+ else {
+ strcpy(fontfname, "unnamed file");
+ }
+ sfseek(s, 0, SEEK_END);
+ buflen = sftell(s);
+ sfseek(s, 0, SEEK_SET);
+ buf = gs_alloc_bytes(ctx->memory, buflen, "pdfi_open_t1_font_file(buf)");
+ if (buf != NULL) {
+ sfread(buf, 1, buflen, s);
+ }
+ else {
+ code = gs_note_error(gs_error_VMerror);
+ }
+ sfclose(s);
+ /* On success, the buffer owership moves to the font object */
+ code = pdfi_load_font_buffer(ctx, buf, buflen, no_type_font, NULL, findex, stream_dict, page_dict, NULL, &pdffont, false);
+ if (code < 0) {
+ gs_free_object(ctx->memory, buf, "pdfi_load_font_file");
+ }
+ else {
+ pdffont->filename = NULL;
+ code = pdfi_object_alloc(ctx, PDF_STRING, strlen(fontfname) , (pdf_obj **)&pdffont->filename);
+ if (code >= 0) {
+ pdfi_countup(pdffont->filename);
+ memcpy(pdffont->filename->data, fontfname, strlen(fontfname));
+ pdffont->filename->length = strlen(fontfname);
+ }
+
+ if (ctx->pdf_substitute_fonts == NULL) {
+ code = pdfi_dict_alloc(ctx, 16, &ctx->pdf_substitute_fonts);
+ if (code >= 0)
+ pdfi_countup(ctx->pdf_substitute_fonts);
+ }
+ if (ctx->pdf_substitute_fonts != NULL) {
+ if (pdfi_type_of(mapname) == PDF_STRING) {
+ pdf_name *n = NULL;
+ pdf_string *mn = (pdf_string *)mapname;
+
+ code = pdfi_name_alloc(ctx, mn->data, mn->length, (pdf_obj **)&n);
+ if (code >= 0) {
+ pdfi_countdown(mapname);
+ mapname = (pdf_obj *)n;
+ pdfi_countup(mapname);
+ code = 0;
+ }
+ }
+ else
+ code = 0;
+
+ if (code == 0)
+ (void)pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
+ code = 0;
+ }
+ }
+ }
+ }
+ break;
+ } while (1);
+
if (code >= 0) {
- gs_const_string fname;
if (basefont) {
- pdfi_print_string(ctx, "Loading font ");
+ pdfi_print_cstring(ctx, "Loading font ");
pdfi_print_font_name(ctx, (pdf_name *)basefont);
- pdfi_print_string(ctx, " (or substitute) from ");
- }
- else {
- pdfi_print_string(ctx, "Loading nameless font from ");
- }
- sfilename(s, &fname);
- if (fname.size < gp_file_name_sizeof) {
- memcpy(fontfname, fname.data, fname.size);
- fontfname[fname.size] = '\0';
- }
- else {
- strcpy(fontfname, "unnamed file");
- }
- pdfi_print_string(ctx, fontfname);
- pdfi_print_string(ctx, "\n");
-
- sfseek(s, 0, SEEK_END);
- *buflen = sftell(s);
- sfseek(s, 0, SEEK_SET);
- *buf = gs_alloc_bytes(ctx->memory, *buflen, "pdfi_open_t1_font_file(buf)");
- if (*buf != NULL) {
- sfread(*buf, 1, *buflen, s);
+ pdfi_print_cstring(ctx, " (or substitute) from ");
}
else {
- code = gs_note_error(gs_error_VMerror);
+ pdfi_print_cstring(ctx, "Loading nameless font from ");
}
- sfclose(s);
+ pdfi_print_font_string(ctx, pdffont->filename);
+ pdfi_print_cstring(ctx, "\n");
+
+ code = pdfi_copy_font(ctx, pdffont, font_dict, &substpdffont);
+ pdfi_countdown(pdffont);
}
+ *ppdffont = substpdffont;
+
pdfi_countdown(basefont);
pdfi_countdown(mapname);
pdfi_countdown(fontname);
return code;
}
-enum {
- font_embedded = 0,
- font_from_file = 1,
- font_substitute = 2
-};
-
int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *font_dict, gs_font **ppfont, bool cidfont)
{
int code;
@@ -655,13 +862,19 @@ int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
int findex = -1;
code = pdfi_dict_get_type(ctx, font_dict, "Type", PDF_NAME, (pdf_obj **)&Type);
- if (code < 0)
- goto exit;
- if (!pdfi_name_is(Type, "Font")){
- code = gs_note_error(gs_error_typecheck);
- goto exit;
+ if (code < 0) {
+ pdfi_set_error(ctx, 0, NULL, E_PDF_MISSINGTYPE, "pdfi_load_font", NULL);
+ }
+ else {
+ if (!pdfi_name_is(Type, "Font")){
+ code = gs_note_error(gs_error_typecheck);
+ goto exit;
+ }
}
code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
+ if (code < 0) {
+ pdfi_set_error(ctx, 0, NULL, E_PDF_NO_SUBTYPE, "pdfi_load_font", NULL);
+ }
/* Beyond Type 0 and Type 3, there is no point trusting the Subtype key */
if (code >= 0 && pdfi_name_is(Subtype, "Type0")) {
@@ -682,7 +895,7 @@ int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
even if we don't
*/
code = pdfi_dict_get_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj**)&fontdesc);
- if (fontdesc != NULL && fontdesc->type == PDF_DICT) {
+ if (fontdesc != NULL && pdfi_type_of(fontdesc) == PDF_DICT) {
code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, (pdf_obj**)&fontfile);
if (code >= 0)
fftype = type1_font;
@@ -692,7 +905,7 @@ int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
}
if (code < 0) {
code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, (pdf_obj**)&fontfile);
- if (fontfile != NULL) {
+ if (code >= 0 && fontfile != NULL) {
code = pdfi_dict_get_type(ctx, fontfile->stream_dict, "Subtype", PDF_NAME, (pdf_obj **)&ffsubtype);
if (code >= 0) {
if (pdfi_name_is(ffsubtype, "Type1"))
@@ -724,59 +937,27 @@ int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
while (1) {
if (fbuf != NULL) {
- /* First, see if we can glean the type from the magic number */
- int sftype = pdfi_fonttype_picker(fbuf, fbuflen);
- if (sftype == no_type_font) {
- if (fftype != no_type_font)
- sftype = fftype;
- else {
- /* If we don't have a Subtype, can't work it out, try Type 1 */
- if (Subtype == NULL || pdfi_name_is(Subtype, "Type1") || pdfi_name_is(Subtype, "MMType1"))
- sftype = type1_font;
- else if (pdfi_name_is(Subtype, "Type1C"))
- sftype = cff_font;
- else if (pdfi_name_is(Subtype, "TrueType"))
- sftype = tt_font;
- }
- }
- /* fbuf ownership passes to the font loader */
- switch (sftype) {
- case type1_font:
- code = pdfi_read_type1_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, &ppdffont);
- fbuf = NULL;
- break;
- case cff_font:
- code = pdfi_read_cff_font(ctx, (pdf_dict *)font_dict, stream_dict, page_dict, fbuf, fbuflen, cidfont, &ppdffont);
- fbuf = NULL;
- break;
- case tt_font:
- {
- if (cidfont)
- code = pdfi_read_cidtype2_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, &ppdffont);
- else
- code = pdfi_read_truetype_font(ctx, font_dict, stream_dict, page_dict, fbuf, fbuflen, findex, &ppdffont);
- fbuf = NULL;
- }
- break;
- default:
- code = gs_note_error(gs_error_invalidfont);
- }
+ /* fbuf overship passes to pdfi_load_font_buffer() */
+ code = pdfi_load_font_buffer(ctx, fbuf, fbuflen, fftype, Subtype, findex, stream_dict, page_dict, font_dict, &ppdffont, cidfont);
if (code < 0 && substitute == font_embedded) {
- char obj[129];
- pdfi_print_string(ctx, "**** Warning: cannot process embedded stream for font object ");
- gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
- pdfi_print_string(ctx, obj);
- pdfi_print_string(ctx, "**** Attempting to load a substitute font.\n");
+ if (ctx->args.pdfstoponerror == true) {
+ goto exit;
+ }
+ else {
+ char obj[129];
+ pdfi_print_cstring(ctx, "**** Warning: cannot process embedded stream for font object ");
+ gs_snprintf(obj, 128, "%d %d\n", (int)font_dict->object_num, (int)font_dict->generation_num);
+ pdfi_print_cstring(ctx, obj);
+ pdfi_print_cstring(ctx, "**** Attempting to load a substitute font.\n");
+ }
}
}
+ else {
+ code = gs_error_invalidfont;
+ }
if (code < 0 && code != gs_error_VMerror && substitute == font_embedded) {
- /* Font not embedded, or embedded font not usable - use a substitute */
- if (fbuf != NULL) {
- gs_free_object(ctx->memory, fbuf, "pdfi_load_font(fbuf)");
- }
-
substitute = font_from_file;
if (cidfont == true) {
@@ -790,14 +971,12 @@ int pdfi_load_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
goto exit;
}
else {
- code = pdfi_open_font_substitute_file(ctx, font_dict, fontdesc, false, &fbuf, &fbuflen, &findex);
+ code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, false, &ppdffont);
if (code < 0) {
- code = pdfi_open_font_substitute_file(ctx, font_dict, fontdesc, true, &fbuf, &fbuflen, &findex);
+ code = pdfi_load_font_file(ctx, no_type_font, Subtype, stream_dict, page_dict, font_dict, fontdesc, true, &ppdffont);
substitute |= font_substitute;
}
-
- if (code < 0)
- goto exit;
+ break;
}
continue;
}
@@ -834,17 +1013,18 @@ int pdfi_load_dict_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_
gs_font *pfont;
pdf_font *pdfif;
- if (font_dict->type == PDF_FONT) {
- pdfi_countup(font_dict);
- pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
- code = 0;
- }
- else {
- if (font_dict->type != PDF_DICT) {
+ switch (pdfi_type_of(font_dict)) {
+ case PDF_FONT:
+ pdfi_countup(font_dict);
+ pfont = (gs_font *)((pdf_font *)font_dict)->pfont;
+ code = 0;
+ break;
+ case PDF_DICT:
+ code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
+ break;
+ default:
code = gs_note_error(gs_error_typecheck);
goto exit;
- }
- code = pdfi_load_font(ctx, stream_dict, page_dict, font_dict, &pfont, false);
}
if (code < 0)
goto exit;
@@ -869,7 +1049,7 @@ static int pdfi_load_resource_font(pdf_context *ctx, pdf_dict *stream_dict, pdf_
int code;
pdf_dict *font_dict = NULL;
- if (fontname->type != PDF_NAME) {
+ if (pdfi_type_of(fontname) != PDF_NAME) {
/* Passing empty string here should fall back to a default font */
return pdfi_font_set_internal_string(ctx, "", point_size);
}
@@ -922,6 +1102,8 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
i = 0;
while(1) {
+ pdf_obj_type type;
+
if (i + 1>= W->size) break;
code = pdfi_array_get_type(pdffont->ctx, W, i, PDF_INT, (pdf_obj **)&c);
if (code < 0) goto cleanup;
@@ -929,7 +1111,9 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
code = pdfi_array_get(pdffont->ctx, W, i + 1, &o);
if (code < 0) goto cleanup;
- if (o->type == PDF_INT) {
+ type = pdfi_type_of(o);
+ if (type == PDF_INT) {
+ double d;
c2 = (pdf_num *)o;
o = NULL;
if (i + 2 >= W->size){
@@ -939,18 +1123,10 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
break;
}
- code = pdfi_array_get(pdffont->ctx, W, i + 2, (pdf_obj **)&o);
+ code = pdfi_array_get_number(pdffont->ctx, W, i + 2, &d);
if (code < 0) goto cleanup;
- if (o->type != PDF_INT && o->type != PDF_REAL) {
- code = gs_note_error(gs_error_typecheck);
- goto cleanup;
- }
if (cid >= c->value.i && cid <= c2->value.i) {
- if (o->type == PDF_INT)
- widths[GLYPH_W0_WIDTH_INDEX] = (double)((pdf_num *)o)->value.i;
- else
- widths[GLYPH_W0_WIDTH_INDEX] = ((pdf_num *)o)->value.d;
-
+ widths[GLYPH_W0_WIDTH_INDEX] = d;
widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
/* We countdown and NULL c, c2 and o after exit from the loop
* in order to avoid doing so in the break statements
@@ -961,27 +1137,17 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
i += 3;
pdfi_countdown(c2);
pdfi_countdown(c);
- pdfi_countdown(o);
c = c2 = NULL;
- o = NULL;
continue;
}
}
- else if (o->type == PDF_ARRAY) {
+ else if (type == PDF_ARRAY) {
pdf_array *a = (pdf_array *)o;
o = NULL;
if (cid >= c->value.i && cid < c->value.i + a->size) {
- code = pdfi_array_get(pdffont->ctx, a, cid - c->value.i, (pdf_obj **)&o);
+ code = pdfi_array_get_number(pdffont->ctx, a, cid - c->value.i, &widths[GLYPH_W0_WIDTH_INDEX]);
if (code >= 0) {
pdfi_countdown(a);
- if (o->type == PDF_INT)
- widths[GLYPH_W0_WIDTH_INDEX] = (double)((pdf_num *)o)->value.i;
- else if (o->type == PDF_REAL)
- widths[GLYPH_W0_WIDTH_INDEX] = ((pdf_num *)o)->value.d;
- else {
- code = gs_note_error(gs_error_typecheck);
- goto cleanup;
- }
widths[GLYPH_W0_HEIGHT_INDEX] = 0.0;
/* We countdown and NULL c, c2 and o on exit from the loop
* in order to avoid doing so in the break statements
@@ -991,8 +1157,6 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
}
pdfi_countdown(a);
pdfi_countdown(c);
- pdfi_countdown(o);
- o = NULL;
c = NULL;
i += 2;
continue;
@@ -1016,78 +1180,42 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
widths[GLYPH_W1_V_X_INDEX] = (widths[GLYPH_W0_WIDTH_INDEX] / 2.0);
widths[GLYPH_W1_V_Y_INDEX] = 880.0;
- if (DW2 != NULL && DW2->type == PDF_ARRAY
+ if (DW2 != NULL && pdfi_type_of(DW2) == PDF_ARRAY
&& DW2->size >= 2) {
- pdf_num *w2_0 = NULL, *w2_1 = NULL;
-
- code = pdfi_array_get(pdffont->ctx, (pdf_array *)DW2, 0, (pdf_obj **)&w2_0);
- if (code >= 0 && (w2_0->type == PDF_INT || w2_0->type == PDF_REAL)) {
- code = pdfi_array_get(pdffont->ctx, (pdf_array *)DW2, 1, (pdf_obj **)&w2_1);
- if (code >= 0 && (w2_1->type == PDF_INT || w2_1->type == PDF_REAL)) {
- widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
- if (w2_0->type == PDF_INT)
- widths[GLYPH_W1_V_Y_INDEX] = (double)w2_0->value.i;
- else
- widths[GLYPH_W1_V_Y_INDEX] = (double)w2_0->value.d;
-
- widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
- if (w2_1->type == PDF_INT)
- widths[GLYPH_W1_HEIGHT_INDEX] = (double)w2_1->value.i;
- else
- widths[GLYPH_W1_HEIGHT_INDEX] = (double)w2_1->value.d;
- }
+ code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 0, &widths[GLYPH_W1_V_Y_INDEX]);
+ if (code >= 0)
+ code = pdfi_array_get_number(pdffont->ctx, (pdf_array *)DW2, 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
+ if (code >= 0) {
+ widths[GLYPH_W1_V_X_INDEX] = widths[GLYPH_W0_WIDTH_INDEX] / 2.0;
+ widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
}
- pdfi_countdown(w2_0);
- pdfi_countdown(w2_1);
}
- if (W2 != NULL && W2->type == PDF_ARRAY) {
+ if (W2 != NULL && pdfi_type_of(W2) == PDF_ARRAY) {
i = 0;
while(1) {
+ pdf_obj_type type;
if (i + 1 >= W2->size) break;
(void)pdfi_array_get(pdffont->ctx, W2, i, (pdf_obj **)&c);
- if (c->type != PDF_INT) {
+ if (pdfi_type_of(c) != PDF_INT) {
code = gs_note_error(gs_error_typecheck);
goto cleanup;
}
code = pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&o);
if (code < 0) goto cleanup;
- if (o->type == PDF_INT) {
+ type = pdfi_type_of(o);
+ if (type == PDF_INT) {
if (cid >= c->value.i && cid <= ((pdf_num *)o)->value.i) {
- pdf_num *w1y, *v1x, *v1y;
if (i + 4 >= W2->size) {
/* We countdown and NULL c, and o on exit from the function
* so we don't need to do so in the break statements
*/
break;
}
- (void)pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&w1y);
- (void)pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&v1x);
- (void)pdfi_array_get(pdffont->ctx, W2, i + 1, (pdf_obj **)&v1y);
- if (w1y != NULL && (w1y->type == PDF_INT || w1y->type == PDF_REAL)
- && v1x != NULL && (v1x->type == PDF_INT || v1x->type == PDF_REAL)
- && v1y != NULL && (v1y->type == PDF_INT || v1y->type == PDF_REAL)) {
- widths[GLYPH_W1_WIDTH_INDEX] = 0;
- if (w1y->type == PDF_INT)
- widths[GLYPH_W1_HEIGHT_INDEX] = (double)w1y->value.i;
- else
- widths[GLYPH_W1_HEIGHT_INDEX] = w1y->value.d;
-
- if (v1x->type == PDF_INT)
- widths[GLYPH_W1_V_X_INDEX] = (double)v1x->value.i;
- else
- widths[GLYPH_W1_V_X_INDEX] = v1x->value.d;
-
- if (v1y->type == PDF_INT)
- widths[GLYPH_W1_V_Y_INDEX] = (double)v1y->value.i;
- else
- widths[GLYPH_W1_V_Y_INDEX] = v1y->value.d;
- }
- else
- code = gs_note_error(gs_error_typecheck);
-
- pdfi_countdown(w1y);
- pdfi_countdown(v1x);
- pdfi_countdown(v1y);
+ code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_HEIGHT_INDEX]);
+ if (code < 0) goto cleanup;
+ code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_V_X_INDEX]);
+ if (code < 0) goto cleanup;
+ code = pdfi_array_get_number(pdffont->ctx, W2, i + 1, &widths[GLYPH_W1_V_Y_INDEX]);
if (code < 0) goto cleanup;
/* We countdown and NULL c, and o on exit from the function
* so we don't need to do so in the break statements
@@ -1096,43 +1224,26 @@ int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths,
}
i += 5;
}
- else if (o->type == PDF_ARRAY) {
+ else if (type == PDF_ARRAY) {
pdf_array *a = (pdf_array *)o;
int l = a->size - (a->size % 3);
o = NULL;
if (cid >= c->value.i && cid < c->value.i + (l / 3)) {
- pdf_num *w1y = NULL, *v1x = NULL, *v1y = NULL;
int index = (cid - c->value.i) * 3;
- (void)pdfi_array_get(pdffont->ctx, a, index, (pdf_obj **)&w1y);
- (void)pdfi_array_get(pdffont->ctx, a, index + 1, (pdf_obj **)&v1x);
- (void)pdfi_array_get(pdffont->ctx, a, index + 2, (pdf_obj **)&v1y);
- pdfi_countdown(a);
-
- if (w1y != NULL && (w1y->type == PDF_INT || w1y->type == PDF_REAL)
- && v1x != NULL && (v1x->type == PDF_INT || v1x->type == PDF_REAL)
- && v1y != NULL && (v1y->type == PDF_INT || v1y->type == PDF_REAL)) {
- widths[GLYPH_W1_WIDTH_INDEX] = 0.0;
- if (w1y->type == PDF_INT)
- widths[GLYPH_W1_HEIGHT_INDEX] = (double)w1y->value.i;
- else
- widths[GLYPH_W1_HEIGHT_INDEX] = w1y->value.d;
-
- if (v1x->type == PDF_INT)
- widths[GLYPH_W1_V_X_INDEX] = (double)v1x->value.i;
- else
- widths[GLYPH_W1_V_X_INDEX] = v1x->value.d;
-
- if (v1y->type == PDF_INT)
- widths[GLYPH_W1_V_Y_INDEX] = (double)v1y->value.i;
- else
- widths[GLYPH_W1_V_Y_INDEX] = v1y->value.d;
+ code = pdfi_array_get_number(pdffont->ctx, a, index, &widths[GLYPH_W1_HEIGHT_INDEX]);
+ if (code < 0) {
+ pdfi_countdown(a);
+ goto cleanup;
}
- else
- code = gs_note_error(gs_error_typecheck);
- pdfi_countdown(w1y);
- pdfi_countdown(v1x);
- pdfi_countdown(v1y);
+ code = pdfi_array_get_number(pdffont->ctx, a, index + 1, &widths[GLYPH_W1_V_X_INDEX]);
+ if (code < 0) {
+ pdfi_countdown(a);
+ goto cleanup;
+ }
+ code = pdfi_array_get_number(pdffont->ctx, a, index + 2, &widths[GLYPH_W1_V_Y_INDEX]);
+ pdfi_countdown(a);
if (code < 0) goto cleanup;
+
/* We countdown and NULL c, and o on exit from the function
* so we don't need to do so in the break statements
*/
@@ -1176,11 +1287,11 @@ int pdfi_d0(pdf_context *ctx)
goto d0_error;
}
- if (ctx->stack_top[-1]->type != PDF_INT && ctx->stack_top[-1]->type != PDF_REAL) {
+ if (pdfi_type_of(ctx->stack_top[-1]) != PDF_INT && pdfi_type_of(ctx->stack_top[-1]) != PDF_REAL) {
code = gs_note_error(gs_error_typecheck);
goto d0_error;
}
- if (ctx->stack_top[-2]->type != PDF_INT && ctx->stack_top[-2]->type != PDF_REAL) {
+ if (pdfi_type_of(ctx->stack_top[-2]) != PDF_INT && pdfi_type_of(ctx->stack_top[-2]) != PDF_REAL) {
code = gs_note_error(gs_error_typecheck);
goto d0_error;
}
@@ -1189,11 +1300,11 @@ int pdfi_d0(pdf_context *ctx)
goto d0_error;
}
- if (ctx->stack_top[-1]->type == PDF_INT)
+ if (pdfi_type_of(ctx->stack_top[-1]) == PDF_INT)
width[0] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
else
width[0] = ((pdf_num *)ctx->stack_top[-1])->value.d;
- if (ctx->stack_top[-2]->type == PDF_INT)
+ if (pdfi_type_of(ctx->stack_top[-2]) == PDF_INT)
width[1] = (double)((pdf_num *)ctx->stack_top[-1])->value.i;
else
width[1] = ((pdf_num *)ctx->stack_top[-1])->value.d;
@@ -1245,7 +1356,7 @@ d0_error:
int pdfi_d1(pdf_context *ctx)
{
- int code = 0, i, gsave_level;
+ int code = 0, gsave_level;
double wbox[6];
if (ctx->text.inside_CharProc == false)
@@ -1253,21 +1364,9 @@ int pdfi_d1(pdf_context *ctx)
ctx->text.CharProc_d_type = pdf_type3_d1;
- if (pdfi_count_stack(ctx) < 6) {
- code = gs_note_error(gs_error_stackunderflow);
+ code = pdfi_destack_reals(ctx, wbox, 6);
+ if (code < 0)
goto d1_error;
- }
-
- for (i=-6;i < 0;i++) {
- if (ctx->stack_top[i]->type != PDF_INT && ctx->stack_top[i]->type != PDF_REAL) {
- code = gs_note_error(gs_error_typecheck);
- goto d1_error;
- }
- if (ctx->stack_top[i]->type == PDF_INT)
- wbox[i + 6] = (double)((pdf_num *)ctx->stack_top[i])->value.i;
- else
- wbox[i + 6] = ((pdf_num *)ctx->stack_top[i])->value.d;
- }
/*
* We don't intend to retain this, instead we will use (effectively) xyshow to apply
@@ -1291,7 +1390,6 @@ int pdfi_d1(pdf_context *ctx)
if (code < 0)
goto d1_error;
- pdfi_pop(ctx, 6);
return 0;
d1_error:
@@ -1319,16 +1417,9 @@ int pdfi_Tf(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
pdfi_pop(ctx, 2);
/* Get the point_size */
- if (point_arg->type == PDF_INT)
- point_size = (double)((pdf_num *)point_arg)->value.i;
- else {
- if (point_arg->type == PDF_REAL)
- point_size = ((pdf_num *)point_arg)->value.d;
- else {
- code = gs_note_error(gs_error_typecheck);
- goto exit0;
- }
- }
+ code = pdfi_obj_to_real(ctx, point_arg, &point_size);
+ if (code < 0)
+ goto exit0;
code = pdfi_load_resource_font(ctx, stream_dict, page_dict, fontname, point_size);
@@ -1378,7 +1469,7 @@ int pdfi_free_font(pdf_obj *font)
static inline int pdfi_encoding_name_to_index(pdf_name *name)
{
int ind = gs_error_undefined;
- if (name->type == PDF_NAME) {
+ if (pdfi_type_of(name) == PDF_NAME) {
if (pdfi_name_is(name, "StandardEncoding")) {
ind = ENCODING_INDEX_STANDARD;
} else {
@@ -1452,21 +1543,23 @@ int pdfi_create_Encoding(pdf_context *ctx, pdf_obj *pdf_Encoding, pdf_obj *font_
return code;
pdfi_countup(*Encoding);
- if (pdf_Encoding->type == PDF_NAME) {
- code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding);
- if (code < 0) {
- pdfi_countdown(*Encoding);
- *Encoding = NULL;
- return code;
- }
- } else {
- if (pdf_Encoding->type == PDF_DICT) {
+ switch (pdfi_type_of(pdf_Encoding)) {
+ case PDF_NAME:
+ code = pdfi_build_Encoding(ctx, (pdf_name *)pdf_Encoding, (pdf_array *)*Encoding);
+ if (code < 0) {
+ pdfi_countdown(*Encoding);
+ *Encoding = NULL;
+ return code;
+ }
+ break;
+ case PDF_DICT:
+ {
pdf_name *n = NULL;
pdf_array *a = NULL;
pdf_obj *o = NULL;
int offset = 0;
- if (font_Encoding != NULL && font_Encoding->type == PDF_ARRAY) {
+ if (font_Encoding != NULL && pdfi_type_of(font_Encoding) == PDF_ARRAY) {
pdf_array *fenc = (pdf_array *)font_Encoding;
for (i = 0; i < pdfi_array_size(fenc) && code >= 0; i++) {
code = pdfi_array_get(ctx, fenc, (uint64_t)i, &o);
@@ -1523,25 +1616,25 @@ int pdfi_create_Encoding(pdf_context *ctx, pdf_obj *pdf_Encoding, pdf_obj *font_
}
for (i=0;i < pdfi_array_size(a);i++) {
+ pdf_obj_type type;
code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
if (code < 0)
break;
- if (o->type == PDF_NAME) {
+ type = pdfi_type_of(o);
+ if (type == PDF_NAME) {
if (offset < pdfi_array_size((pdf_array *)*Encoding))
code = pdfi_array_put(ctx, (pdf_array *)*Encoding, (uint64_t)offset, o);
pdfi_countdown(o);
offset++;
if (code < 0)
break;
+ } else if (type == PDF_INT) {
+ offset = ((pdf_num *)o)->value.i;
+ pdfi_countdown(o);
} else {
- if (o->type == PDF_INT) {
- offset = ((pdf_num *)o)->value.i;
- pdfi_countdown(o);
- } else {
- code = gs_note_error(gs_error_typecheck);
- pdfi_countdown(o);
- break;
- }
+ code = gs_note_error(gs_error_typecheck);
+ pdfi_countdown(o);
+ break;
}
}
pdfi_countdown(a);
@@ -1550,11 +1643,12 @@ int pdfi_create_Encoding(pdf_context *ctx, pdf_obj *pdf_Encoding, pdf_obj *font_
*Encoding = NULL;
return code;
}
- } else {
+ break;
+ }
+ default:
pdfi_countdown(*Encoding);
*Encoding = NULL;
return gs_note_error(gs_error_typecheck);
- }
}
return 0;
}
@@ -1575,6 +1669,10 @@ gs_glyph pdfi_encode_char(gs_font * pfont, gs_char chr, gs_glyph_space_t not_use
pdf_name *GlyphName = NULL;
code = pdfi_array_get(ctx, font->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName);
if (code >= 0) {
+ if (pdfi_type_of(GlyphName) != PDF_NAME)
+ /* Can't signal an error, just return the 'not found' case */
+ return g;
+
code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &nindex);
pdfi_countdown(GlyphName);
if (code >= 0)
@@ -1595,9 +1693,9 @@ int pdfi_tounicode_char_to_unicode(pdf_context *ctx, pdf_cmap *tounicode, gs_gly
if (tounicode != NULL) {
gs_cmap_lookups_enum_t lenum;
gs_cmap_lookups_enum_init((const gs_cmap_t *)tounicode->gscmap, 0, &lenum);
- while (l == 0 && (code = gs_cmap_enum_next_lookup(ctx->memory, &lenum)) == 0) {
+ while (l == 0 && gs_cmap_enum_next_lookup(ctx->memory, &lenum) == 0) {
gs_cmap_lookups_enum_t counter = lenum;
- while (l == 0 && (code = gs_cmap_enum_next_entry(&counter) == 0)) {
+ while (l == 0 && gs_cmap_enum_next_entry(&counter) == 0) {
if (counter.entry.value_type == CODE_VALUE_CID) {
unsigned int v = 0;
for (i = 0; i < counter.entry.key_size; i++) {
@@ -1704,6 +1802,62 @@ static int pdfi_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, g
return code;
}
+int pdfi_map_glyph_name_via_agl(pdf_dict *cstrings, pdf_name *gname, pdf_string **cstring)
+{
+ single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
+ int i, code, ucode = gs_error_undefined;
+ *cstring = NULL;
+
+ if (gname->length == 7 && strncmp((char *)gname->data, "uni", 3) == 0) {
+ char u[5] = {0};
+ memcpy(u, gname->data + 3, 4);
+ code = sscanf(u, "%x", &ucode);
+ if (code <= 0)
+ ucode = gs_error_undefined;
+ }
+
+ if (ucode == gs_error_undefined) {
+ for (i = 0; sgl[i].Glyph != 0x00; i++) {
+ if (sgl[i].Glyph[0] == gname->data[0]
+ && strlen(sgl[i].Glyph) == gname->length
+ && !strncmp((char *)sgl[i].Glyph, (char *)gname->data, gname->length)) {
+ ucode = (int)sgl[i].Unicode;
+ break;
+ }
+ }
+ }
+ if (ucode > 0) {
+ for (i = 0; sgl[i].Glyph != 0x00; i++) {
+ if (sgl[i].Unicode == (unsigned short)ucode) {
+ pdf_string *s;
+ code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, (char *)sgl[i].Glyph, (pdf_obj **)&s);
+ if (code >= 0) {
+ *cstring = s;
+ break;
+ }
+ }
+ }
+ if (*cstring == NULL) {
+ char u[16] = {0};
+ code = gs_snprintf(u, 16, "uni%04x", ucode);
+ if (code > 0) {
+ pdf_string *s;
+ code = pdfi_dict_get((pdf_context *)cstrings->ctx, cstrings, u, (pdf_obj **)&s);
+ if (code >= 0) {
+ *cstring = s;
+ }
+ }
+ }
+ }
+
+ if (*cstring == NULL)
+ code = gs_note_error(gs_error_undefined);
+ else
+ code = 0;
+
+ return code;
+}
+
int pdfi_init_font_directory(pdf_context *ctx)
{
ctx->font_dir = gs_font_dir_alloc2(ctx->memory, ctx->memory);
@@ -1763,6 +1917,95 @@ int pdfi_load_font_by_name_string(pdf_context *ctx, const byte *fontname, size_t
return code;
}
+
+int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double scale)
+{
+ int code = 0;
+ pdf_obj *obj = NULL;
+ int i;
+
+ font->Widths = NULL;
+
+ if (font->FontDescriptor != NULL) {
+ code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
+ if (code > 0) {
+ if (pdfi_type_of(obj) == PDF_INT) {
+ font->MissingWidth = ((pdf_num *) obj)->value.i * scale;
+ }
+ else if (pdfi_type_of(obj) == PDF_REAL) {
+ font->MissingWidth = ((pdf_num *) obj)->value.d * scale;
+ }
+ else {
+ font->MissingWidth = 0;
+ }
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+ else {
+ font->MissingWidth = 0;
+ }
+ }
+ else {
+ font->MissingWidth = 1000.0 * scale;
+ }
+
+ code = pdfi_dict_knownget_type(ctx, fontdict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
+ if (code > 0) {
+ if (pdfi_array_size((pdf_array *)obj) < font->LastChar - font->FirstChar + 1) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
+
+ font->Widths = (double *)gs_alloc_bytes(OBJ_MEMORY(font), sizeof(double) * (font->LastChar - font->FirstChar + 1), "pdfi_font_create_widths(Widths)");
+ if (font->Widths == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
+ memset(font->Widths, 0x00, sizeof(double) * (font->LastChar - font->FirstChar + 1));
+ for (i = 0; i < (font->LastChar - font->FirstChar + 1); i++) {
+ code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
+ if (code < 0)
+ goto error;
+ font->Widths[i] *= scale;
+ }
+ }
+error:
+ pdfi_countdown(obj);
+ if (code < 0) {
+ gs_free_object(OBJ_MEMORY(font), font->Widths, "pdfi_font_create_widths(Widths)");
+ font->Widths = NULL;
+ }
+ return code;
+}
+
+void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font)
+{
+ double f, l;
+ int code;
+
+ if (fontdict == NULL) {
+ f = (double)0;
+ l = (double)255;
+ }
+ else {
+ code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
+ if (code < 0 || f < 0 || f > 255)
+ f = (double)0;
+
+ code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &l);
+ if (code < 0 || l < 0 || l > 255)
+ l = (double)255;
+ }
+ if (f <= l) {
+ font->FirstChar = f;
+ font->LastChar = l;
+ }
+ else {
+ font->FirstChar = 0;
+ font->LastChar = 255;
+ }
+}
+
/* Patch or create a new XUID based on the existing UID/XUID, a simple hash
of the input file name and the font dictionary object number.
This allows improved glyph cache efficiency, also ensures pdfwrite understands
@@ -1776,10 +2019,10 @@ int pdfi_font_generate_pseudo_XUID(pdf_context *ctx, pdf_dict *fontdict, gs_font
int i;
uint32_t hash = 0;
long *xvalues;
- int xuidlen = 2;
+ int xuidlen = 3;
sfilename(ctx->main_stream->s, &fn);
- if (fn.size > 0 && fontdict->object_num != 0) {
+ if (fn.size > 0 && fontdict!= NULL && fontdict->object_num != 0) {
for (i = 0; i < fn.size; i++) {
hash = ((((hash & 0xf8000000) >> 27) ^ (hash << 5)) & 0x7ffffffff) ^ fn.data[i];
}
@@ -1795,14 +2038,17 @@ int pdfi_font_generate_pseudo_XUID(pdf_context *ctx, pdf_dict *fontdict, gs_font
}
xvalues[0] = 1000000; /* "Private" value */
xvalues[1] = hash;
+
+ xvalues[2] = ctx->device_state.HighLevelDevice ? pfont->id : 0;
+
if (uid_is_XUID(&pfont->UID)) {
for (i = 0; i < uid_XUID_size(&pfont->UID); i++) {
- xvalues[i + 2] = uid_XUID_values(&pfont->UID)[i];
+ xvalues[i + 3] = uid_XUID_values(&pfont->UID)[i];
}
uid_free(&pfont->UID, pfont->memory, "pdfi_font_generate_pseudo_XUID");
}
else if (uid_is_valid(&pfont->UID))
- xvalues[2] = pfont->UID.id;
+ xvalues[3] = pfont->UID.id;
uid_set_XUID(&pfont->UID, xvalues, xuidlen);
}
@@ -1817,7 +2063,7 @@ int pdfi_set_font_internal(pdf_context *ctx, pdf_obj *fontobj, double point_size
int code;
pdf_font *pdffont = (pdf_font *)fontobj;
- if (pdffont->type != PDF_FONT || pdffont->pfont == NULL)
+ if (pdfi_type_of(pdffont) != PDF_FONT || pdffont->pfont == NULL)
return_error(gs_error_invalidfont);
code = gs_setPDFfontsize(ctx->pgs, point_size);
@@ -1854,7 +2100,7 @@ int pdfi_font_set_internal_string(pdf_context *ctx, const char *fontname, double
int pdfi_font_set_internal_name(pdf_context *ctx, pdf_name *fontname, double point_size)
{
- if (fontname->type != PDF_NAME)
+ if (pdfi_type_of(fontname) != PDF_NAME)
return_error(gs_error_typecheck);
else
return pdfi_font_set_internal_inner(ctx, fontname->data, fontname->length, point_size);