From 16c09856508abbf059ed94b9234b28143025318b Mon Sep 17 00:00:00 2001 From: Jonathan Scruggs Date: Wed, 24 Jan 2018 10:09:02 +0000 Subject: [PATCH 1/4] Included necessary char widths in generated PDF * /W and /CIDToGIDMap can be created in the before_write_fn * Only add width for actually used glyphs to the /W array * Try reducing the size of the /CIDToGIDMap. Only care about actually used glyphs, so that a) the length of the array can be reduced, b) unused entries can be easily compressed as they are zeroed out. --- src/hpdf_font_cid.c | 139 ++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/src/hpdf_font_cid.c b/src/hpdf_font_cid.c index d1c1a82..5ab3b28 100644 --- a/src/hpdf_font_cid.c +++ b/src/hpdf_font_cid.c @@ -346,19 +346,14 @@ CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref) HPDF_STATUS ret = HPDF_OK; HPDF_FontAttr attr = (HPDF_FontAttr)parent->attr; HPDF_FontDef fontdef = attr->fontdef; - HPDF_TTFontDefAttr fontdef_attr = (HPDF_TTFontDefAttr)fontdef->attr; HPDF_Encoder encoder = attr->encoder; HPDF_CMapEncoderAttr encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_Font font; HPDF_Array array; - HPDF_UINT i; - HPDF_UNICODE tmp_map[65536]; HPDF_Dict cid_system_info; - HPDF_UINT16 max = 0; - HPDF_PTRACE ((" HPDF_CIDFontType2_New\n")); font = HPDF_Dict_New (parent->mmgr); @@ -388,11 +383,55 @@ CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref) ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.bottom - fontdef->font_bbox.top)); - HPDF_MemSet (tmp_map, 0, sizeof(HPDF_UNICODE) * 65536); + /* create CIDSystemInfo dictionary */ + cid_system_info = HPDF_Dict_New (parent->mmgr); + if (!cid_system_info) + return NULL; + + if (HPDF_Dict_Add (font, "CIDSystemInfo", cid_system_info) != HPDF_OK) + return NULL; + + ret += HPDF_Dict_Add (cid_system_info, "Registry", + HPDF_String_New (parent->mmgr, encoder_attr->registry, NULL)); + ret += HPDF_Dict_Add (cid_system_info, "Ordering", + HPDF_String_New (parent->mmgr, encoder_attr->ordering, NULL)); + ret += HPDF_Dict_AddNumber (cid_system_info, "Supplement", + encoder_attr->suppliment); if (ret != HPDF_OK) return NULL; + return font; +} + + +static HPDF_STATUS +CIDFontType2_BeforeWrite_Func (HPDF_Dict obj) +{ + HPDF_FontAttr font_attr = (HPDF_FontAttr)obj->attr; + HPDF_FontDef def = font_attr->fontdef; + HPDF_TTFontDefAttr def_attr = (HPDF_TTFontDefAttr)def->attr; + HPDF_STATUS ret = 0; + + HPDF_Font font; + HPDF_Encoder encoder = font_attr->encoder; + HPDF_CMapEncoderAttr encoder_attr = + (HPDF_CMapEncoderAttr)encoder->attr; + + HPDF_Array array; + HPDF_UINT i; + HPDF_UNICODE tmp_map[65536]; + HPDF_UINT16 max = 0; + + + HPDF_PTRACE ((" CIDFontType2_BeforeWrite_Func\n")); + + font = font_attr->descendant_font; + HPDF_MemSet (tmp_map, 0, sizeof(HPDF_UNICODE) * 65536); + + if (ret != HPDF_OK) + return ret; + for (i = 0; i < 256; i++) { HPDF_UINT j; @@ -401,66 +440,70 @@ CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref) HPDF_UINT16 cid = encoder_attr->cid_map[i][j]; if (cid != 0) { HPDF_UNICODE unicode = encoder_attr->unicode_map[i][j]; - HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, + HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (def, unicode); - tmp_map[cid] = gid; - if (max < cid) - max = cid; + if (def_attr->glyph_tbl.flgs[gid]) { + tmp_map[cid] = gid; + if (max < cid) + max = cid; + } } } else { HPDF_UNICODE unicode = (i << 8) | j; - HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, + HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (def, unicode); - tmp_map[unicode] = gid; - if (max < unicode) - max = unicode; + if (def_attr->glyph_tbl.flgs[gid]) { + tmp_map[unicode] = gid; + if (max < unicode) + max = unicode; + } } } } if (max > 0) { - HPDF_INT16 dw = fontdef->missing_width; + HPDF_INT16 dw = def->missing_width; HPDF_UNICODE *ptmp_map = tmp_map; HPDF_Array tmp_array = NULL; /* add 'W' element */ array = HPDF_Array_New (font->mmgr); if (!array) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; if (HPDF_Dict_Add (font, "W", array) != HPDF_OK) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; for (i = 0; i < max; i++, ptmp_map++) { - HPDF_INT w = HPDF_TTFontDef_GetGidWidth (fontdef, *ptmp_map); + HPDF_INT w = HPDF_TTFontDef_GetGidWidth (def, *ptmp_map); - if (w != dw) { + if (def_attr->glyph_tbl.flgs[*ptmp_map] && w != dw) { if (!tmp_array) { if (HPDF_Array_AddNumber (array, i) != HPDF_OK) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; tmp_array = HPDF_Array_New (font->mmgr); if (!tmp_array) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; if (HPDF_Array_Add (array, tmp_array) != HPDF_OK) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; } if ((ret = HPDF_Array_AddNumber (tmp_array, w)) != HPDF_OK) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; } else tmp_array = NULL; } /* create "CIDToGIDMap" data */ - if (fontdef_attr->embedding) { - attr->map_stream = HPDF_DictStream_New (font->mmgr, xref); - if (!attr->map_stream) - return NULL; + if (def_attr->embedding) { + font_attr->map_stream = HPDF_DictStream_New (font->mmgr, font_attr->xref); + if (!font_attr->map_stream) + return HPDF_FAILD_TO_ALLOC_MEM; - if (HPDF_Dict_Add (font, "CIDToGIDMap", attr->map_stream) != HPDF_OK) - return NULL; + if (HPDF_Dict_Add (font, "CIDToGIDMap", font_attr->map_stream) != HPDF_OK) + return HPDF_FAILD_TO_ALLOC_MEM; for (i = 0; i < max; i++) { HPDF_BYTE u[2]; @@ -472,47 +515,15 @@ CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref) HPDF_MemCpy ((HPDF_BYTE *)(tmp_map + i), u, 2); } - if ((ret = HPDF_Stream_Write (attr->map_stream->stream, + if ((ret = HPDF_Stream_Write (font_attr->map_stream->stream, (HPDF_BYTE *)tmp_map, max * 2)) != HPDF_OK) - return NULL; + return HPDF_FAILD_TO_ALLOC_MEM; } } else { HPDF_SetError (font->error, HPDF_INVALID_FONTDEF_DATA, 0); - return 0; + return HPDF_INVALID_FONTDEF_DATA; } - /* create CIDSystemInfo dictionary */ - cid_system_info = HPDF_Dict_New (parent->mmgr); - if (!cid_system_info) - return NULL; - - if (HPDF_Dict_Add (font, "CIDSystemInfo", cid_system_info) != HPDF_OK) - return NULL; - - ret += HPDF_Dict_Add (cid_system_info, "Registry", - HPDF_String_New (parent->mmgr, encoder_attr->registry, NULL)); - ret += HPDF_Dict_Add (cid_system_info, "Ordering", - HPDF_String_New (parent->mmgr, encoder_attr->ordering, NULL)); - ret += HPDF_Dict_AddNumber (cid_system_info, "Supplement", - encoder_attr->suppliment); - - if (ret != HPDF_OK) - return NULL; - - return font; -} - - -static HPDF_STATUS -CIDFontType2_BeforeWrite_Func (HPDF_Dict obj) -{ - HPDF_FontAttr font_attr = (HPDF_FontAttr)obj->attr; - HPDF_FontDef def = font_attr->fontdef; - HPDF_TTFontDefAttr def_attr = (HPDF_TTFontDefAttr)def->attr; - HPDF_STATUS ret = 0; - - HPDF_PTRACE ((" CIDFontType2_BeforeWrite_Func\n")); - if (font_attr->map_stream) font_attr->map_stream->filter = obj->filter; -- 2.16.0