summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdf/ghostpdf.c2
-rw-r--r--pdf/ghostpdf.h1
-rw-r--r--pdf/pdf_fapi.c66
-rw-r--r--pdf/pdf_font.c397
-rw-r--r--pdf/pdf_font.h2
-rw-r--r--pdf/pdf_font0.c3
-rw-r--r--pdf/pdf_font1.c305
-rw-r--r--pdf/pdf_font1.h4
-rw-r--r--pdf/pdf_font11.c62
-rw-r--r--pdf/pdf_font1C.c351
-rw-r--r--pdf/pdf_font1C.h5
-rw-r--r--pdf/pdf_font3.c63
-rw-r--r--pdf/pdf_fontTT.c301
-rw-r--r--pdf/pdf_fontTT.h3
-rw-r--r--pdf/pdf_font_types.h31
-rw-r--r--pdf/pdf_fontps.c36
-rw-r--r--pdf/pdf_obj.c57
-rw-r--r--pdf/pdf_obj.h18
-rw-r--r--pdf/pdf_types.h11
19 files changed, 1126 insertions, 592 deletions
diff --git a/pdf/ghostpdf.c b/pdf/ghostpdf.c
index 24bf7394b..2dd4c63cc 100644
--- a/pdf/ghostpdf.c
+++ b/pdf/ghostpdf.c
@@ -2095,6 +2095,8 @@ int pdfi_clear_context(pdf_context *ctx)
ctx->pdffontmap = NULL;
pdfi_countdown(ctx->pdfnativefontmap);
ctx->pdfnativefontmap = NULL;
+ pdfi_countdown(ctx->pdf_substitute_fonts);
+ ctx->pdf_substitute_fonts = NULL;
return 0;
}
diff --git a/pdf/ghostpdf.h b/pdf/ghostpdf.h
index 6e8906726..a2ca382f0 100644
--- a/pdf/ghostpdf.h
+++ b/pdf/ghostpdf.h
@@ -452,6 +452,7 @@ typedef struct pdf_context_s
search_paths_t search_paths;
pdf_dict *pdffontmap;
pdf_dict *pdfnativefontmap; /* Explicit mappings take precedence, hence we need separate dictionaries */
+ pdf_dict *pdf_substitute_fonts;
pdf_dict *pdfcidfmap;
/* These function pointers can be replaced by ones intended to replicate
diff --git a/pdf/pdf_fapi.c b/pdf/pdf_fapi.c
index 503064e13..7fb7c954c 100644
--- a/pdf/pdf_fapi.c
+++ b/pdf/pdf_fapi.c
@@ -254,7 +254,7 @@ pdfi_fapi_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, uns
{
if (pfont->FontType == ft_encrypted2) {
pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
- *ret = pdffont2->NumGlobalSubrs;
+ *ret = pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs);
}
else {
*ret = 0;
@@ -266,11 +266,11 @@ pdfi_fapi_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, uns
{
if (pfont->FontType == ft_encrypted) {
pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
- *ret = pdffont1->NumSubrs;
+ *ret = pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs);
}
else if (pfont->FontType == ft_encrypted2) {
pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
- *ret = pdffont2->NumSubrs;
+ *ret = pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs);
}
else {
*ret = 0;
@@ -449,8 +449,13 @@ pdfi_fapi_get_long(gs_fapi_font * ff, gs_fapi_font_feature var_id, int index, un
pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
int i;
*ret = 0;
- for (i = 0; i < pdffont1->NumSubrs; i++) {
- *ret += pdffont1->Subrs[i].size;
+ for (i = 0; i < (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs)); i++) {
+ pdf_string *subr_str = NULL;
+ code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, i, PDF_STRING, (pdf_obj **)&subr_str);
+ if (code >= 0) {
+ *ret += subr_str->length;
+ }
+ pdfi_countdown(subr_str);
}
}
}
@@ -675,7 +680,7 @@ pdfi_fapi_get_gsubr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
int code = 0;
if (pfont->FontType == ft_encrypted2) {
pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
- if (index > pdffont2->NumGlobalSubrs) {
+ if (index > (pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs))) {
code = gs_error_rangecheck;
}
else {
@@ -716,27 +721,35 @@ pdfi_fapi_get_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
if (pfont->FontType == ft_encrypted) {
pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
- if (index > pdffont1->NumSubrs) {
+ if (index > (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
code = gs_note_error(gs_error_rangecheck);
}
else {
int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
- if (pdffont1->Subrs[index].size > 0) {
- code = pdffont1->Subrs[index].size - leniv;
+ pdf_string *subr_str = NULL;
+
+ code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
+ if (code >= 0) {
+ code = subr_str->length - leniv;
if (buf && buf_length >= code) {
if (ff->need_decrypt && pfont->data.lenIV >= 0) {
- decode_bytes(buf, pdffont1->Subrs[index].data, code + leniv, pfont->data.lenIV);
+ decode_bytes(buf, subr_str->data, code + leniv, pfont->data.lenIV);
}
else {
- memcpy(buf, pdffont1->Subrs[index].data, code);
+ memcpy(buf, subr_str->data, code);
}
}
}
+ else {
+ /* Ignore invalid or missing subrs */
+ code = 0;
+ }
+ pdfi_countdown(subr_str);
}
}
else if (pfont->FontType == ft_encrypted2) {
pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
- if (index > pdffont2->NumSubrs) {
+ if (index > (pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs))) {
code = gs_error_rangecheck;
}
else {
@@ -782,14 +795,23 @@ pdfi_fapi_get_raw_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
if (pfont->FontType == ft_encrypted) {
pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
- if (index > pdffont1->NumSubrs) {
+ if (index > (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
code = gs_error_rangecheck;
}
else {
- code = pdffont1->Subrs[index].size;
- if (buf && buf_length >= code) {
- memcpy(buf, pdffont1->Subrs[index].data, code);
+ pdf_string *subr_str = NULL;
+ code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
+ if (code >= 0) {
+ code = subr_str->length;
+ if (buf && buf_length >= code) {
+ memcpy(buf, subr_str->data, code);
+ }
+ }
+ else {
+ /* Ignore missing or invalid subrs */
+ code = 0;
}
+ pdfi_countdown(subr_str);
}
}
return code;
@@ -825,8 +847,8 @@ pdfi_fapi_get_glyphname_or_cid(gs_text_enum_t *penum, gs_font_base * pbfont, gs_
if (pttfont->substitute == false) {
gid = ccode;
- if (pttfont->cidtogidmap.size > (ccode << 1) + 1) {
- gid = pttfont->cidtogidmap.data[ccode << 1] << 8 | pttfont->cidtogidmap.data[(ccode << 1) + 1];
+ if (pttfont->cidtogidmap != NULL && pttfont->cidtogidmap->length > (ccode << 1) + 1) {
+ gid = pttfont->cidtogidmap->data[ccode << 1] << 8 | pttfont->cidtogidmap->data[(ccode << 1) + 1];
}
cr->client_char_code = ccode;
cr->char_codes[0] = gid;
@@ -1287,8 +1309,8 @@ pdfi_fapi_retrieve_tt_font(gs_fapi_font * ff, void **buf, int *buf_size)
gs_font_type42 *pfonttt = (gs_font_type42 *) ff->client_font_data;
pdf_font_truetype *pdfttf = (pdf_font_truetype *)pfonttt->client_data;
- *buf = pdfttf->sfnt.data;
- *buf_size = pdfttf->sfnt.size;
+ *buf = pdfttf->sfnt->data;
+ *buf_size = pdfttf->sfnt->length;
return 0;
}
@@ -1472,8 +1494,8 @@ pdfi_fapi_passfont(pdf_font *font, int subfont, char *fapi_request,
fdatap = NULL;
}
else if (font->pdfi_font_type == e_pdf_cidfont_type2) {
- fdatap->data = ((pdf_cidfont_type2 *)font)->sfnt.data;
- fdatap->size = ((pdf_cidfont_type2 *)font)->sfnt.size;
+ fdatap->data = ((pdf_cidfont_type2 *)font)->sfnt->data;
+ fdatap->size = ((pdf_cidfont_type2 *)font)->sfnt->length;
}
else {
fdatap->data = font_data;
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c
index 6479cf791..634feb890 100644
--- a/pdf/pdf_font.c
+++ b/pdf/pdf_font.c
@@ -159,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));
@@ -256,12 +262,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dic
}
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) {
@@ -271,8 +277,8 @@ pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dic
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);
@@ -303,12 +309,12 @@ pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dic
}
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) {
@@ -318,8 +324,8 @@ pdfi_open_CIDFont_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dic
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);
@@ -559,22 +565,100 @@ 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;
+ return_error(gs_error_invalidfont);
- if (fallback == true) {
+ if (substitute == true) {
char *fbname;
int fbnamelen;
int64_t flags = 0;
@@ -607,7 +691,7 @@ pdfi_open_font_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *
}
do {
- code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, findex);
+ 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);
@@ -622,7 +706,7 @@ pdfi_open_font_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *
pdfi_countup(fontname);
}
}
- code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, findex);
+ code = pdf_fontmap_lookup_font(ctx, (pdf_name *) fontname, &mapname, &findex);
if (code < 0) {
mapname = fontname;
pdfi_countup(mapname);
@@ -647,62 +731,100 @@ pdfi_open_font_substitute_file(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *
return_error(gs_error_invalidfileaccess);
}
- 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;
- if (basefont) {
- pdfi_print_string(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");
+ 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;
}
- pdfi_print_string(ctx, fontfname);
- pdfi_print_string(ctx, "\n");
+ }
+ else
+ code = 0;
- 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);
+ 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;
}
- else {
- code = gs_note_error(gs_error_VMerror);
+ 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) {
+ code = pdfi_dict_put_obj(ctx, ctx->pdf_substitute_fonts, mapname, (pdf_obj *)pdffont, true);
+ }
+ }
}
- sfclose(s);
}
break;
} while (1);
+ if (code >= 0) {
+ if (basefont) {
+ pdfi_print_cstring(ctx, "Loading font ");
+ pdfi_print_font_name(ctx, (pdf_name *)basefont);
+ pdfi_print_cstring(ctx, " (or substitute) from ");
+ }
+ else {
+ pdfi_print_cstring(ctx, "Loading nameless font from ");
+ }
+ 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;
@@ -788,59 +910,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) {
@@ -854,14 +944,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;
}
@@ -1802,6 +1890,91 @@ 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;
+ int code;
+
+ if (fontdict == NULL) {
+ font->FirstChar = 0;
+ font->LastChar = 255;
+ }
+ else {
+ code = pdfi_dict_get_number(ctx, fontdict, "FirstChar", &f);
+ if (code < 0)
+ font->FirstChar = 0;
+ else
+ font->FirstChar = (int)(f < 0 ? 0 : f);
+
+ code = pdfi_dict_get_number(ctx, fontdict, "LastChar", &f);
+ if (code < 0)
+ font->LastChar = 255;
+ else
+ font->LastChar = (int)(f > 255 ? 255 : f);
+ }
+}
+
/* 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
diff --git a/pdf/pdf_font.h b/pdf/pdf_font.h
index 9da05eb5a..a18541c6f 100644
--- a/pdf/pdf_font.h
+++ b/pdf/pdf_font.h
@@ -106,5 +106,7 @@ enum {
};
int pdfi_get_cidfont_glyph_metrics(gs_font *pfont, gs_glyph cid, double *widths, bool vertical);
+int pdfi_font_create_widths(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font, double wscale);
+void pdfi_font_set_first_last_char(pdf_context *ctx, pdf_dict *fontdict, pdf_font *font);
int pdfi_font_generate_pseudo_XUID(pdf_context *ctx, pdf_dict *fontdict, gs_font_base *pfont);
#endif
diff --git a/pdf/pdf_font0.c b/pdf/pdf_font0.c
index a88e7a93e..76a94c8a4 100644
--- a/pdf/pdf_font0.c
+++ b/pdf/pdf_font0.c
@@ -365,6 +365,7 @@ int pdfi_read_type0_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream
dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", pdft0->type, pdft0->UID);
#endif
pdft0->refcnt = 1;
+ pdft0->filename = NULL;
pdft0->object_num = font_dict->object_num;
pdft0->generation_num = font_dict->generation_num;
pdft0->indirect_num = font_dict->indirect_num;
@@ -537,6 +538,8 @@ pdfi_free_font_type0(pdf_obj *font)
pdfi_countdown(pdft0->Encoding);
pdfi_countdown(pdft0->DescendantFonts);
pdfi_countdown(pdft0->ToUnicode);
+ pdfi_countdown(pdft0->filename);
+
gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.Encoding, "pdfi_free_font_type0(data.Encoding)");
/* We shouldn't need to free the fonts in the FDepVector, that should happen
with DescendantFonts above.
diff --git a/pdf/pdf_font1.c b/pdf/pdf_font1.c
index 2c54ad312..aa0c9ac07 100644
--- a/pdf/pdf_font1.c
+++ b/pdf/pdf_font1.c
@@ -135,11 +135,17 @@ pdfi_t1_subr_data(gs_font_type1 *pfont, int index, bool global, gs_glyph_data_t
int code = 0;
pdf_font_type1 *pdffont1 = (pdf_font_type1 *) pfont->client_data;
- if (global == true || index < 0 || index >= pdffont1->NumSubrs) {
+ if (global == true || index < 0 || index >= (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
code = gs_note_error(gs_error_rangecheck);
}
else {
- gs_glyph_data_from_bytes(pgd, pdffont1->Subrs[index].data, 0, pdffont1->Subrs[index].size, NULL);
+ pdf_string *subr_str;
+ code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
+ if (code >= 0) {
+ gs_glyph_data_from_bytes(pgd, subr_str->data, 0, subr_str->length, NULL);
+ /* decrementing is safe here, because the reference in the pdffont1->Subrs will persist */
+ pdfi_countdown(subr_str);
+ }
}
return code;
}
@@ -515,7 +521,8 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
pdf_obj *tounicode = NULL;
ps_font_interp_private fpriv = { 0 };
- (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
+ if (font_dict != NULL)
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
if (fbuf[0] == 128 && fbuf[1] == 1) {
byte *decodebuf = NULL;
@@ -541,7 +548,7 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
code = gs_note_error(gs_error_invalidfont);
goto error;
}
- code = pdfi_alloc_t1_font(ctx, &t1f, font_dict->object_num);
+ code = pdfi_alloc_t1_font(ctx, &t1f, font_dict != NULL ? font_dict->object_num : 0);
if (code >= 0) {
gs_font_type1 *pfont1 = (gs_font_type1 *) t1f->pfont;
@@ -561,22 +568,26 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
pfont1->PaintType = fpriv.gsu.gst1.PaintType;
pfont1->StrokeWidth = fpriv.gsu.gst1.StrokeWidth;
- t1f->object_num = font_dict->object_num;
- t1f->generation_num = font_dict->generation_num;
- t1f->indirect_num = font_dict->indirect_num;
- t1f->indirect_gen = font_dict->indirect_gen;
+ if (font_dict != NULL) {
+ t1f->object_num = font_dict->object_num;
+ t1f->generation_num = font_dict->generation_num;
+ t1f->indirect_num = font_dict->indirect_num;
+ t1f->indirect_gen = font_dict->indirect_gen;
+ }
t1f->PDF_font = font_dict;
pdfi_countup(font_dict);
- t1f->BaseFont = basefont;
- pdfi_countup(basefont);
t1f->FontDescriptor = (pdf_dict *) fontdesc;
pdfi_countup(fontdesc);
t1f->Name = mapname;
pdfi_countup(mapname);
/* We want basefont, but we can live without it */
- (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
+ if (font_dict != NULL) {
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
+ t1f->BaseFont = basefont;
+ pdfi_countup(basefont);
+ }
t1f->descflags = 0;
if (t1f->FontDescriptor != NULL) {
@@ -594,7 +605,7 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
t1f->descflags |= 4;
}
- if (ctx->args.ignoretounicode != true) {
+ if (ctx->args.ignoretounicode != true && font_dict != NULL) {
code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
pdf_cmap *tu = NULL;
@@ -614,88 +625,22 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
t1f->ToUnicode = tounicode;
tounicode = NULL;
- code = pdfi_dict_knownget_type(ctx, font_dict, "FirstChar", PDF_INT, &tmp);
- if (code == 1) {
- t1f->FirstChar = ((pdf_num *) tmp)->value.i;
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- t1f->FirstChar = 0;
- }
- code = pdfi_dict_knownget_type(ctx, font_dict, "LastChar", PDF_INT, &tmp);
- if (code == 1) {
- t1f->LastChar = ((pdf_num *) tmp)->value.i;
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- t1f->LastChar = 255;
- }
-
- t1f->fake_glyph_names = (gs_string *) gs_alloc_bytes(ctx->memory, t1f->LastChar * sizeof(gs_string), "pdfi_read_type1_font: fake_glyph_names");
- if (!t1f->fake_glyph_names) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
- memset(t1f->fake_glyph_names, 0x00, t1f->LastChar * sizeof(gs_string));
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)t1f);
/* Widths are defined assuming a 1000x1000 design grid, but we apply
* them in font space - so undo the 1000x1000 scaling, and apply
* the inverse of the font's x scaling
*/
x_scale = 0.001 / hypot(pfont1->FontMatrix.xx, pfont1->FontMatrix.xy);
- if (t1f->FontDescriptor != NULL) {
- code = pdfi_dict_knownget(ctx, t1f->FontDescriptor, "MissingWidth", &tmp);
- if (code > 0) {
- if (pdfi_type_of(tmp) == PDF_INT) {
- t1f->MissingWidth = ((pdf_num *) tmp)->value.i * x_scale;
- }
- else if (pdfi_type_of(tmp) == PDF_REAL) {
- t1f->MissingWidth = ((pdf_num *) tmp)->value.d * x_scale;
- }
- else {
- t1f->MissingWidth = 0;
- }
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- t1f->MissingWidth = 0;
- }
- }
- else {
- t1f->MissingWidth = 1000 * x_scale;
- }
- code = pdfi_dict_knownget_type(ctx, font_dict, "Widths", PDF_ARRAY, &tmp);
- if (code > 0) {
- int i;
- int num_chars = t1f->LastChar - t1f->FirstChar + 1;
-
- if (num_chars == pdfi_array_size((pdf_array *) tmp)) {
- t1f->Widths = (double *)gs_alloc_bytes(ctx->memory, sizeof(double) * num_chars, "Type 1 font Widths array");
- if (t1f->Widths == NULL) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
-
- memset(t1f->Widths, 0x00, sizeof(double) * num_chars);
- for (i = 0; i < num_chars; i++) {
- code = pdfi_array_get_number(ctx, (pdf_array *) tmp, (uint64_t) i, &t1f->Widths[i]);
- if (code < 0)
- goto error;
- t1f->Widths[i] *= x_scale;
- }
- }
- else {
- t1f->Widths = NULL;
- }
- }
- pdfi_countdown(tmp);
- tmp = NULL;
+ /* ignore errors with widths... for now */
+ if (font_dict != NULL)
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)t1f, x_scale);
- code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ if (font_dict != NULL)
+ code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ else
+ code = gs_error_undefined;
if (code == 1) {
if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (t1f->descflags & 4) == 0) {
code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & t1f->Encoding);
@@ -740,7 +685,6 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
t1f->Subrs = fpriv.u.t1.Subrs;
fpriv.u.t1.Subrs = NULL;
- t1f->NumSubrs = fpriv.u.t1.NumSubrs;
t1f->blenddesignpositions = fpriv.u.t1.blenddesignpositions;
pdfi_countup(t1f->blenddesignpositions);
@@ -780,20 +724,179 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
pdfi_countdown(fpriv.u.t1.blenddesignmap);
pdfi_countdown(fpriv.u.t1.blendfontbbox);
pdfi_countdown(fpriv.u.t1.blendaxistypes);
+ pdfi_countdown(fpriv.u.t1.Subrs);
if (fpriv.gsu.gst1.UID.xvalues != NULL) {
gs_free_object(ctx->memory, fpriv.gsu.gst1.UID.xvalues, "pdfi_read_type1_font(xuid)");
}
- if (fpriv.u.t1.Subrs) {
- int i;
- for (i = 0; i < fpriv.u.t1.NumSubrs; i++) {
- gs_free_object(ctx->memory, fpriv.u.t1.Subrs[i].data, "Subrs[i]");
+ if (code < 0) {
+ pdfi_countdown(t1f);
+ }
+ return code;
+}
+
+int
+pdfi_copy_type1_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
+{
+ int code = 0;
+ pdf_font_type1 *font = NULL;
+ gs_font_type1 *spfont1 = (gs_font_type1 *) spdffont->pfont;
+ gs_font_type1 *dpfont1;
+ gs_id t_id;
+ pdf_obj *tmp;
+
+ if (font_dict == NULL)
+ return_error(gs_error_invalidfont);
+
+ code = pdfi_alloc_t1_font(ctx, &font, font_dict->object_num);
+ if (code < 0)
+ return code;
+ dpfont1 = (gs_font_type1 *) font->pfont;
+
+ t_id = dpfont1->id;
+ memcpy(dpfont1, spfont1, sizeof(gs_font_type1));
+ dpfont1->id = t_id;
+ dpfont1->FAPI = NULL;
+ dpfont1->FAPI_font_data = NULL;
+
+ memcpy(font, spdffont, sizeof(pdf_font_type1));
+ font->pfont = (gs_font_base *)dpfont1;
+ font->refcnt = 1;
+ dpfont1->client_data = (void *)font;
+ font->filename = NULL;
+
+ dpfont1->notify_list.memory = NULL;
+ dpfont1->notify_list.first = NULL;
+ gs_notify_init(&dpfont1->notify_list, dpfont1->memory);
+
+ font->PDF_font = font_dict;
+ font->object_num = font_dict->object_num;
+ font->generation_num = font_dict->generation_num;
+ pdfi_countup(font->PDF_font);
+
+ /* We want basefont and descriptor, but we can live without them */
+ font->BaseFont = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont);
+ font->FontDescriptor = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
+
+ pdfi_countup(font->Name);
+ pdfi_countup(font->CharStrings);
+ pdfi_countup(font->blenddesignpositions);
+ pdfi_countup(font->blenddesignmap);
+ pdfi_countup(font->blendfontbbox);
+ pdfi_countup(font->blendaxistypes);
+ pdfi_countup(font->Subrs);
+
+ if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) {
+ memcpy(dpfont1->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont1->key_name.size = ((pdf_name *)font->BaseFont)->length;
+ memcpy(dpfont1->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont1->font_name.size = ((pdf_name *)font->BaseFont)->length;
+ }
+
+ font->Encoding = NULL;
+ font->ToUnicode = NULL;
+ font->Widths = NULL;
+
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font *)font, (double)(0.001 / hypot(dpfont1->FontMatrix.xx, dpfont1->FontMatrix.xy)));
+
+ font->descflags = 0;
+ if (font->FontDescriptor != NULL) {
+ code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags);
+ if (code >= 0) {
+ /* If both the symbolic and non-symbolic flag are set,
+ believe that latter.
+ */
+ if ((font->descflags & 32) != 0)
+ font->descflags = (font->descflags & ~4);
+ }
+ }
+
+ if (pdfi_font_known_symbolic(font->BaseFont)) {
+ font->descflags |= 4;
+ }
+
+ tmp = NULL;
+ code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ if (code == 1) {
+ if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) {
+ code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) {
+ code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else
+ code = gs_error_undefined;
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ if (code == 1) {
+ /* Since the underlying font stream can be shared between font descriptors,
+ and the font descriptors can be shared between font objects, if we change
+ the encoding, we can't share cached glyphs with other instances of this
+ underlying font, so invalidate the UniqueID/XUID so the glyph cache won't
+ try.
+ */
+ if (uid_is_XUID(&font->pfont->UID))
+ uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
+ uid_set_invalid(&font->pfont->UID);
+ }
+ }
+ else {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
+ }
+
+ if (code <= 0) {
+ font->Encoding = spdffont->Encoding;
+ pdfi_countup(font->Encoding);
+ }
+
+ if (ctx->args.ignoretounicode != true) {
+ code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp);
+ if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) {
+ pdf_cmap *tu = NULL;
+ code = pdfi_read_cmap(ctx, tmp, &tu);
+ pdfi_countdown(tmp);
+ tmp = (pdf_obj *)tu;
+ }
+ if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
}
- gs_free_object(ctx->memory, fpriv.u.t1.Subrs, "Subrs");
}
+ else {
+ tmp = NULL;
+ }
+ font->ToUnicode = tmp;
+
+ code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont);
if (code < 0) {
- pdfi_countdown(t1f);
+ goto error;
+ }
+
+ code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0);
+ if (code < 0) {
+ goto error;
+ }
+ /* object_num can be zero if the dictionary was defined inline */
+ if (font->object_num != 0) {
+ (void)replace_cache_entry(ctx, (pdf_obj *) font);
}
+
+ *tpdffont = (pdf_font *)font;
+
+error:
+ if (code < 0)
+ pdfi_countdown(font);
+
return code;
}
@@ -801,7 +904,6 @@ int
pdfi_free_font_type1(pdf_obj *font)
{
pdf_font_type1 *t1f = (pdf_font_type1 *) font;
- int i;
gs_free_object(OBJ_MEMORY(font), t1f->pfont, "Free Type 1 gs_font");
@@ -816,20 +918,9 @@ pdfi_free_font_type1(pdf_obj *font)
pdfi_countdown(t1f->blenddesignmap);
pdfi_countdown(t1f->blendfontbbox);
pdfi_countdown(t1f->blendaxistypes);
+ pdfi_countdown(t1f->Subrs);
+ pdfi_countdown(t1f->filename);
- if (t1f->fake_glyph_names != NULL) {
- for (i = 0; i < t1f->LastChar; i++) {
- if (t1f->fake_glyph_names[i].data != NULL)
- gs_free_object(OBJ_MEMORY(font), t1f->fake_glyph_names[i].data, "Type 1 fake_glyph_name");
- }
- gs_free_object(OBJ_MEMORY(font), t1f->fake_glyph_names, "Type 1 fake_glyph_names");
- }
- if (t1f->NumSubrs > 0 && t1f->Subrs != NULL) {
- for (i = 0; i < t1f->NumSubrs; i++) {
- gs_free_object(OBJ_MEMORY(font), t1f->Subrs[i].data, "Type 1 Subr");
- }
- gs_free_object(OBJ_MEMORY(font), t1f->Subrs, "Type 1 Subrs");
- }
gs_free_object(OBJ_MEMORY(font), t1f->Widths, "Free Type 1 fontWidths");
gs_free_object(OBJ_MEMORY(font), t1f, "Free Type 1 font");
return 0;
diff --git a/pdf/pdf_font1.h b/pdf/pdf_font1.h
index 0385aafd5..5fd41afa0 100644
--- a/pdf/pdf_font1.h
+++ b/pdf/pdf_font1.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019-2021 Artifex Software, Inc.
+/* Copyright (C) 2019-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -21,6 +21,8 @@
int pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *fbuf, int64_t fbuflen, pdf_font **ppdffont);
int pdfi_free_font_type1(pdf_obj *font);
+int pdfi_copy_type1_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont);
+
int pdfi_t1_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph);
#endif
diff --git a/pdf/pdf_font11.c b/pdf/pdf_font11.c
index f4c002589..685ebe768 100644
--- a/pdf/pdf_font11.c
+++ b/pdf/pdf_font11.c
@@ -36,12 +36,12 @@ static int pdfi_cidtype2_string_proc(gs_font_type42 * pfont, ulong offset, uint
pdf_cidfont_type2 *ttfont = (pdf_cidfont_type2 *)pfont->client_data;
int code = 0;
- if (offset + length > ttfont->sfnt.size) {
+ if (offset + length > ttfont->sfnt->length) {
*pdata = NULL;
code = gs_note_error(gs_error_invalidfont);
}
else {
- *pdata = ttfont->sfnt.data + offset;
+ *pdata = ttfont->sfnt->data + offset;
}
return code;
}
@@ -51,8 +51,8 @@ static int pdfi_cidtype2_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data;
uint gid = glyph - GS_MIN_CID_GLYPH;
- if (pdffont11->cidtogidmap.size > (gid << 1) + 1) {
- gid = pdffont11->cidtogidmap.data[gid << 1] << 8 | pdffont11->cidtogidmap.data[(gid << 1) + 1];
+ if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) {
+ gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
}
return (int)gid;
@@ -69,8 +69,8 @@ static uint pdfi_cidtype2_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
else {
if (glyph < GS_MIN_GLYPH_INDEX) {
gid = glyph - GS_MIN_CID_GLYPH;
- if (pdffont11->cidtogidmap.size > 0) {
- gid = pdffont11->cidtogidmap.data[gid << 1] << 8 | pdffont11->cidtogidmap.data[(gid << 1) + 1];
+ if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) {
+ gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1];
}
}
else {
@@ -151,15 +151,15 @@ pdfi_cidtype2_enumerate_glyph(gs_font *font, int *pindex,
if (*pindex <= 0)
*pindex = 0;
- if (pdffont11->cidtogidmap.size > 0) {
+ if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) {
do {
- *pglyph = pdffont11->cidtogidmap.data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap.data[((*pindex) << 1) + 1];
+ *pglyph = pdffont11->cidtogidmap->data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap->data[((*pindex) << 1) + 1];
(*pindex)++;
if (*pglyph == 0 && *pindex == 1) /* notdef - special case */
break;
- } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap.size);
+ } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap->length);
- if (((*pindex) << 1) >= pdffont11->cidtogidmap.size) {
+ if (((*pindex) << 1) >= pdffont11->cidtogidmap->length) {
*pindex = 0;
}
else {
@@ -312,9 +312,16 @@ int pdfi_read_cidtype2_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
font->FontDescriptor = (pdf_dict *)fontdesc;
fontdesc = NULL;
- /* Ownership of buf is now part of the font and managed via its lifetime */
- font->sfnt.data = buf;
- font->sfnt.size = buflen;
+ code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
+ if (code < 0) {
+ goto error;
+ }
+ pdfi_countup(font->sfnt);
+ code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
+ if (code < 0) {
+ goto error;
+ }
+ buf = NULL;
/* Strictly speaking BaseFont is required, but we can continue without one */
code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&obj);
@@ -368,18 +375,26 @@ int pdfi_read_cidtype2_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **)&obj);
if (code > 0) {
- font->cidtogidmap.data = NULL;
- font->cidtogidmap.size = 0;
/* CIDToGIDMap can only be a stream or a name, and if it's a name
it's only permitted to be "/Identity", so ignore it
*/
if (pdfi_type_of(obj) == PDF_STREAM) {
+ byte *d;
int64_t sz;
- code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &(font->cidtogidmap.data), &sz);
+
+ code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->cidtogidmap);
+ if (code < 0) {
+ goto error;
+ }
+ pdfi_countup(font->cidtogidmap);
+ code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz);
+ if (code < 0) {
+ goto error;
+ }
+ code = pdfi_buffer_set_data((pdf_obj *)font->cidtogidmap, d, (int32_t)sz);
if (code < 0) {
goto error;
}
- font->cidtogidmap.size = (uint)sz;
}
pdfi_countdown(obj);
obj = NULL;
@@ -435,12 +450,12 @@ int pdfi_read_cidtype2_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
font->pfont->procs.glyph_info = pdfi_cidtype2_glyph_info;
font->pfont->procs.enumerate_glyph = pdfi_cidtype2_enumerate_glyph;
- if (font->cidtogidmap.size > 0) {
+ if (font->cidtogidmap != NULL) {
gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont;
- if (cid2->data.numGlyphs > font->cidtogidmap.size >> 1)
+ if (cid2->data.numGlyphs > font->cidtogidmap->length >> 1)
cid2->cidata.common.CIDCount = cid2->data.numGlyphs;
else {
- cid2->cidata.common.CIDCount = font->cidtogidmap.size >> 1;
+ cid2->cidata.common.CIDCount = font->cidtogidmap->length >> 1;
}
cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount;
}
@@ -462,7 +477,7 @@ int pdfi_read_cidtype2_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
goto error;
}
- code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt.data, font->sfnt.size);
+ code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length);
if (code < 0) {
goto error;
}
@@ -487,9 +502,9 @@ int pdfi_free_font_cidtype2(pdf_obj *font)
gs_font_cid2 *pfont = (gs_font_cid2 *)pdfcidf->pfont;
gs_free_object(OBJ_MEMORY(pdfcidf), pfont, "pdfi_free_font_cidtype2(pfont)");
- gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf->cidtogidmap.data, "pdfi_free_font_cidtype2(cidtogidmap.data)");
- gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf->sfnt.data, "pdfi_free_font_cidtype2(sfnt.data)");
+ pdfi_countdown(pdfcidf->cidtogidmap);
+ pdfi_countdown(pdfcidf->sfnt);
pdfi_countdown(pdfcidf->PDF_font);
pdfi_countdown(pdfcidf->BaseFont);
pdfi_countdown(pdfcidf->FontDescriptor);
@@ -498,6 +513,7 @@ int pdfi_free_font_cidtype2(pdf_obj *font)
pdfi_countdown(pdfcidf->W2);
pdfi_countdown(pdfcidf->registry);
pdfi_countdown(pdfcidf->ordering);
+ pdfi_countdown(pdfcidf->filename);
gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf, "pdfi_free_font_cidtype2(pdfcidf)");
return 0;
diff --git a/pdf/pdf_font1C.c b/pdf/pdf_font1C.c
index 7753bf2f7..6bebc5a2d 100644
--- a/pdf/pdf_font1C.c
+++ b/pdf/pdf_font1C.c
@@ -60,7 +60,7 @@ typedef struct pdfi_cff_font_priv_s {
pdf_array *W;
pdf_array *DW2;
pdf_array *W2;
- gs_string cidtogidmap;
+ pdf_buffer *cidtogidmap;
pdf_array *FDArray;
/* The registry and ordering strings in gs_font_cid0_data are just references to
strings assumed to be managed be managed by the interpreter - so we have to stash
@@ -301,9 +301,9 @@ pdfi_cff_enumerate_glyph(gs_font *pfont, int *pindex,
}
if (l > 0) {
pdf_cidfont_type0 *cffcidfont = (pdf_cidfont_type0 *) pdffont;
- if (cffcidfont->cidtogidmap.size > 0) {
- for (j = (cffcidfont->cidtogidmap.size >> 1) - 1; j >= 0; j--) {
- if (val == (cffcidfont->cidtogidmap.data[j << 1] << 8 | cffcidfont->cidtogidmap.data[(j << 1) + 1])) {
+ if (cffcidfont->cidtogidmap != NULL && cffcidfont->cidtogidmap->length > 0) {
+ for (j = (cffcidfont->cidtogidmap->length >> 1) - 1; j >= 0; j--) {
+ if (val == (cffcidfont->cidtogidmap->data[j << 1] << 8 | cffcidfont->cidtogidmap->data[(j << 1) + 1])) {
val = j;
break;
}
@@ -432,8 +432,8 @@ pdfi_cff_cid_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *p
else
gid = glyph - GS_MIN_CID_GLYPH;
- if (pdffont9->cidtogidmap.size > (gid << 1) + 1) {
- gid = pdffont9->cidtogidmap.data[gid << 1] << 8 | pdffont9->cidtogidmap.data[(gid << 1) + 1];
+ if (pdffont9->cidtogidmap != NULL && pdffont9->cidtogidmap->length > (gid << 1) + 1) {
+ gid = pdffont9->cidtogidmap->data[gid << 1] << 8 | pdffont9->cidtogidmap->data[(gid << 1) + 1];
}
l = gs_snprintf(nbuf, sizeof(nbuf), "%" PRId64, gid);
@@ -1874,9 +1874,8 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv)
/* Check the subrs index */
pdffont->Subrs = NULL;
- pdffont->subrs = fdptpriv.pdfcffpriv.subrs;
- if (pdffont->subrs) {
- p = pdfi_count_cff_index(pdffont->subrs, e, &pdffont->NumSubrs);
+ if (fdptpriv.pdfcffpriv.subrs) {
+ p = pdfi_count_cff_index(fdptpriv.pdfcffpriv.subrs, e, &pdffont->NumSubrs);
if (!p) {
pdffont->Subrs = NULL;
pdffont->NumSubrs = 0;
@@ -1892,7 +1891,7 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv)
for (j = 0; j < pdffont->NumSubrs; j++) {
pdf_string *subrstr;
- p = pdfi_find_cff_index(pdffont->subrs, e, j, &strp, &stre);
+ p = pdfi_find_cff_index(fdptpriv.pdfcffpriv.subrs, e, j, &strp, &stre);
if (p) {
code = pdfi_object_alloc(ctx, PDF_STRING, stre - strp, (pdf_obj **) &subrstr);
if (code >= 0) {
@@ -2265,8 +2264,13 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
fbuflen = tlen;
}
- code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
- if (code < 0) {
+ if (font_dict != NULL) {
+ code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
+ if (code < 0) {
+ fontdesc = NULL;
+ }
+ }
+ else {
fontdesc = NULL;
}
@@ -2353,9 +2357,6 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
cffcid->PDF_font = font_dict;
pdfi_countup(font_dict);
- cffcid->cidtogidmap.data = NULL;
- cffcid->cidtogidmap.size = 0;
-
pfont->client_data = cffcid;
cffcid->object_num = font_dict->object_num;
@@ -2379,23 +2380,35 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
pfont->cidata.common.CIDCount = cffpriv.pdfcffpriv.cidcount;
- cffcid->cidtogidmap.data = NULL;
- cffcid->cidtogidmap.size = 0;
+ cffcid->cidtogidmap = NULL;
code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **) &obj);
if (code > 0) {
/* CIDToGIDMap can only be a stream or a name, and if it's a name
it's only permitted to be "/Identity", so ignore it
*/
- int64_t size = 0;
if (pdfi_type_of(obj) == PDF_STREAM) {
- code = pdfi_stream_to_buffer(ctx, (pdf_stream *) obj, &(cffcid->cidtogidmap.data), &size);
+ byte *d;
+ int64_t sz;
+
+ code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&cffcid->cidtogidmap);
+ if (code < 0) {
+ goto error;
+ }
+ pdfi_countup(cffcid->cidtogidmap);
+ code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz);
+ if (code < 0) {
+ goto error;
+ }
+ code = pdfi_buffer_set_data((pdf_obj *)cffcid->cidtogidmap, d, (int32_t)sz);
+ if (code < 0) {
+ goto error;
+ }
}
pdfi_countdown(obj);
obj = NULL;
- cffcid->cidtogidmap.size = size;
- if (size > 0) {
- pfont->cidata.common.CIDCount = size >> 1;
+ if (cffcid->cidtogidmap != NULL && cffcid->cidtogidmap->length > 0) {
+ pfont->cidata.common.CIDCount = cffcid->cidtogidmap->length >> 1;
}
}
pfont->cidata.common.MaxCID = pfont->cidata.common.CIDCount - 1;
@@ -2576,22 +2589,34 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
cffcid->PDF_font = font_dict;
pdfi_countup(font_dict);
- cffcid->cidtogidmap.data = NULL;
- cffcid->cidtogidmap.size = 0;
+ cffcid->cidtogidmap = NULL;
code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **) &obj);
if (code > 0) {
+ byte *d;
+ int64_t sz;
/* CIDToGIDMap can only be a stream or a name, and if it's a name
it's only permitted to be "/Identity", so ignore it
*/
- int64_t size = 0;
if (pdfi_type_of(obj) == PDF_STREAM) {
- code = pdfi_stream_to_buffer(ctx, (pdf_stream *) obj, &(cffcid->cidtogidmap.data), (int64_t *) &size);
+ code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&cffcid->cidtogidmap);
+ if (code < 0) {
+ goto error;
+ }
+ pdfi_countup(cffcid->cidtogidmap);
+ code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz);
+ if (code < 0) {
+ goto error;
+ }
+ code = pdfi_buffer_set_data((pdf_obj *)cffcid->cidtogidmap, d, (int32_t)sz);
+ if (code < 0) {
+ goto error;
+ }
}
pdfi_countdown(obj);
obj = NULL;
- cffcid->cidtogidmap.size = size;
- if (size > 0) {
- pfont->cidata.common.CIDCount = size >> 1;
+
+ if (cffcid->cidtogidmap != NULL && cffcid->cidtogidmap->length > 0) {
+ pfont->cidata.common.CIDCount = cffcid->cidtogidmap->length >> 1;
}
}
pfont->cidata.common.MaxCID = pfont->cidata.common.CIDCount - 1;
@@ -2639,9 +2664,8 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
pdf_font_cff *cfffont;
gs_font_type1 *pfont = NULL;
pdf_obj *tounicode = NULL;
- double x_scale;
- code = pdfi_alloc_cff_font(ctx, &cfffont, font_dict->object_num, false);
+ code = pdfi_alloc_cff_font(ctx, &cfffont, font_dict != NULL ? font_dict->object_num : 0, false);
pfont = (gs_font_type1 *) cfffont->pfont;
ppdfont = (pdf_font *) cfffont;
@@ -2653,12 +2677,15 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
pfont->procs.glyph_info = pdfi_cff_glyph_info;
- cfffont->object_num = font_dict->object_num;
- cfffont->generation_num = font_dict->generation_num;
- cfffont->indirect_num = font_dict->indirect_num;
- cfffont->indirect_gen = font_dict->indirect_gen;
+ if (font_dict) {
+ cfffont->object_num = font_dict->object_num;
+ cfffont->generation_num = font_dict->generation_num;
+ cfffont->indirect_num = font_dict->indirect_num;
+ cfffont->indirect_gen = font_dict->indirect_gen;
+
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
+ }
- (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont);
cfffont->BaseFont = basefont;
cfffont->Name = basefont;
pdfi_countup(basefont);
@@ -2696,89 +2723,21 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
cfffont->descflags |= 4;
}
- code = pdfi_dict_knownget_type(ctx, font_dict, "FirstChar", PDF_INT, &tmp);
- if (code == 1) {
- cfffont->FirstChar = ((pdf_num *) tmp)->value.i;
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- cfffont->FirstChar = 0;
- }
- code = pdfi_dict_knownget_type(ctx, font_dict, "LastChar", PDF_INT, &tmp);
- if (code == 1) {
- cfffont->LastChar = ((pdf_num *) tmp)->value.i;
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- cfffont->LastChar = 255;
- }
-
- cfffont->fake_glyph_names = (gs_string *) gs_alloc_bytes(ctx->memory, cfffont->LastChar * sizeof(gs_string), "pdfi_read_cff_font: fake_glyph_names");
- if (!cfffont->fake_glyph_names) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
- memset(cfffont->fake_glyph_names, 0x00, cfffont->LastChar * sizeof(gs_string));
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)cfffont);
/* Widths are defined assuming a 1000x1000 design grid, but we apply
* them in font space - so undo the 1000x1000 scaling, and apply
* the inverse of the font's x scaling
*/
- x_scale = 0.001 / hypot(pfont->FontMatrix.xx, pfont->FontMatrix.xy);
- if (cfffont->FontDescriptor != NULL) {
- code = pdfi_dict_knownget(ctx, cfffont->FontDescriptor, "MissingWidth", &tmp);
- if (code > 0) {
- if (pdfi_type_of(tmp) == PDF_INT) {
- cfffont->MissingWidth = ((pdf_num *) tmp)->value.i * x_scale;
- }
- else if (pdfi_type_of(tmp) == PDF_REAL) {
- cfffont->MissingWidth = ((pdf_num *) tmp)->value.d * x_scale;
- }
- else {
- cfffont->MissingWidth = 0;
- }
- pdfi_countdown(tmp);
- tmp = NULL;
- }
- else {
- cfffont->MissingWidth = 0;
- }
- }
- else {
- cfffont->MissingWidth = 1000 * x_scale;
- }
-
- code = pdfi_dict_knownget_type(ctx, font_dict, "Widths", PDF_ARRAY, &tmp);
- if (code > 0) {
- int i;
- int num_chars = cfffont->LastChar - cfffont->FirstChar + 1;
-
- if (num_chars != pdfi_array_size((pdf_array *) tmp)) {
- pdfi_countdown(tmp);
- code = gs_note_error(gs_error_rangecheck);
- goto error;
- }
-
- cfffont->Widths = (double *)gs_alloc_bytes(ctx->memory, sizeof(double) * num_chars, "Type 1C font Widths array");
- if (cfffont->Widths == NULL) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
- memset(cfffont->Widths, 0x00, sizeof(double) * num_chars);
-
- for (i = 0; i < num_chars; i++) {
- code = pdfi_array_get_number(ctx, (pdf_array *) tmp, (uint64_t) i, &cfffont->Widths[i]);
- if (code < 0)
- goto error;
- cfffont->Widths[i] *= x_scale;
- }
+ if (font_dict != NULL) {
+ /* ignore errors with widths... for now */
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)cfffont, (double)(0.001 / hypot(pfont->FontMatrix.xx, pfont->FontMatrix.xy)));
}
- pdfi_countdown(tmp);
- tmp = NULL;
- code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ if (font_dict != NULL)
+ code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ else
+ code = gs_error_undefined;
if (code == 1) {
if ((cfffont->descflags & 4) != 0 && pdfi_type_of(tmp) == PDF_DICT) {
code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)cffpriv.pdfcffpriv.Encoding, (pdf_obj **) &cfffont->Encoding);
@@ -2810,7 +2769,7 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict,
cfffont->Encoding = cffpriv.pdfcffpriv.Encoding;
cffpriv.pdfcffpriv.Encoding = NULL;
}
- if (ctx->args.ignoretounicode != true) {
+ if (ctx->args.ignoretounicode != true && font_dict != NULL) {
code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
pdf_cmap *tu = NULL;
@@ -2916,6 +2875,167 @@ pdfi_read_type1C_font(pdf_context *ctx, pdf_dict *font_dict,
}
int
+pdfi_copy_cff_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
+{
+ int code = 0;
+ pdf_font_cff *font = NULL;
+ gs_font_type1 *spfont1 = (gs_font_type1 *) spdffont->pfont;
+ gs_font_type1 *dpfont1;
+ gs_id t_id;
+ pdf_obj *tmp;
+
+ if (font_dict == NULL)
+ return_error(gs_error_invalidfont);
+
+ code = pdfi_alloc_cff_font(ctx, &font, font_dict->object_num, false);
+ if (code < 0)
+ return code;
+ dpfont1 = (gs_font_type1 *) font->pfont;
+
+ t_id = dpfont1->id;
+ memcpy(dpfont1, spfont1, sizeof(gs_font_type1));
+ dpfont1->id = t_id;
+ dpfont1->FAPI = NULL;
+ dpfont1->FAPI_font_data = NULL;
+ dpfont1->notify_list.memory = NULL;
+ dpfont1->notify_list.first = NULL;
+ gs_notify_init(&dpfont1->notify_list, dpfont1->memory);
+
+ memcpy(font, spdffont, sizeof(pdf_font_type1));
+ font->refcnt = 1;
+ font->pfont = (gs_font_base *)dpfont1;
+ dpfont1->client_data = (void *)font;
+ font->filename = NULL;
+
+ font->PDF_font = font_dict;
+ font->object_num = font_dict->object_num;
+ font->generation_num = font_dict->generation_num;
+ pdfi_countup(font->PDF_font);
+
+ /* We want basefont and descriptor, but we can live without them */
+ font->BaseFont = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont);
+ font->FontDescriptor = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
+
+ pdfi_countup(font->Name);
+ pdfi_countup(font->CharStrings);
+ pdfi_countup(font->Subrs);
+ pdfi_countup(font->GlobalSubrs);
+
+ if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) {
+ memcpy(dpfont1->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont1->key_name.size = ((pdf_name *)font->BaseFont)->length;
+ memcpy(dpfont1->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont1->font_name.size = ((pdf_name *)font->BaseFont)->length;
+ }
+
+ font->Encoding = NULL;
+ font->ToUnicode = NULL;
+ font->Widths = NULL;
+
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font *)font, (double)(0.001 / hypot(dpfont1->FontMatrix.xx, dpfont1->FontMatrix.xy)));
+
+ font->descflags = 0;
+ if (font->FontDescriptor != NULL) {
+ code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags);
+ if (code >= 0) {
+ /* If both the symbolic and non-symbolic flag are set,
+ believe that latter.
+ */
+ if ((font->descflags & 32) != 0)
+ font->descflags = (font->descflags & ~4);
+ }
+ }
+
+ if (pdfi_font_known_symbolic(font->BaseFont)) {
+ font->descflags |= 4;
+ }
+
+
+ tmp = NULL;
+ code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ if (code == 1) {
+ if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) {
+ code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) {
+ code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else
+ code = gs_error_undefined;
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ if (code == 1) {
+ /* Since the underlying font stream can be shared between font descriptors,
+ and the font descriptors can be shared between font objects, if we change
+ the encoding, we can't share cached glyphs with other instances of this
+ underlying font, so invalidate the UniqueID/XUID so the glyph cache won't
+ try.
+ */
+ if (uid_is_XUID(&font->pfont->UID))
+ uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
+ uid_set_invalid(&font->pfont->UID);
+ }
+ }
+ else {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
+ }
+
+ if (code <= 0) {
+ font->Encoding = spdffont->Encoding;
+ pdfi_countup(font->Encoding);
+ }
+
+ if (ctx->args.ignoretounicode != true) {
+ code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp);
+ if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) {
+ pdf_cmap *tu = NULL;
+ code = pdfi_read_cmap(ctx, tmp, &tu);
+ pdfi_countdown(tmp);
+ tmp = (pdf_obj *)tu;
+ }
+ if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
+ }
+ }
+ else {
+ tmp = NULL;
+ }
+ font->ToUnicode = tmp;
+
+ code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont);
+ if (code < 0) {
+ goto error;
+ }
+
+ code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0);
+ if (code < 0) {
+ goto error;
+ }
+ /* object_num can be zero if the dictionary was defined inline */
+ if (font->object_num != 0) {
+ (void)replace_cache_entry(ctx, (pdf_obj *) font);
+ }
+
+ *tpdffont = (pdf_font *)font;
+
+error:
+ if (code < 0)
+ pdfi_countdown(font);
+ return code;
+}
+
+int
pdfi_free_font_cff(pdf_obj *font)
{
pdf_font_cff *pdfontcff = (pdf_font_cff *) font;
@@ -2931,8 +3051,8 @@ pdfi_free_font_cff(pdf_obj *font)
pdfi_countdown(pdfontcff->GlobalSubrs);
pdfi_countdown(pdfontcff->Encoding);
pdfi_countdown(pdfontcff->ToUnicode);
+ pdfi_countdown(pdfontcff->filename);
- gs_free_object(OBJ_MEMORY(font), pdfontcff->fake_glyph_names, "Type 2 fake_glyph_names");
gs_free_object(OBJ_MEMORY(font), pdfontcff->Widths, "Type 2 fontWidths");
gs_free_object(OBJ_MEMORY(font), pdfontcff, "pdfi_free_font_cff(pbfont)");
@@ -2966,8 +3086,9 @@ pdfi_free_font_cidtype0(pdf_obj *font)
pdfi_countdown(pdfont0->FDArray);
pdfi_countdown(pdfont0->registry);
pdfi_countdown(pdfont0->ordering);
+ pdfi_countdown(pdfont0->cidtogidmap);
+ pdfi_countdown(pdfont0->filename);
- gs_free_object(OBJ_MEMORY(font), pdfont0->cidtogidmap.data, "pdfi_free_font_cff(cidtogidmap.data)");
gs_free_object(OBJ_MEMORY(font), pdfont0, "pdfi_free_font_cff(pbfont)");
return 0;
diff --git a/pdf/pdf_font1C.h b/pdf/pdf_font1C.h
index e02b63424..ea8c7084f 100644
--- a/pdf/pdf_font1C.h
+++ b/pdf/pdf_font1C.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019-2021 Artifex Software, Inc.
+/* Copyright (C) 2019-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -19,10 +19,11 @@
#define PDF_TYPE1C_FONT
int pdfi_read_type1C_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont);
int pdfi_cff_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph);
-int pdfi_free_font_cff(pdf_obj *font);
int pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *pfbuf, int64_t fbuflen, bool forcecid, pdf_font **ppdffont);
+int pdfi_copy_cff_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont);
+int pdfi_free_font_cff(pdf_obj *font);
int pdfi_free_font_cidtype0(pdf_obj *font);
#endif
diff --git a/pdf/pdf_font3.c b/pdf/pdf_font3.c
index 0ca1431c0..708e7658e 100644
--- a/pdf/pdf_font3.c
+++ b/pdf/pdf_font3.c
@@ -223,6 +223,8 @@ int pdfi_free_font_type3(pdf_obj *font)
pdfi_countdown(t3font->CharProcs);
pdfi_countdown(t3font->Encoding);
pdfi_countdown(t3font->ToUnicode);
+ pdfi_countdown(t3font->filename); /* Should never exist, but just in case */
+
gs_free_object(OBJ_MEMORY(font), font, "Free type 3 font");
return 0;
}
@@ -230,10 +232,9 @@ int pdfi_free_font_type3(pdf_obj *font)
int pdfi_read_type3_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont)
{
- int code = 0, i, num_chars = 0;
+ int code = 0;
pdf_font_type3 *font = NULL;
pdf_obj *obj = NULL;
- double f;
pdf_obj *tounicode = NULL;
*ppdffont = NULL;
@@ -271,67 +272,15 @@ int pdfi_read_type3_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream
if (code < 0)
goto font3_error;
- code = pdfi_dict_get_number(ctx, font_dict, "FirstChar", &f);
- if (code < 0)
- goto font3_error;
- font->FirstChar = (int)f;
- code = pdfi_dict_get_number(ctx, font_dict, "LastChar", &f);
- if (code < 0)
- goto font3_error;
- font->LastChar = (int)f;
-
- num_chars = (font->LastChar - font->FirstChar) + 1;
code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
if (code < 0)
goto font3_error;
- 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 = (double)((pdf_num *) obj)->value.i;
- }
- else if (pdfi_type_of(obj) == PDF_REAL) {
- font->MissingWidth = ((pdf_num *) obj)->value.d;
- }
- else {
- font->MissingWidth = 0;
- }
- pdfi_countdown(obj);
- obj = NULL;
- }
- else {
- font->MissingWidth = 0;
- }
- }
- else {
- font->MissingWidth = 1000;
- }
-
- code = pdfi_dict_knownget_type(ctx, font_dict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
- if (code < 0)
- goto font3_error;
- if (code > 0) {
- if (num_chars != pdfi_array_size((pdf_array *)obj)) {
- code = gs_note_error(gs_error_rangecheck);
- goto font3_error;
- }
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
+ /* ignore errors with widths... for now */
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, 1.0);
- font->Widths = (double *)gs_alloc_bytes(ctx->memory, sizeof(double) * num_chars, "type 3 font Widths array");
- if (font->Widths == NULL) {
- code = gs_note_error(gs_error_VMerror);
- goto font3_error;
- }
- memset(font->Widths, 0x00, sizeof(double) * num_chars);
- for (i = 0; i < num_chars; i++) {
- code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
- if (code < 0)
- goto font3_error;
- }
- }
- pdfi_countdown(obj);
- obj = NULL;
code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj);
if (code < 0)
diff --git a/pdf/pdf_fontTT.c b/pdf/pdf_fontTT.c
index 628c01033..661c182a2 100644
--- a/pdf/pdf_fontTT.c
+++ b/pdf/pdf_fontTT.c
@@ -44,12 +44,12 @@ pdfi_ttf_string_proc(gs_font_type42 * pfont, ulong offset, uint length, const by
pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data;
int code = 0;
- if ((uint64_t)offset + length > ttfont->sfnt.size) {
+ if ((uint64_t)offset + length > ttfont->sfnt->length) {
*pdata = NULL;
code = gs_note_error(gs_error_invalidfont);
}
else {
- *pdata = ttfont->sfnt.data + offset;
+ *pdata = ttfont->sfnt->data + offset;
}
return code;
}
@@ -356,11 +356,10 @@ static int pdfi_set_type42_data_procs(gs_font_type42 *pfont)
int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *buf, int64_t buflen, int findex, pdf_font **ppdffont)
{
pdf_font_truetype *font = NULL;
- int code = 0, num_chars = 0, i;
+ int code = 0, i;
pdf_obj *fontdesc = NULL;
pdf_obj *obj = NULL;
pdf_obj *basefont = NULL;
- double f;
int64_t descflags;
bool encoding_known = false;
bool forced_symbolic = false;
@@ -371,107 +370,63 @@ int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
*ppdffont = NULL;
- (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
+ if (font_dict != NULL)
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc);
if ((code = pdfi_alloc_tt_font(ctx, &font, false)) < 0) {
code = gs_note_error(gs_error_invalidfont);
goto error;
}
- font->object_num = font_dict->object_num;
- font->generation_num = font_dict->generation_num;
- font->indirect_num = font_dict->indirect_num;
- font->indirect_gen = font_dict->indirect_gen;
+ if (font_dict != NULL) {
+ font->object_num = font_dict->object_num;
+ font->generation_num = font_dict->generation_num;
+ font->indirect_num = font_dict->indirect_num;
+ font->indirect_gen = font_dict->indirect_gen;
+ }
font->FontDescriptor = (pdf_dict *)fontdesc;
fontdesc = NULL;
- code = pdfi_dict_get_number(ctx, font_dict, "FirstChar", &f);
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
+
+ code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt);
if (code < 0) {
- f = 0;
- code = 0;
+ goto error;
}
- font->FirstChar = (int)f;
-
- code = pdfi_dict_get_number(ctx, font_dict, "LastChar", &f);
+ pdfi_countup(font->sfnt);
+ code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen);
if (code < 0) {
- f = 255;
- code = 0;
+ goto error;
}
- font->LastChar = (int)f;
-
- num_chars = font->LastChar - font->FirstChar + 1;
-
- font->sfnt.data = buf;
- font->sfnt.size = buflen;
buf = NULL;
/* Strictly speaking BaseFont is required, but we can continue without one */
- code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&basefont);
- if (code > 0) {
- pdf_name *nobj = (pdf_name *)basefont;
- int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
-
- memcpy(font->pfont->key_name.chars, nobj->data, nlen);
- font->pfont->key_name.chars[nlen] = 0;
- font->pfont->key_name.size = nlen;
- memcpy(font->pfont->font_name.chars, nobj->data, nlen);
- font->pfont->font_name.chars[nlen] = 0;
- font->pfont->font_name.size = nlen;
- pdfi_countdown(obj);
- obj = NULL;
- }
- font->BaseFont = basefont;
- basefont = NULL;
- font->PDF_font = font_dict;
- pdfi_countup(font_dict);
-
- if (font->FontDescriptor != NULL) {
- code = pdfi_dict_knownget(ctx, font->FontDescriptor, "MissingWidth", &obj);
+ if (font_dict != NULL) {
+ code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&basefont);
if (code > 0) {
- if (pdfi_type_of(obj) == PDF_INT) {
- font->MissingWidth = ((pdf_num *) obj)->value.i / 1000.0;
- }
- else if (pdfi_type_of(obj) == PDF_REAL) {
- font->MissingWidth = ((pdf_num *) obj)->value.d / 1000.0;
- }
- else {
- font->MissingWidth = 0;
- }
+ pdf_name *nobj = (pdf_name *)basefont;
+ int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length;
+
+ memcpy(font->pfont->key_name.chars, nobj->data, nlen);
+ font->pfont->key_name.chars[nlen] = 0;
+ font->pfont->key_name.size = nlen;
+ memcpy(font->pfont->font_name.chars, nobj->data, nlen);
+ font->pfont->font_name.chars[nlen] = 0;
+ font->pfont->font_name.size = nlen;
pdfi_countdown(obj);
obj = NULL;
}
- else {
- font->MissingWidth = 0;
- }
- }
- else {
- font->MissingWidth = 1.0;
}
+ font->BaseFont = basefont;
+ basefont = NULL;
+ font->PDF_font = font_dict;
+ pdfi_countup(font_dict);
- code = pdfi_dict_knownget_type(ctx, font_dict, "Widths", PDF_ARRAY, (pdf_obj **)&obj);
- if (code > 0) {
- if (num_chars != pdfi_array_size((pdf_array *)obj)) {
- code = gs_note_error(gs_error_rangecheck);
- goto error;
- }
-
- font->Widths = (double *)gs_alloc_bytes(ctx->memory, sizeof(double) * num_chars, "truetype font Widths array");
- if (font->Widths == NULL) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
- memset(font->Widths, 0x00, sizeof(double) * num_chars);
- for (i = 0; i < num_chars; i++) {
- code = pdfi_array_get_number(ctx, (pdf_array *)obj, (uint64_t)i, &font->Widths[i]);
- if (code < 0)
- goto error;
- font->Widths[i] /= 1000.0;
- }
- }
- pdfi_countdown(obj);
- obj = NULL;
+ /* ignore errors with widths... for now */
+ if (font_dict != NULL)
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, 0.001);
- if (ctx->args.ignoretounicode != true) {
+ if (ctx->args.ignoretounicode != true && font_dict != NULL) {
code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode);
if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) {
pdf_cmap *tu = NULL;
@@ -500,7 +455,11 @@ int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
descflags = 0;
}
- code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj);
+ if (font_dict != NULL)
+ code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj);
+ else
+ code = gs_error_undefined;
+
if (code < 0) {
static const char encstr[] = "WinAnsiEncoding";
code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj);
@@ -532,13 +491,6 @@ int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
pdfi_countdown(obj);
obj = NULL;
- font->fake_glyph_names = (gs_string *)gs_alloc_bytes(OBJ_MEMORY(font), font->LastChar * sizeof(gs_string), "pdfi_read_truetype_font: fake_glyph_names");
- if (!font->fake_glyph_names) {
- code = gs_note_error(gs_error_VMerror);
- goto error;
- }
- memset(font->fake_glyph_names, 0x00, font->LastChar * sizeof(gs_string));
-
code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0);
if (code < 0) {
goto error;
@@ -626,7 +578,7 @@ int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *str
goto error;
}
- code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt.data, font->sfnt.size);
+ code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length);
if (code < 0) {
goto error;
}
@@ -648,30 +600,177 @@ error:
return code;
}
+int
+pdfi_copy_truetype_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont)
+{
+ int code = 0;
+ pdf_font_truetype *font = NULL;
+ gs_font_type42 *spfont1 = (gs_font_type42 *) spdffont->pfont;
+ gs_font_type42 *dpfont42;
+ gs_id t_id;
+ pdf_obj *tmp;
+
+ if (font_dict == NULL)
+ return_error(gs_error_invalidfont);
+
+ code = pdfi_alloc_tt_font(ctx, &font, font_dict->object_num);
+ if (code < 0)
+ return code;
+ dpfont42 = (gs_font_type42 *) font->pfont;
+
+ t_id = dpfont42->id;
+ memcpy(dpfont42, spfont1, sizeof(gs_font_type42));
+ dpfont42->id = t_id;
+ dpfont42->FAPI = NULL;
+ dpfont42->FAPI_font_data = NULL;
+ dpfont42->notify_list.memory = NULL;
+ dpfont42->notify_list.first = NULL;
+ gs_notify_init(&dpfont42->notify_list, dpfont42->memory);
+
+ memcpy(font, spdffont, sizeof(pdf_font_truetype));
+ font->refcnt = 1;
+ font->filename = NULL;
+
+ font->pfont = (gs_font_base *)dpfont42;
+ dpfont42->client_data = (void *)font;
+
+ font->PDF_font = font_dict;
+ font->object_num = font_dict->object_num;
+ font->generation_num = font_dict->generation_num;
+ pdfi_countup(font->PDF_font);
+
+ /* We want basefont and descriptor, but we can live without them */
+ font->BaseFont = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont);
+ font->FontDescriptor = NULL;
+ (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor);
+
+ pdfi_countup(font->sfnt);
+
+ if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) {
+ memcpy(dpfont42->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont42->key_name.size = ((pdf_name *)font->BaseFont)->length;
+ memcpy(dpfont42->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length);
+ dpfont42->font_name.size = ((pdf_name *)font->BaseFont)->length;
+ }
+
+ font->Encoding = NULL;
+ font->ToUnicode = NULL;
+ font->Widths = NULL;
+
+ pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font);
+ (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, (double)0.001);
+
+ font->descflags = 0;
+ if (font->FontDescriptor != NULL) {
+ code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags);
+ if (code >= 0) {
+ /* If both the symbolic and non-symbolic flag are set,
+ believe that latter.
+ */
+ if ((font->descflags & 32) != 0)
+ font->descflags = (font->descflags & ~4);
+ }
+ }
+
+ tmp = NULL;
+ code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp);
+ if (code == 1) {
+ if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) {
+ code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) {
+ code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding);
+ if (code >= 0)
+ code = 1;
+ }
+ else
+ code = gs_error_undefined;
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ if (code == 1) {
+ /* Since the underlying font stream can be shared between font descriptors,
+ and the font descriptors can be shared between font objects, if we change
+ the encoding, we can't share cached glyphs with other instances of this
+ underlying font, so invalidate the UniqueID/XUID so the glyph cache won't
+ try.
+ */
+ if (uid_is_XUID(&font->pfont->UID))
+ uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font");
+ uid_set_invalid(&font->pfont->UID);
+ }
+ }
+ else {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
+ }
+
+ if (code <= 0) {
+ font->Encoding = spdffont->Encoding;
+ pdfi_countup(font->Encoding);
+ }
+
+ if (ctx->args.ignoretounicode != true) {
+ code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp);
+ if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) {
+ pdf_cmap *tu = NULL;
+ code = pdfi_read_cmap(ctx, tmp, &tu);
+ pdfi_countdown(tmp);
+ tmp = (pdf_obj *)tu;
+ }
+ if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) {
+ pdfi_countdown(tmp);
+ tmp = NULL;
+ code = 0;
+ }
+ }
+ else {
+ tmp = NULL;
+ }
+ font->ToUnicode = tmp;
+ code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont);
+ if (code < 0) {
+ goto error;
+ }
+
+ code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0);
+ if (code < 0) {
+ goto error;
+ }
+ /* object_num can be zero if the dictionary was defined inline */
+ if (font->object_num != 0) {
+ (void)replace_cache_entry(ctx, (pdf_obj *) font);
+ }
+
+ *tpdffont = (pdf_font *)font;
+
+error:
+ if (code < 0)
+ pdfi_countdown(font);
+ return code;
+}
+
int pdfi_free_font_truetype(pdf_obj *font)
{
pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
- int i;
+
if (ttfont->pfont)
gs_free_object(OBJ_MEMORY(ttfont), ttfont->pfont, "Free TrueType gs_font");
if (ttfont->Widths)
gs_free_object(OBJ_MEMORY(ttfont), ttfont->Widths, "Free TrueType font Widths array");
- if (ttfont->fake_glyph_names != NULL) {
- for (i = 0; i < ttfont->LastChar; i++) {
- if (ttfont->fake_glyph_names[i].data != NULL)
- gs_free_object(OBJ_MEMORY(ttfont), ttfont->fake_glyph_names[i].data, "Free TrueType fake_glyph_name");
- }
- }
- gs_free_object(OBJ_MEMORY(ttfont), ttfont->fake_glyph_names, "Free TrueType fake_glyph_names");
- gs_free_object(OBJ_MEMORY(ttfont), ttfont->sfnt.data, "Free TrueType font sfnt buffer");
-
+ pdfi_countdown(ttfont->sfnt);
pdfi_countdown(ttfont->FontDescriptor);
pdfi_countdown(ttfont->Encoding);
pdfi_countdown(ttfont->BaseFont);
pdfi_countdown(ttfont->PDF_font);
pdfi_countdown(ttfont->ToUnicode);
+ pdfi_countdown(ttfont->filename);
+
gs_free_object(OBJ_MEMORY(ttfont), ttfont, "Free TrueType font");
return 0;
diff --git a/pdf/pdf_fontTT.h b/pdf/pdf_fontTT.h
index 90e4086ea..14932f665 100644
--- a/pdf/pdf_fontTT.h
+++ b/pdf/pdf_fontTT.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2019-2021 Artifex Software, Inc.
+/* Copyright (C) 2019-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -19,6 +19,7 @@
#define PDF_TRUETYPE_FONT
int pdfi_read_truetype_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *buf, int64_t buflen, int findex, pdf_font **ppdffont);
+int pdfi_copy_truetype_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont);
int pdfi_free_font_truetype(pdf_obj *font);
#endif
diff --git a/pdf/pdf_font_types.h b/pdf/pdf_font_types.h
index 7eb28d15b..f29088f59 100644
--- a/pdf/pdf_font_types.h
+++ b/pdf/pdf_font_types.h
@@ -84,8 +84,9 @@ typedef enum pdf_font_type_e {
pdf_dict *PDF_font; /* The original font dictionary from the PDF file */\
pdf_obj *BaseFont; /* Should be a name object, but best allow for strings as well */\
pdf_dict *FontDescriptor; /* For PDF up to 1.4 this may be absent for the base 14 */ \
- int64_t descflags
-
+ int64_t descflags; \
+ pdf_obj *ToUnicode; /* Name or stream (technically should be a stream, but we've seen Identity names */ \
+ pdf_string *filename /* If we read this from disk, this is the file it came from */
#define pdf_font_common \
pdf_font_base;\
@@ -93,10 +94,8 @@ typedef enum pdf_font_type_e {
unsigned int FirstChar; /* For PDF up to 1.4 this may be absent for the base 14 */\
unsigned int LastChar; /* For PDF up to 1.4 this may be absent for the base 14 */\
double MissingWidth; \
- double *Widths; /* For PDF up to 1.4 this may be absent for the base 14 */\
- pdf_array *Encoding; /* Array built from name or dictionary */\
- pdf_obj *ToUnicode; /* Name or stream (technically should be a stream, but we've seen Identity names */ \
- gs_string *fake_glyph_names /* For when we encounter a glyph not in the Encoding */
+ double *Widths; /* For PDF up to 1.4 this may be absent for the base 14 */\
+ pdf_array *Encoding /* Array built from name or dictionary */\
/* The registry and ordering strings in gs_font_cid0_data are just references to
@@ -113,7 +112,7 @@ typedef enum pdf_font_type_e {
pdf_string *registry; \
pdf_string *ordering; \
int supplement; \
- gs_string cidtogidmap; \
+ pdf_buffer *cidtogidmap; \
bool substitute; /* We need to know what a CIDFont is a substitute */ \
font_proc_glyph_info((*orig_glyph_info))
@@ -148,16 +147,14 @@ typedef struct pdf_font_type0_s {
pdf_obj *Encoding; /* CMap */
pdf_array *DescendantFonts; /* A single element array specifying the CIDFont dictionary */
- pdf_obj *ToUnicode; /* Name or stream (technically shoudl be a stream, but we've seen Identity names */
pdfi_cid_decoding_t *decoding; /* Used when substituting a non-Identity CIDFont */
pdfi_cid_subst_nwp_table_t *substnwp; /* Also used for CIDFont substitions */
} pdf_font_type0;
typedef struct pdf_font_type1_s {
pdf_font_common;
- gs_string *Subrs;
+ pdf_array *Subrs;
pdf_dict *CharStrings;
- int NumSubrs;
/* Multiple Master Support - weightvector is stored in gs_font_type1 */
pdf_array *blenddesignpositions;
pdf_array *blenddesignmap;
@@ -172,11 +169,6 @@ typedef struct pdf_font_cff_s {
pdf_array *GlobalSubrs;
int NumGlobalSubrs;
pdf_dict *CharStrings;
- byte *cffdata;
- byte *cffend;
- byte *gsubrs;
- byte *subrs;
- byte *charstrings;
int ncharstrings;
} pdf_font_cff;
@@ -198,7 +190,7 @@ typedef enum {
typedef struct pdf_font_truetype_s {
pdf_font_common;
- gs_string sfnt;
+ pdf_buffer *sfnt;
pdfi_truetype_cmap cmap;
} pdf_font_truetype;
@@ -213,11 +205,6 @@ typedef struct pdf_cidfont_type0_s {
pdf_array *GlobalSubrs;
int NumGlobalSubrs;
pdf_dict *CharStrings;
- byte *cffdata;
- byte *cffend;
- byte *gsubrs;
- byte *subrs;
- byte *charstrings;
int ncharstrings;
pdf_array *FDArray;
int cidcount;
@@ -226,7 +213,7 @@ typedef struct pdf_cidfont_type0_s {
typedef struct pdf_cidfont_type2_s {
pdf_cid_font_common;
- gs_string sfnt;
+ pdf_buffer *sfnt;
} pdf_cidfont_type2;
#endif
diff --git a/pdf/pdf_fontps.c b/pdf/pdf_fontps.c
index 45ae23bd6..c7488c2e4 100644
--- a/pdf/pdf_fontps.c
+++ b/pdf/pdf_fontps.c
@@ -1045,21 +1045,14 @@ ps_font_array_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
!memcmp(s->cur[-1].val.name, PDF_PS_OPER_NAME_AND_LEN("Subrs"))) {
if (s->cur[0].val.i > 0) {
- if (priv->u.t1.Subrs != NULL) {
- int i;
- for (i = 0; i < priv->u.t1.NumSubrs; i++) {
- gs_free_object(mem, priv->u.t1.Subrs[i].data, "ps_font_array_func(Subrs[i])");
- }
- gs_free_object(mem, priv->u.t1.Subrs, "ps_font_array_func(Subrs)");
- }
+ pdfi_countdown(priv->u.t1.Subrs);
- priv->u.t1.Subrs = (gs_string *) gs_alloc_bytes(mem, s->cur[0].val.i *sizeof(gs_string), "ps_font_array_func(Subrs)");
- if (priv->u.t1.Subrs == NULL) {
- return_error(gs_error_VMerror);
+ pdfi_object_alloc(s->pdfi_ctx, PDF_ARRAY, (unsigned int)s->cur[0].val.i, (pdf_obj **)&priv->u.t1.Subrs);
+ if (code < 0) {
+ return code;
}
- memset(priv->u.t1.Subrs, 0x00, s->cur[0].val.i * sizeof(gs_string));
+ pdfi_countup(priv->u.t1.Subrs);
}
- priv->u.t1.NumSubrs = s->cur[0].val.i;
code = pdf_ps_stack_pop(s, 1);
}
else if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME) &&
@@ -1162,14 +1155,19 @@ pdf_ps_RD_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend)
size = s->cur[0].val.i;
buf++;
if (buf + size < bufend) {
- priv->u.t1.Subrs[inx].data =
- gs_alloc_bytes(mem, size, "pdf_ps_RD_oper_func(subr string)");
- if (priv->u.t1.Subrs[inx].data == NULL) {
- (void)pdf_ps_stack_pop(s, 2);
- return_error(gs_error_VMerror);
+ pdf_string *subr_str;
+
+ code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)size, (pdf_obj **)&subr_str);
+ if (code < 0) {
+ return code;
+ }
+ memcpy(subr_str->data, buf, size);
+ pdfi_countup(subr_str);
+ code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.Subrs, inx, (pdf_obj *)subr_str);
+ if (code < 0) {
+ pdfi_countdown(subr_str);
+ return code;
}
- memcpy(priv->u.t1.Subrs[inx].data, buf, size);
- priv->u.t1.Subrs[inx].size = size;
}
}
}
diff --git a/pdf/pdf_obj.c b/pdf/pdf_obj.c
index a0607ebb1..aae9401bf 100644
--- a/pdf/pdf_obj.c
+++ b/pdf/pdf_obj.c
@@ -36,6 +36,7 @@
int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pdf_obj **obj)
{
int bytes = 0;
+ int code = 0;
switch(type) {
case PDF_ARRAY_MARK:
@@ -51,6 +52,9 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
case PDF_NAME:
bytes = sizeof(pdf_string) + size - PDF_NAME_DECLARED_LENGTH;
break;
+ case PDF_BUFFER:
+ bytes = sizeof(pdf_buffer);
+ break;
case PDF_ARRAY:
bytes = sizeof(pdf_array);
break;
@@ -75,11 +79,14 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
case PDF_NULL:
case PDF_BOOL:
default:
- return_error(gs_error_typecheck);
+ code = gs_note_error(gs_error_typecheck);
+ goto error_out;
}
*obj = (pdf_obj *)gs_alloc_bytes(ctx->memory, bytes, "pdfi_object_alloc");
- if (*obj == NULL)
- return_error(gs_error_VMerror);
+ if (*obj == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error_out;
+ }
memset(*obj, 0x00, bytes);
(*obj)->ctx = ctx;
@@ -106,6 +113,24 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
case PDF_NAME:
((pdf_string *)*obj)->length = size;
break;
+ case PDF_BUFFER:
+ {
+ pdf_buffer *b = (pdf_buffer *)*obj;
+ /* NOTE: size can be 0 if the caller wants to allocate the data area itself
+ */
+ if (size > 0) {
+ b->data = gs_alloc_bytes(ctx->memory, size, "pdfi_object_alloc");
+ if (b->data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error_out;
+ }
+ }
+ else {
+ b->data = NULL;
+ }
+ b->length = size;
+ }
+ break;
case PDF_ARRAY:
{
pdf_obj **values = NULL;
@@ -114,10 +139,8 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
if (size > 0) {
values = (pdf_obj **)gs_alloc_bytes(ctx->memory, size * sizeof(pdf_obj *), "pdfi_object_alloc");
if (values == NULL) {
- gs_free_object(ctx->memory, *obj, "pdfi_object_alloc");
- gs_free_object(ctx->memory, values, "pdfi_object_alloc");
- *obj = NULL;
- return_error(gs_error_VMerror);
+ code = gs_note_error(gs_error_VMerror);
+ goto error_out;
}
((pdf_array *)*obj)->values = values;
memset(((pdf_array *)*obj)->values, 0x00, size * sizeof(pdf_obj *));
@@ -132,9 +155,8 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
if (size > 0) {
entries = (pdf_dict_entry *)gs_alloc_bytes(ctx->memory, size * sizeof(pdf_dict_entry), "pdfi_object_alloc");
if (entries == NULL) {
- gs_free_object(ctx->memory, *obj, "pdfi_object_alloc");
- *obj = NULL;
- return_error(gs_error_VMerror);
+ code = gs_note_error(gs_error_VMerror);
+ goto error_out;
}
((pdf_dict *)*obj)->list = entries;
memset(((pdf_dict *)*obj)->list, 0x00, size * sizeof(pdf_dict_entry));
@@ -154,6 +176,10 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd
dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", (*obj)->type, (*obj)->UID);
#endif
return 0;
+error_out:
+ gs_free_object(ctx->memory, *obj, "pdfi_object_alloc");
+ *obj = NULL;
+ return code;
}
/* Create a PDF number object from a numeric value. Attempts to create
@@ -221,6 +247,14 @@ static void pdfi_free_stream(pdf_obj *o)
gs_free_object(OBJ_MEMORY(o), o, "pdfi_free_stream");
}
+static void pdfi_free_buffer(pdf_obj *o)
+{
+ pdf_buffer *b = (pdf_buffer *)o;
+
+ gs_free_object(OBJ_MEMORY(b), b->data, "pdfi_free_buffer(data)");
+ gs_free_object(OBJ_MEMORY(o), o, "pdfi_free_buffer");
+}
+
void pdfi_free_object(pdf_obj *o)
{
if (o == NULL)
@@ -240,6 +274,9 @@ void pdfi_free_object(pdf_obj *o)
case PDF_NAME:
pdfi_free_namestring(o);
break;
+ case PDF_BUFFER:
+ pdfi_free_buffer(o);
+ break;
case PDF_ARRAY:
pdfi_free_array(o);
break;
diff --git a/pdf/pdf_obj.h b/pdf/pdf_obj.h
index f058a872b..eb512db96 100644
--- a/pdf/pdf_obj.h
+++ b/pdf/pdf_obj.h
@@ -93,4 +93,22 @@ pdfi_obj_to_int(pdf_context *ctx, pdf_obj *obj, int64_t *i)
return 0;
}
+/* NOTE: the buffer object takes ownership of "data" */
+static inline int
+pdfi_buffer_set_data(pdf_obj *o, byte *data, int32_t length)
+{
+ pdf_buffer *b = (pdf_buffer *)o;
+ if (pdfi_type_of(b) != PDF_BUFFER) {
+ return_error(gs_error_typecheck);
+ }
+
+ if (b->data) {
+ gs_free_object(OBJ_MEMORY(b), b->data, "pdfi_buffer_set_data(data)");
+ }
+ b->data = data;
+ b->length = length;
+ return 0;
+}
+
+
#endif
diff --git a/pdf/pdf_types.h b/pdf/pdf_types.h
index 6528be7ff..6f78dde7f 100644
--- a/pdf/pdf_types.h
+++ b/pdf/pdf_types.h
@@ -58,6 +58,7 @@ typedef enum pdf_obj_type_e {
PDF_DICT_MARK = '<',
PDF_PROC_MARK = '{',
PDF_CMAP = 'C',
+ PDF_BUFFER = 'B',
/* Lastly, for the benefit of duplicate colour space identification, we store either
* a name for a colour space, or if there is no name, the context (we can get the
* context from the name object if there is one). We need to be able to tell if a
@@ -137,6 +138,16 @@ typedef struct pdf_name_s {
unsigned char data[PDF_NAME_DECLARED_LENGTH];
} pdf_name;
+/* For storing arbitrary byte arrays where the length may be
+ greater than PDF_NAME_DECLARED_LENGTH - prevents static
+ alalysis tools complaining if we just used pdf_string
+ */
+typedef struct pdf_buffer_s {
+ pdf_obj_common;
+ uint32_t length;
+ unsigned char *data;
+} pdf_buffer;
+
typedef enum pdf_key_e {
#include "pdf_tokens.h"
TOKEN__LAST_KEY,