summaryrefslogtreecommitdiff
path: root/pdf/pdf_font1.c
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2022-08-01 15:24:28 +0100
committerChris Liddell <chris.liddell@artifex.com>2022-08-04 10:58:31 +0100
commit08e545978236b4b8b941c7073214cab87f73a78b (patch)
tree186cd49d2ea130c2829600beeb3e7ff07b83b214 /pdf/pdf_font1.c
parent56c1f0cd5cee10e389438667a5902c58a4b4eb17 (diff)
downloadghostpdl-08e545978236b4b8b941c7073214cab87f73a78b.tar.gz
Bug 705650: Use "fake" unique XUIDs for fonts
pdfwrite's heuristics for judging whether different font objects represent the same font, or font subsets that are compatible, were being defeated by the way pdfi (re)loads and (re)creates font objects. This works around that by forcibly generating a "private" fake XUID combining a hash of the input file name, object number of font dictionary object and, when we're feeding a high level device, the gs_id for the font object - the final one ensuring the XUID is unique to the font object, For non-high level devices, the XUID doesn't include the gs_id, meaning font objects derived from the same PDF object number will share the XUID, improving glyph cache efficiency. Multiple font objects coming from the same PDF object can happen if the font object gets flushed from the object cache, and then later used again.
Diffstat (limited to 'pdf/pdf_font1.c')
-rw-r--r--pdf/pdf_font1.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/pdf/pdf_font1.c b/pdf/pdf_font1.c
index aa0c9ac07..eec20d5a1 100644
--- a/pdf/pdf_font1.c
+++ b/pdf/pdf_font1.c
@@ -139,13 +139,13 @@ pdfi_t1_subr_data(gs_font_type1 *pfont, int index, bool global, gs_glyph_data_t
code = gs_note_error(gs_error_rangecheck);
}
else {
- pdf_string *subr_str;
+ pdf_string *subr_str = NULL;
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);
}
+ /* decrementing is safe here, because the reference in the pdffont1->Subrs will persist */
+ pdfi_countdown(subr_str);
}
return code;
}
@@ -657,15 +657,6 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
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(&t1f->pfont->UID))
- uid_free(&t1f->pfont->UID, t1f->pfont->memory, "pdfi_read_type1_font");
- uid_set_invalid(&t1f->pfont->UID);
}
}
else {
@@ -678,6 +669,15 @@ pdfi_read_type1_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dic
t1f->Encoding = fpriv.u.t1.Encoding;
pdfi_countup(t1f->Encoding);
}
+ /* 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(&t1f->pfont->UID))
+ uid_free(&t1f->pfont->UID, t1f->pfont->memory, "pdfi_read_type1_font");
+ uid_set_invalid(&t1f->pfont->UID);
t1f->CharStrings = fpriv.u.t1.CharStrings;
pdfi_countup(t1f->CharStrings);
@@ -686,6 +686,11 @@ 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;
+ code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, t1f->pfont);
+ if (code < 0) {
+ goto error;
+ }
+
t1f->blenddesignpositions = fpriv.u.t1.blenddesignpositions;
pdfi_countup(t1f->blenddesignpositions);
t1f->blenddesignmap = fpriv.u.t1.blenddesignmap;
@@ -835,17 +840,6 @@ pdfi_copy_type1_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict,
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);
@@ -858,6 +852,18 @@ pdfi_copy_type1_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict,
pdfi_countup(font->Encoding);
}
+ /* Since various aspects of the font may differ (widths, encoding, etc)
+ we cannot reliably use the UniqueID/XUID for copied fonts.
+ */
+ 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);
+
+ code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont);
+ if (code < 0) {
+ goto error;
+ }
+
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) {