diff options
Diffstat (limited to 'pdf/pdf_font1C.c')
-rw-r--r-- | pdf/pdf_font1C.c | 434 |
1 files changed, 301 insertions, 133 deletions
diff --git a/pdf/pdf_font1C.c b/pdf/pdf_font1C.c index f4788845..43ebced3 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 @@ -145,6 +145,9 @@ pdfi_cff_glyph_data(gs_font_type1 *pfont, gs_glyph glyph, gs_glyph_data_t *pgd) } if (code >= 0) { code = pdfi_dict_get_by_key(ctx, cfffont->CharStrings, glyphname, (pdf_obj **) &charstring); + if (code < 0) { + code = pdfi_map_glyph_name_via_agl(cfffont->CharStrings, glyphname, &charstring); + } if (code >= 0) gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); } @@ -205,11 +208,13 @@ pdfi_cff_seac_data(gs_font_type1 *pfont, int ccode, gs_glyph *pglyph, gs_const_s pdfi_countup(glyphname); code = pdfi_dict_get_by_key(ctx, cfffont->CharStrings, glyphname, (pdf_obj **)&charstring); pdfi_countdown(glyphname); - if (code >= 0) - if (pgd != NULL) + if (code >= 0) { + if (pgd != NULL) { gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); + } pdfi_countdown(charstring); } + } } return code; @@ -272,8 +277,13 @@ pdfi_cff_enumerate_glyph(gs_font *pfont, int *pindex, else if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->Encoding != NULL) { unsigned int nindex; code = (*ctx->get_glyph_index)(pfont, key->data, key->length, &nindex); - if (code < 0) - *pglyph = GS_NO_GLYPH; + if (code < 0) { + code = (*ctx->get_glyph_index)(pfont, (byte *)".notdef", 7, &nindex); + if (code < 0) + *pglyph = GS_NO_GLYPH; + else + *pglyph = (gs_glyph)nindex; + } else *pglyph = (gs_glyph)nindex; } @@ -296,9 +306,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; } @@ -427,8 +437,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); @@ -814,7 +824,8 @@ pdfi_read_cff_dict(byte *p, byte *e, pdfi_gs_cff_font_priv *ptpriv, cff_font_off n = 0; while (p < e && code >= 0) { - b0 = *p++; + b0 = *p; + p++; switch (b0) { case 22: @@ -946,9 +957,10 @@ pdfi_read_cff_dict(byte *p, byte *e, pdfi_gs_cff_font_priv *ptpriv, cff_font_off code = pdfi_make_string_from_sid(font->ctx, (pdf_obj **) &fnamestr, font, offsets, args[0].ival); if (code >= 0) { - memcpy(ptpriv->font_name.chars, fnamestr->data, fnamestr->length); - memcpy(ptpriv->key_name.chars, fnamestr->data, fnamestr->length); - ptpriv->font_name.size = ptpriv->key_name.size = fnamestr->length; + int nlen = fnamestr->length > gs_font_name_max ? gs_font_name_max : fnamestr->length; + memcpy(ptpriv->font_name.chars, fnamestr->data, nlen); + memcpy(ptpriv->key_name.chars, fnamestr->data, nlen); + ptpriv->font_name.size = ptpriv->key_name.size = nlen; pdfi_countdown(fnamestr); } break; @@ -1698,7 +1710,6 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) font->GlobalSubrs->refcnt = 1; for (i = 0; i < font->NumGlobalSubrs; i++) { pdf_string *gsubrstr; - pdf_obj *nullobj = NULL; p = pdfi_find_cff_index(font->gsubrs, font->cffend, i, &strp, &stre); if (p) { @@ -1715,11 +1726,7 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) } } else { - code = 0; - if (nullobj == NULL) - code = pdfi_object_alloc(ctx, PDF_NULL, 1, (pdf_obj **) &nullobj); - if (code >= 0) - code = pdfi_array_put(ctx, font->GlobalSubrs, (uint64_t) i, (pdf_obj *) nullobj); + code = pdfi_array_put(ctx, font->GlobalSubrs, (uint64_t) i, PDF_NULL_OBJ); if (code < 0) { pdfi_countdown(font->GlobalSubrs); font->GlobalSubrs = NULL; @@ -1736,7 +1743,6 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) font->Subrs->refcnt = 1; for (i = 0; i < font->NumSubrs; i++) { pdf_string *subrstr; - pdf_obj *nullobj = NULL; p = pdfi_find_cff_index(font->subrs, font->cffend, i, &strp, &stre); if (p) { @@ -1751,11 +1757,7 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) } } else { - code = 0; - if (nullobj == NULL) - code = pdfi_object_alloc(ctx, PDF_NULL, 1, (pdf_obj **) &nullobj); - if (code >= 0) - code = pdfi_array_put(ctx, font->Subrs, (uint64_t) i, (pdf_obj *) nullobj); + code = pdfi_array_put(ctx, font->Subrs, (uint64_t) i, PDF_NULL_OBJ); if (code < 0) { pdfi_countdown(font->Subrs); font->Subrs = NULL; @@ -1838,7 +1840,7 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) pdf_font_cff *pdffont = NULL; gs_font_type1 *pt1font; - pdfi_init_cff_font_priv(ctx, &fdptpriv, font->cffdata, (font->cffend - font->cffdata) + 1, true); + pdfi_init_cff_font_priv(ctx, &fdptpriv, font->cffdata, (font->cffend - font->cffdata), true); offsets.private_off = 0; @@ -1879,9 +1881,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; @@ -1897,7 +1898,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) { @@ -1975,7 +1976,7 @@ pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) if (g > maxcid) maxcid = g; gs_snprintf(gkey, sizeof(gkey), "%d", g); - code = pdfi_dict_put(ctx, font->CharStrings, gkey, (pdf_obj *) charstr); + code = pdfi_dict_put_unchecked(ctx, font->CharStrings, gkey, (pdf_obj *) charstr); } if (maxcid > ptpriv->pdfcffpriv.cidcount - 1) ptpriv->pdfcffpriv.cidcount = maxcid + 1; @@ -2270,8 +2271,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; } @@ -2335,7 +2341,7 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, cffpriv.pdfcffpriv.ordering = NULL; } code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl); - if (code <= 0 || suppl->type != PDF_INT) { + if (code <= 0 || pdfi_type_of(suppl) != PDF_INT) { cffcid->supplement = cffpriv.pdfcffpriv.supplement; } else { @@ -2358,9 +2364,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; @@ -2384,23 +2387,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 (obj->type == PDF_STREAM) { - code = pdfi_stream_to_buffer(ctx, (pdf_stream *) obj, &(cffcid->cidtogidmap.data), &size); + if (pdfi_type_of(obj) == PDF_STREAM) { + 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; @@ -2438,10 +2453,10 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, else { cffcid->W2 = NULL; } - code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, (gs_font_base *)cffcid->pfont); - if (code < 0) - uid_set_invalid(&cffcid->pfont->UID); - + if (uid_is_XUID(&cffcid->pfont->UID)) + uid_free(&cffcid->pfont->UID, cffcid->pfont->memory, "pdfi_read_type1_font"); + uid_set_invalid(&cffcid->pfont->UID); + cffcid->pfont->id = gs_next_ids(ctx->memory, 1); } else if (forcecid) { pdf_obj *obj; @@ -2581,22 +2596,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 (obj->type == PDF_STREAM) { - code = pdfi_stream_to_buffer(ctx, (pdf_stream *) obj, &(cffcid->cidtogidmap.data), (int64_t *) &size); + if (pdfi_type_of(obj) == PDF_STREAM) { + 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; @@ -2635,17 +2662,17 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, cffcid->W2 = NULL; } - code = pdfi_font_generate_pseudo_XUID(ctx, cffcid->PDF_font, ppdfont->pfont); - if (code < 0) - goto error; - + if (uid_is_XUID(&cffcid->pfont->UID)) + uid_free(&cffcid->pfont->UID, cffcid->pfont->memory, "pdfi_read_type1_font"); + uid_set_invalid(&cffcid->pfont->UID); + cffcid->pfont->id = gs_next_ids(ctx->memory, 1); } else { pdf_font_cff *cfffont; gs_font_type1 *pfont = NULL; pdf_obj *tounicode = NULL; - 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; @@ -2657,12 +2684,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); @@ -2700,69 +2730,23 @@ 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; - } + pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)cfffont); - 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)); - code = pdfi_dict_knownget_type(ctx, font_dict, "Widths", PDF_ARRAY, &tmp); - if (code > 0) { - int i; - double x_scale; - 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); - - /* 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); - - 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; - } + /* 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 + */ + 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 && tmp->type == PDF_DICT) { + 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); if (code >= 0) { pdfi_countdown(cffpriv.pdfcffpriv.Encoding); @@ -2770,7 +2754,7 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, code = 1; } } - else if ((tmp->type == PDF_NAME || tmp->type == PDF_DICT)) { + else if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT)) { code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) &cfffont->Encoding); if (code >= 0) { pdfi_countdown(cffpriv.pdfcffpriv.Encoding); @@ -2780,6 +2764,9 @@ pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, } else code = gs_error_undefined; + + if (code == 1) { + } pdfi_countdown(tmp); tmp = NULL; } @@ -2792,15 +2779,27 @@ 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) { + + /* 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(&cfffont->pfont->UID)) + uid_free(&cfffont->pfont->UID, cfffont->pfont->memory, "pdfi_read_type1_font"); + uid_set_invalid(&cfffont->pfont->UID); + cfffont->pfont->id = gs_next_ids(ctx->memory, 1); + + if (ctx->args.ignoretounicode != true && font_dict != NULL) { code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode); - if (code >= 0 && tounicode->type == PDF_STREAM) { + if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) { pdf_cmap *tu = NULL; code = pdfi_read_cmap(ctx, tounicode, &tu); pdfi_countdown(tounicode); tounicode = (pdf_obj *)tu; } - if (code < 0 || (tounicode != NULL && tounicode->type != PDF_CMAP)) { + if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) { pdfi_countdown(tounicode); tounicode = NULL; code = 0; @@ -2831,6 +2830,11 @@ error: } } else { + code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, ppdfont->pfont); + if (code < 0) { + goto error; + } + code = gs_definefont(ctx->font_dir, (gs_font *) ppdfont->pfont); if (code >= 0) @@ -2840,6 +2844,7 @@ error: if (code >= 0 && ppdfont->object_num != 0) { (void)replace_cache_entry(ctx, (pdf_obj *) ppdfont); } + if (code >= 0) { *ppdffont = (pdf_font *) ppdfont; ppdfont = NULL; @@ -2898,6 +2903,168 @@ 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; + } + else { + pdfi_countdown(tmp); + tmp = NULL; + code = 0; + } + + if (code <= 0) { + font->Encoding = spdffont->Encoding; + 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) { + 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; @@ -2913,8 +3080,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)"); @@ -2948,8 +3115,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; |