/src/ghostpdl/pdf/pdf_fontTT.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2019-2025 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* code for TrueType font handling */ |
17 | | |
18 | | #include "pdf_int.h" |
19 | | #include "pdf_font.h" |
20 | | #include "pdf_fontTT.h" |
21 | | #include "pdf_font1C.h" /* OTTO support */ |
22 | | #include "pdf_font_types.h" |
23 | | #include "pdf_stack.h" |
24 | | #include "pdf_file.h" |
25 | | #include "pdf_dict.h" |
26 | | #include "pdf_array.h" |
27 | | #include "pdf_deref.h" |
28 | | #include "gxfont42.h" |
29 | | #include "gscencs.h" |
30 | | #include "gsagl.h" |
31 | | #include "gsutil.h" /* For gs_next_ids() */ |
32 | | |
33 | | enum { |
34 | | CMAP_TABLE_NONE = 0, |
35 | | CMAP_TABLE_10_PRESENT = 1, |
36 | | CMAP_TABLE_30_PRESENT = 2, |
37 | | CMAP_TABLE_31_PRESENT = 4, |
38 | | CMAP_TABLE_310_PRESENT = 8 |
39 | | }; |
40 | | |
41 | | static int |
42 | | pdfi_ttf_string_proc(gs_font_type42 * pfont, ulong offset, uint length, const byte ** pdata) |
43 | 1.91G | { |
44 | 1.91G | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
45 | 1.91G | int code = 0; |
46 | | |
47 | 1.91G | if ((uint64_t)offset + length > ttfont->sfnt->length) { |
48 | 12.2M | *pdata = NULL; |
49 | 12.2M | code = gs_note_error(gs_error_invalidfont); |
50 | 12.2M | } |
51 | 1.89G | else { |
52 | 1.89G | *pdata = ttfont->sfnt->data + offset; |
53 | 1.89G | } |
54 | 1.91G | return code; |
55 | 1.91G | } |
56 | | |
57 | | static gs_glyph pdfi_ttf_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t sp) |
58 | 11.2M | { |
59 | 11.2M | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
60 | 11.2M | gs_glyph g = GS_NO_GLYPH; |
61 | 11.2M | uint ID; |
62 | 11.2M | int code; |
63 | | |
64 | 11.2M | if ((ttfont->descflags & 4) != 0 || sp == GLYPH_SPACE_INDEX) { |
65 | 3.85M | int code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)chr, &ID); |
66 | 3.85M | if (code < 0 || ID == 0) |
67 | 1.44M | code = pdfi_fapi_check_cmap_for_GID(pfont, (uint)(chr | 0xf0 << 8), &ID); |
68 | 3.85M | g = (gs_glyph)ID; |
69 | 3.85M | } |
70 | 7.36M | else { |
71 | 7.36M | pdf_context *ctx = (pdf_context *)ttfont->ctx; |
72 | | |
73 | 7.36M | if (ttfont->Encoding != NULL) { /* safety */ |
74 | 7.36M | pdf_name *GlyphName = NULL; |
75 | 7.36M | code = pdfi_array_get(ctx, ttfont->Encoding, (uint64_t)chr, (pdf_obj **)&GlyphName); |
76 | 7.36M | if (code >= 0) { |
77 | 7.35M | code = (*ctx->get_glyph_index)(pfont, (byte *)GlyphName->data, GlyphName->length, &ID); |
78 | 7.35M | pdfi_countdown(GlyphName); |
79 | 7.35M | if (code >= 0) |
80 | 7.35M | g = (gs_glyph)ID; |
81 | 7.35M | } |
82 | 7.36M | } |
83 | 7.36M | } |
84 | | |
85 | 11.2M | return g; |
86 | 11.2M | } |
87 | | |
88 | | int pdfi_find_post_entry(gs_font_type42 *pfont, gs_const_string *gname, uint *cc) |
89 | 2.56M | { |
90 | 2.56M | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
91 | 2.56M | pdf_context *ctx = (pdf_context *)ttfont->ctx; |
92 | 2.56M | int code = 0; |
93 | 2.56M | if (ttfont->post != NULL) { |
94 | 2.51M | pdf_name *name = NULL; |
95 | 2.51M | pdf_num *n = NULL; |
96 | | |
97 | 2.51M | code = pdfi_name_alloc(ctx, (byte *)gname->data, gname->size, (pdf_obj **)&name); |
98 | 2.51M | if (code >= 0) { |
99 | 2.51M | pdfi_countup(name); |
100 | 2.51M | code = pdfi_dict_get_by_key(ctx, ttfont->post, name, (pdf_obj **)&n); |
101 | 2.51M | if (code >= 0 && pdfi_type_of(n) == PDF_INT) { |
102 | 69.2k | *cc = (uint)n->value.i; |
103 | 69.2k | } |
104 | 2.44M | else |
105 | 2.44M | *cc = 0; |
106 | 2.51M | pdfi_countdown(name); |
107 | 2.51M | pdfi_countdown(n); |
108 | 2.51M | } |
109 | 2.51M | } |
110 | 48.1k | else |
111 | 48.1k | code = gs_error_VMerror; |
112 | | |
113 | 2.56M | if (code == gs_error_VMerror){ |
114 | 48.1k | uint i; |
115 | 48.1k | gs_string postname = {0}; |
116 | | |
117 | 48.1k | code = gs_error_undefined; |
118 | 48.1k | if (pfont->data.numGlyphs > 0) { /* protect from corrupt font */ |
119 | 0 | for (i = 0; i < pfont->data.numGlyphs; i++) { |
120 | 0 | code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname); |
121 | 0 | if (code >= 0) { |
122 | 0 | if (gname->data[0] == postname.data[0] |
123 | 0 | && gname->size == postname.size |
124 | 0 | && !strncmp((char *)gname->data, (char *)postname.data, postname.size)) |
125 | 0 | { |
126 | 0 | *cc = i; |
127 | 0 | code = 0; |
128 | 0 | break; |
129 | 0 | } |
130 | 0 | } |
131 | 0 | } |
132 | 0 | } |
133 | 48.1k | } |
134 | 2.56M | return code; |
135 | 2.56M | } |
136 | | |
137 | | extern single_glyph_list_t SingleGlyphList[]; |
138 | | |
139 | | static uint pdfi_type42_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph) |
140 | 7.21M | { |
141 | 7.21M | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
142 | 7.21M | uint gind = 0; |
143 | 7.21M | uint cc = 0; |
144 | 7.21M | int i, code = 0; |
145 | | |
146 | 7.21M | if ((ttfont->descflags & 4) != 0 || glyph >= GS_MIN_GLYPH_INDEX) { |
147 | 1.89M | gind = (uint)glyph < GS_MIN_GLYPH_INDEX ? glyph : glyph - GS_MIN_GLYPH_INDEX; |
148 | 1.89M | } |
149 | 5.32M | else { |
150 | 5.32M | pdf_context *ctx = (pdf_context *)ttfont->ctx; |
151 | 5.32M | gs_const_string gname; |
152 | | |
153 | 5.32M | code = (*ctx->get_glyph_name)((gs_font *)pfont, glyph, &gname); |
154 | 5.32M | if (code < 0 || gname.data == NULL) { |
155 | 0 | return (uint)glyph; |
156 | 0 | } |
157 | 5.32M | if (gname.size == 7 && gname.data[0] == '.' && strncmp((char *)gname.data, ".notdef", 7) == 0) { |
158 | 1.03M | return 0; /* .notdef is GID 0, so short cut the rest of the function */ |
159 | 1.03M | } |
160 | | |
161 | 4.28M | if (ttfont->cmap == pdfi_truetype_cmap_10) { |
162 | 626k | gs_glyph g; |
163 | | |
164 | 626k | g = gs_c_name_glyph((const byte *)gname.data, gname.size); |
165 | 626k | if (g != GS_NO_GLYPH) { |
166 | 626k | g = (gs_glyph)gs_c_decode(g, ENCODING_INDEX_MACROMAN); |
167 | 626k | } |
168 | 0 | else { |
169 | 0 | g = GS_NO_CHAR; |
170 | 0 | } |
171 | | |
172 | 626k | if (g != GS_NO_CHAR) { |
173 | 617k | code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)g, &cc); |
174 | 617k | } |
175 | | |
176 | 626k | if (code < 0 || cc == 0) { |
177 | 387k | code = pdfi_find_post_entry(pfont, &gname, &cc); |
178 | 387k | if (code < 0) { |
179 | 383k | cc = 0; |
180 | 383k | code = 0; |
181 | 383k | } |
182 | 387k | } |
183 | 626k | } |
184 | 3.66M | else { |
185 | | /* In theory, this should be 3,1 cmap, but we have examples that use 0,1 or other |
186 | | Unicode "platform" cmap tables, so "hail mary" just try it |
187 | | */ |
188 | 3.66M | single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList); |
189 | | /* Not to spec, but... if we get a "uni..." formatted name, use |
190 | | the hex value from that. |
191 | | */ |
192 | 3.66M | if (gname.size == 7 && !strncmp((char *)gname.data, "uni", 3)) { |
193 | 29.2k | char gnbuf[64]; |
194 | 29.2k | int l = (gname.size - 3) > 63 ? 63 : gname.size - 3; |
195 | | |
196 | 29.2k | memcpy(gnbuf, gname.data + 3, l); |
197 | 29.2k | gnbuf[l] = '\0'; |
198 | 29.2k | l = sscanf(gnbuf, "%x", &gind); |
199 | 29.2k | if (l > 0) |
200 | 29.2k | (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)gind, &cc); |
201 | 0 | else |
202 | 0 | cc = 0; |
203 | 29.2k | } |
204 | 3.63M | else { |
205 | | /* Slow linear search */ |
206 | 6.99G | for (i = 0; sgl->Glyph != 0x00; i++) { |
207 | 6.99G | if (sgl->Glyph[0] == gname.data[0] |
208 | 6.99G | && strlen(sgl->Glyph) == gname.size |
209 | 6.99G | && !strncmp((char *)sgl->Glyph, (char *)gname.data, gname.size)) |
210 | 3.63M | break; |
211 | 6.99G | sgl++; |
212 | 6.99G | } |
213 | 3.63M | if (sgl->Glyph != NULL) { |
214 | 3.63M | code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (uint)sgl->Unicode, &cc); |
215 | 3.63M | if (code < 0 || cc == 0) |
216 | 2.14M | cc = 0; |
217 | 3.63M | } |
218 | 204 | else |
219 | 204 | cc = 0; |
220 | | |
221 | 3.63M | if (cc == 0) { |
222 | 2.14M | code = pdfi_find_post_entry(pfont, &gname, &cc); |
223 | 2.14M | if (code < 0) { |
224 | 2.08M | cc = (uint)glyph; |
225 | 2.08M | code = 0; |
226 | 2.08M | } |
227 | 2.14M | } |
228 | 3.63M | } |
229 | 3.66M | } |
230 | 4.28M | gind = cc; |
231 | 4.28M | } |
232 | 6.18M | return gind; |
233 | 7.21M | } |
234 | | |
235 | | static int |
236 | | pdfi_ttf_enumerate_glyph(gs_font *font, int *pindex, gs_glyph_space_t glyph_space, gs_glyph *pglyph) |
237 | 4.26M | { |
238 | 4.26M | if (glyph_space == GLYPH_SPACE_INDEX) { |
239 | 148k | return gs_type42_enumerate_glyph(font, pindex, glyph_space, pglyph); |
240 | 148k | } |
241 | 4.11M | else if (glyph_space == GLYPH_SPACE_NAME) { |
242 | 4.11M | pdf_font_truetype *ttfont = (pdf_font_truetype *)font->client_data; |
243 | | |
244 | 4.11M | if ((ttfont->descflags & 4) == 0) { |
245 | 4.09M | if (*pindex <= 0) { |
246 | 54.5k | *pindex = 0; |
247 | 54.5k | } |
248 | 4.09M | *pglyph = (*font->procs.encode_char)(font, (gs_char)*pindex, glyph_space); |
249 | 4.09M | if (*pglyph == GS_NO_GLYPH) |
250 | 9.84k | *pindex = 0; |
251 | 4.08M | else |
252 | 4.08M | (*pindex)++; |
253 | 4.09M | } |
254 | 4.11M | } |
255 | 0 | else |
256 | 0 | *pindex = 0; |
257 | 4.11M | return 0; |
258 | 4.26M | } |
259 | | |
260 | | static int pdfi_ttf_glyph_name(gs_font *pfont, gs_glyph glyph, gs_const_string * pstr) |
261 | 545k | { |
262 | 545k | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
263 | 545k | pdf_context *ctx = (pdf_context *)ttfont->ctx; |
264 | 545k | uint ID = 0; |
265 | 545k | int l, code = -1; |
266 | | |
267 | 545k | if (glyph >= GS_MIN_CID_GLYPH) { /* Fabricate a numeric name. */ |
268 | 1.59k | char cid_name[sizeof(gs_glyph) * 3 + 1]; |
269 | | |
270 | 1.59k | l = gs_snprintf(cid_name, sizeof(cid_name), "%lu", (ulong) glyph); |
271 | | /* We need to create the entry in the name table... */ |
272 | 1.59k | code = (*ctx->get_glyph_index)(pfont, (byte *)cid_name, l, &ID); |
273 | 1.59k | if (code < 0) |
274 | 0 | return -1; |
275 | | |
276 | 1.59k | code = (*ctx->get_glyph_name)(pfont, (gs_glyph)ID, pstr); |
277 | 1.59k | if (code < 0) |
278 | 0 | return -1; /* No name, trigger pdfwrite Type 3 fallback */ |
279 | 544k | } else { |
280 | 544k | if ((ttfont->descflags & 4) != 0) { |
281 | 62.4k | code = gs_type42_find_post_name((gs_font_type42 *)pfont, glyph, (gs_string *)pstr); |
282 | 62.4k | if (code < 0) { |
283 | 56.9k | char buf[64]; |
284 | 56.9k | l = gs_snprintf(buf, sizeof(buf), "~gs~gName~%04x", (uint)glyph); |
285 | 56.9k | code = (*ctx->get_glyph_index)(pfont, (byte *)buf, l, &ID); |
286 | 56.9k | } |
287 | 5.50k | else { |
288 | 5.50k | code = (*ctx->get_glyph_index)(pfont, (byte *)pstr->data, pstr->size, &ID); |
289 | 5.50k | } |
290 | 62.4k | if (code < 0) |
291 | 0 | return -1; /* No name, trigger pdfwrite Type 3 fallback */ |
292 | | |
293 | 62.4k | code = (*ctx->get_glyph_name)(pfont, (gs_glyph)ID, pstr); |
294 | 62.4k | if (code < 0) |
295 | 0 | return -1; /* No name, trigger pdfwrite Type 3 fallback */ |
296 | 62.4k | } |
297 | 481k | else { |
298 | 481k | code = (*ctx->get_glyph_name)(pfont, glyph, pstr); |
299 | 481k | if (code < 0) |
300 | 0 | return -1; /* No name, trigger pdfwrite Type 3 fallback */ |
301 | 481k | } |
302 | 544k | } |
303 | 545k | return code; |
304 | | |
305 | 545k | } |
306 | | |
307 | | static void pdfi_make_post_dict(gs_font_type42 *pfont) |
308 | 17.0k | { |
309 | 17.0k | pdf_font_truetype *ttfont = (pdf_font_truetype *)pfont->client_data; |
310 | 17.0k | pdf_context *ctx = (pdf_context *)ttfont->ctx; |
311 | 17.0k | int i, code = 0; |
312 | 17.0k | if (ttfont->post == NULL && pfont->data.numGlyphs > 0) { |
313 | 16.7k | code = pdfi_dict_alloc(ctx, pfont->data.numGlyphs, &ttfont->post); |
314 | 16.7k | if (code < 0) |
315 | 0 | return; |
316 | | |
317 | 16.7k | pdfi_countup(ttfont->post); |
318 | | |
319 | 18.2M | for (i = 0; i < pfont->data.numGlyphs; i++) { |
320 | 18.2M | gs_string postname = {0}; |
321 | 18.2M | pdf_name *key; |
322 | 18.2M | pdf_num *ind; |
323 | | |
324 | 18.2M | code = gs_type42_find_post_name(pfont, (gs_glyph)i, &postname); |
325 | 18.2M | if (code < 0) { |
326 | 16.6M | continue; |
327 | 16.6M | } |
328 | 1.63M | code = pdfi_name_alloc(ctx, postname.data, postname.size, (pdf_obj **)&key); |
329 | 1.63M | if (code < 0) { |
330 | 0 | continue; |
331 | 0 | } |
332 | 1.63M | pdfi_countup(key); |
333 | 1.63M | code = pdfi_object_alloc(ctx, PDF_INT, 0, (pdf_obj **)&ind); |
334 | 1.63M | if (code < 0) { |
335 | 0 | pdfi_countdown(key); |
336 | 0 | continue; |
337 | 0 | } |
338 | 1.63M | pdfi_countup(ind); |
339 | 1.63M | ind->value.i = i; |
340 | 1.63M | (void)pdfi_dict_put_obj(ctx, ttfont->post, (pdf_obj *)key, (pdf_obj *)ind, false); |
341 | 1.63M | pdfi_countdown(key); |
342 | 1.63M | pdfi_countdown(ind); |
343 | 1.63M | } |
344 | 16.7k | } |
345 | 17.0k | } |
346 | | |
347 | | |
348 | | static int |
349 | | pdfi_alloc_tt_font(pdf_context *ctx, pdf_font_truetype **font, bool is_cid) |
350 | 26.4k | { |
351 | 26.4k | pdf_font_truetype *ttfont = NULL; |
352 | 26.4k | gs_font_type42 *pfont = NULL; |
353 | | |
354 | 26.4k | ttfont = (pdf_font_truetype *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_truetype), "pdfi (truetype pdf_font)"); |
355 | 26.4k | if (ttfont == NULL) |
356 | 0 | return_error(gs_error_VMerror); |
357 | | |
358 | 26.4k | memset(ttfont, 0x00, sizeof(pdf_font_truetype)); |
359 | 26.4k | ttfont->type = PDF_FONT; |
360 | 26.4k | ttfont->ctx = ctx; |
361 | 26.4k | ttfont->pdfi_font_type = e_pdf_font_truetype; |
362 | | |
363 | | #if REFCNT_DEBUG |
364 | | ttfont->UID = ctx->UID++; |
365 | | outprintf(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID); |
366 | | #endif |
367 | | |
368 | 26.4k | pdfi_countup(ttfont); |
369 | | |
370 | 26.4k | pfont = (gs_font_type42 *)gs_alloc_struct(ctx->memory, gs_font_type42, &st_gs_font_type42, |
371 | 26.4k | "pdfi (truetype pfont)"); |
372 | 26.4k | if (pfont == NULL) { |
373 | 0 | pdfi_countdown(ttfont); |
374 | 0 | return_error(gs_error_VMerror); |
375 | 0 | } |
376 | 26.4k | memset(pfont, 0x00, sizeof(gs_font_type42)); |
377 | | |
378 | 26.4k | ttfont->pfont = (gs_font_base *)pfont; |
379 | | |
380 | 26.4k | gs_make_identity(&pfont->orig_FontMatrix); |
381 | 26.4k | gs_make_identity(&pfont->FontMatrix); |
382 | 26.4k | pfont->next = pfont->prev = 0; |
383 | 26.4k | pfont->memory = ctx->memory; |
384 | 26.4k | pfont->dir = ctx->font_dir; |
385 | 26.4k | pfont->is_resource = false; |
386 | 26.4k | gs_notify_init(&pfont->notify_list, ctx->memory); |
387 | 26.4k | pfont->base = (gs_font *) ttfont->pfont; |
388 | 26.4k | pfont->client_data = ttfont; |
389 | 26.4k | pfont->WMode = 0; |
390 | 26.4k | pfont->PaintType = 0; |
391 | 26.4k | pfont->StrokeWidth = 0; |
392 | 26.4k | pfont->is_cached = 0; |
393 | 26.4k | pfont->FAPI = NULL; |
394 | 26.4k | pfont->FAPI_font_data = NULL; |
395 | 26.4k | pfont->procs.init_fstack = gs_default_init_fstack; |
396 | 26.4k | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
397 | 26.4k | pfont->FontType = ft_TrueType; |
398 | 26.4k | pfont->ExactSize = fbit_use_outlines; |
399 | 26.4k | pfont->InBetweenSize = fbit_use_outlines; |
400 | 26.4k | pfont->TransformedChar = fbit_use_outlines; |
401 | | /* We may want to do something clever with an XUID here */ |
402 | 26.4k | pfont->id = gs_next_ids(ctx->memory, 1); |
403 | 26.4k | uid_set_UniqueID(&pfont->UID, pfont->id); |
404 | | /* The buildchar proc will be filled in by FAPI - |
405 | | we won't worry about working without FAPI */ |
406 | 26.4k | pfont->procs.encode_char = pdfi_ttf_encode_char; |
407 | 26.4k | pfont->data.string_proc = pdfi_ttf_string_proc; |
408 | 26.4k | pfont->procs.glyph_name = pdfi_ttf_glyph_name; |
409 | 26.4k | pfont->procs.decode_glyph = pdfi_decode_glyph; |
410 | 26.4k | pfont->procs.define_font = gs_no_define_font; |
411 | 26.4k | pfont->procs.make_font = gs_no_make_font; |
412 | | |
413 | 26.4k | ttfont->default_font_info = gs_default_font_info; |
414 | 26.4k | pfont->procs.font_info = pdfi_default_font_info; |
415 | | |
416 | 26.4k | pfont->procs.glyph_info = gs_default_glyph_info; |
417 | 26.4k | pfont->procs.glyph_outline = gs_no_glyph_outline; |
418 | 26.4k | pfont->procs.build_char = NULL; |
419 | 26.4k | pfont->procs.same_font = gs_default_same_font; |
420 | 26.4k | pfont->procs.enumerate_glyph = gs_no_enumerate_glyph; |
421 | | |
422 | 26.4k | pfont->encoding_index = ENCODING_INDEX_UNKNOWN; |
423 | 26.4k | pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN; |
424 | | |
425 | 26.4k | pfont->client_data = (void *)ttfont; |
426 | | |
427 | 26.4k | *font = ttfont; |
428 | 26.4k | return 0; |
429 | 26.4k | } |
430 | | |
431 | | static void pdfi_set_type42_custom_procs(pdf_font_truetype *pdfttfont) |
432 | 17.1k | { |
433 | 17.1k | gs_font_type42 *pfont = (gs_font_type42 *)pdfttfont->pfont; |
434 | | |
435 | 17.1k | pdfttfont->default_font_info = pfont->procs.font_info; |
436 | 17.1k | pfont->procs.font_info = pdfi_default_font_info; |
437 | 17.1k | pfont->data.get_glyph_index = pdfi_type42_get_glyph_index; |
438 | 17.1k | pfont->procs.enumerate_glyph = pdfi_ttf_enumerate_glyph; |
439 | 17.1k | } |
440 | | |
441 | | 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) |
442 | 23.3k | { |
443 | 23.3k | pdf_font_truetype *font = NULL; |
444 | 23.3k | int code = 0, i; |
445 | 23.3k | pdf_obj *fontdesc = NULL; |
446 | 23.3k | pdf_obj *obj = NULL; |
447 | 23.3k | pdf_obj *basefont = NULL; |
448 | 23.3k | int64_t descflags; |
449 | 23.3k | bool encoding_known = false; |
450 | 23.3k | bool forced_symbolic = false; |
451 | 23.3k | pdf_obj *tounicode = NULL; |
452 | | |
453 | 23.3k | if (ppdffont == NULL) |
454 | 0 | return_error(gs_error_invalidaccess); |
455 | | |
456 | 23.3k | *ppdffont = NULL; |
457 | | |
458 | 23.3k | if (font_dict != NULL) |
459 | 23.3k | (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
460 | | |
461 | 23.3k | if ((code = pdfi_alloc_tt_font(ctx, &font, false)) < 0) { |
462 | 0 | code = gs_note_error(gs_error_invalidfont); |
463 | 0 | goto error; |
464 | 0 | } |
465 | 23.3k | if (font_dict != NULL) { |
466 | 23.3k | font->object_num = font_dict->object_num; |
467 | 23.3k | font->generation_num = font_dict->generation_num; |
468 | 23.3k | font->indirect_num = font_dict->indirect_num; |
469 | 23.3k | font->indirect_gen = font_dict->indirect_gen; |
470 | 23.3k | } |
471 | | |
472 | 23.3k | font->FontDescriptor = (pdf_dict *)fontdesc; |
473 | 23.3k | fontdesc = NULL; |
474 | | |
475 | 23.3k | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font); |
476 | | |
477 | 23.3k | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt); |
478 | 23.3k | if (code < 0) { |
479 | 0 | goto error; |
480 | 0 | } |
481 | 23.3k | pdfi_countup(font->sfnt); |
482 | 23.3k | code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen); |
483 | 23.3k | if (code < 0) { |
484 | 0 | goto error; |
485 | 0 | } |
486 | 23.3k | buf = NULL; |
487 | | |
488 | | /* Strictly speaking BaseFont is required, but we can continue without one */ |
489 | 23.3k | if (font_dict != NULL) { |
490 | 23.3k | code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&basefont); |
491 | 23.3k | if (code > 0) { |
492 | 22.7k | pdf_name *nobj = (pdf_name *)basefont; |
493 | 22.7k | int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length; |
494 | | |
495 | 22.7k | memcpy(font->pfont->key_name.chars, nobj->data, nlen); |
496 | 22.7k | font->pfont->key_name.chars[nlen] = 0; |
497 | 22.7k | font->pfont->key_name.size = nlen; |
498 | 22.7k | memcpy(font->pfont->font_name.chars, nobj->data, nlen); |
499 | 22.7k | font->pfont->font_name.chars[nlen] = 0; |
500 | 22.7k | font->pfont->font_name.size = nlen; |
501 | 22.7k | pdfi_countdown(obj); |
502 | 22.7k | obj = NULL; |
503 | 22.7k | } |
504 | 23.3k | } |
505 | 23.3k | font->BaseFont = basefont; |
506 | 23.3k | basefont = NULL; |
507 | 23.3k | font->PDF_font = font_dict; |
508 | 23.3k | pdfi_countup(font_dict); |
509 | | |
510 | | /* ignore errors with widths... for now */ |
511 | 23.3k | if (font_dict != NULL) |
512 | 23.3k | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, 0.001); |
513 | | |
514 | 23.3k | if (ctx->args.ignoretounicode != true && font_dict != NULL) { |
515 | 23.3k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode); |
516 | 23.3k | if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) { |
517 | 9.59k | pdf_cmap *tu = NULL; |
518 | 9.59k | code = pdfi_read_cmap(ctx, tounicode, &tu); |
519 | 9.59k | pdfi_countdown(tounicode); |
520 | 9.59k | tounicode = (pdf_obj *)tu; |
521 | 9.59k | } |
522 | 23.3k | if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) { |
523 | 13.5k | pdfi_countdown(tounicode); |
524 | 13.5k | tounicode = NULL; |
525 | 13.5k | code = 0; |
526 | 13.5k | } |
527 | 23.3k | } |
528 | 0 | else { |
529 | 0 | tounicode = NULL; |
530 | 0 | } |
531 | 23.3k | font->ToUnicode = tounicode; |
532 | 23.3k | tounicode = NULL; |
533 | | |
534 | 23.3k | if (font->FontDescriptor != NULL) { |
535 | 23.3k | code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &descflags); |
536 | 23.3k | if (code < 0) |
537 | 15 | descflags = 0; |
538 | 23.3k | } |
539 | 0 | else { |
540 | 0 | descflags = 0; |
541 | 0 | } |
542 | | |
543 | 23.3k | if (font_dict != NULL) |
544 | 23.3k | code = pdfi_dict_get(ctx, font_dict, "Encoding", &obj); |
545 | 0 | else |
546 | 0 | code = gs_error_undefined; |
547 | | |
548 | 23.3k | if (code < 0) { |
549 | 6.04k | static const char encstr[] = "WinAnsiEncoding"; |
550 | 6.04k | code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj); |
551 | 6.04k | if (code >= 0) |
552 | 6.04k | pdfi_countup(obj); |
553 | 0 | else |
554 | 0 | goto error; |
555 | 6.04k | } |
556 | 17.2k | else { |
557 | 17.2k | encoding_known = true; |
558 | | /* If we have and encoding, and both the symbolic and non-symbolic flag are set, |
559 | | believe that latter. |
560 | | */ |
561 | 17.2k | if ((descflags & 32) != 0) |
562 | 16.8k | descflags = (descflags & ~4); |
563 | 17.2k | } |
564 | | |
565 | 23.3k | if ((forced_symbolic = pdfi_font_known_symbolic(font->BaseFont)) == true) { |
566 | 0 | descflags |= 4; |
567 | 0 | } |
568 | | |
569 | 23.3k | code = pdfi_create_Encoding(ctx, (pdf_font *)font, obj, NULL, (pdf_obj **)&font->Encoding); |
570 | | /* If we get an error, and the font is non-symbolic, return the error */ |
571 | 23.3k | if (code < 0 && (descflags & 4) == 0) |
572 | 43 | goto error; |
573 | | /* If we get an error, and the font is symbolic, pretend we never saw an /Encoding */ |
574 | 23.2k | if (code < 0) |
575 | 6 | encoding_known = false; |
576 | 23.2k | pdfi_countdown(obj); |
577 | 23.2k | obj = NULL; |
578 | | |
579 | 23.2k | code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0); |
580 | 23.2k | if (code < 0) { |
581 | 6.11k | goto error; |
582 | 6.11k | } |
583 | | |
584 | 17.1k | pdfi_set_type42_custom_procs(font); |
585 | | |
586 | | /* We're probably dead in the water without cmap tables, but make sure, for safety */ |
587 | | /* This is a horrendous morass of guesses at what Acrobat does with files that contravene |
588 | | what the spec says about symbolic fonts, cmap tables and encodings. |
589 | | */ |
590 | 17.1k | if (forced_symbolic != true && (descflags & 4) != 0 && ((gs_font_type42 *)font->pfont)->data.cmap != 0) { |
591 | 4.62k | gs_font_type42 *t42f = (gs_font_type42 *)font->pfont; |
592 | 4.62k | int numcmaps; |
593 | 4.62k | int cmaps_available = CMAP_TABLE_NONE; |
594 | 4.62k | const byte *d; |
595 | 4.62k | code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 2, 2, &d); |
596 | 4.62k | if (code < 0) |
597 | 8 | goto error; |
598 | 4.61k | numcmaps = d[1] | d[0] << 8; |
599 | 92.3k | for (i = 0; i < numcmaps; i++) { |
600 | 87.8k | code = (*t42f->data.string_proc)(t42f, t42f->data.cmap + 4 + i * 8, 4, &d); |
601 | 87.8k | if (code < 0) |
602 | 149 | goto error; |
603 | 93.4k | #define CMAP_PLAT_ENC_ID(a,b,c,d) (a << 24 | b << 16 | c << 8 | d) |
604 | 87.7k | switch(CMAP_PLAT_ENC_ID(d[0], d[1], d[2], d[3])) { |
605 | 4.23k | case CMAP_PLAT_ENC_ID(0, 1, 0, 0): |
606 | 4.23k | cmaps_available |= CMAP_TABLE_10_PRESENT; |
607 | 4.23k | break; |
608 | 1.39k | case CMAP_PLAT_ENC_ID(0, 3, 0, 0): |
609 | 1.39k | cmaps_available |= CMAP_TABLE_30_PRESENT; |
610 | 1.39k | break; |
611 | 82 | case CMAP_PLAT_ENC_ID(0, 3, 0, 1): |
612 | 82 | cmaps_available |= CMAP_TABLE_31_PRESENT; |
613 | 82 | break; |
614 | 0 | case CMAP_PLAT_ENC_ID(0, 3, 1, 0): |
615 | 0 | cmaps_available |= CMAP_TABLE_310_PRESENT; |
616 | 0 | break; |
617 | 82.0k | default: /* Not one we're interested in */ |
618 | 82.0k | break; |
619 | 87.7k | } |
620 | 87.7k | } |
621 | 4.46k | #undef CMAP_PLAT_ENC_ID |
622 | 4.46k | if ((cmaps_available & CMAP_TABLE_30_PRESENT) == CMAP_TABLE_30_PRESENT) { |
623 | 1.35k | font->descflags = descflags; |
624 | 1.35k | } |
625 | 3.11k | else if (encoding_known == true) { |
626 | 47 | static const char mrencstr[] = "MacRomanEncoding"; |
627 | 47 | static const char waencstr[] = "WinAnsiEncoding"; |
628 | 47 | const char *encstr = ((cmaps_available & CMAP_TABLE_31_PRESENT) == CMAP_TABLE_31_PRESENT) ? waencstr : mrencstr; |
629 | 47 | font->descflags = descflags & ~4; |
630 | 47 | code = pdfi_name_alloc(ctx, (byte *)encstr, strlen(encstr), (pdf_obj **)&obj); |
631 | 47 | if (code >= 0) |
632 | 47 | pdfi_countup(obj); |
633 | 0 | else |
634 | 0 | goto error; |
635 | 47 | pdfi_countdown(font->Encoding); |
636 | 47 | code = pdfi_create_Encoding(ctx, (pdf_font *)font, obj, NULL, (pdf_obj **)&font->Encoding); |
637 | 47 | if (code < 0) |
638 | 0 | goto error; |
639 | 47 | pdfi_countdown(obj); |
640 | 47 | obj = NULL; |
641 | 47 | } |
642 | 3.06k | else |
643 | 3.06k | font->descflags = descflags; |
644 | 4.46k | } |
645 | 12.5k | else { |
646 | 12.5k | font->descflags = descflags; |
647 | 12.5k | } |
648 | | |
649 | 17.0k | if (uid_is_XUID(&font->pfont->UID)) |
650 | 17.0k | uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font"); |
651 | 17.0k | uid_set_invalid(&font->pfont->UID); |
652 | | |
653 | 17.0k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
654 | 17.0k | if (code < 0) { |
655 | 0 | goto error; |
656 | 0 | } |
657 | | |
658 | 17.0k | if ((font->descflags & 4) == 0) { |
659 | | /* Horrid hacky solution */ |
660 | | /* We don't want to draw the TTF notdef */ |
661 | 12.5k | gs_font_type42 *gst42 = ((gs_font_type42 *)font->pfont); |
662 | 12.5k | if (gst42->data.len_glyphs != NULL && gst42->data.len_glyphs[0] > 10) { |
663 | 9.96k | gst42->data.len_glyphs[0] = 0; |
664 | 9.96k | } |
665 | 12.5k | } |
666 | | |
667 | 17.0k | pdfi_make_post_dict((gs_font_type42 *)font->pfont); |
668 | | |
669 | 17.0k | pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font); |
670 | 17.0k | code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont); |
671 | 17.0k | if (code < 0) { |
672 | 0 | goto error; |
673 | 0 | } |
674 | | |
675 | 17.0k | code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length); |
676 | 17.0k | if (code < 0) { |
677 | 993 | goto error; |
678 | 993 | } |
679 | | |
680 | | /* object_num can be zero if the dictionary was defined inline */ |
681 | 16.0k | if (font->object_num != 0) { |
682 | 15.8k | (void)replace_cache_entry(ctx, (pdf_obj *)font); |
683 | 15.8k | } |
684 | | |
685 | 16.0k | *ppdffont = (pdf_font *)font; |
686 | 16.0k | return code; |
687 | 7.31k | error: |
688 | 7.31k | pdfi_countdown(obj); |
689 | 7.31k | obj = NULL; |
690 | 7.31k | if (font_dict != NULL) { |
691 | 7.31k | if (pdfi_dict_get(ctx, font_dict, ".Path", &obj) >= 0) |
692 | 0 | { |
693 | 0 | char fname[gp_file_name_sizeof + 1]; |
694 | 0 | pdf_string *fobj = (pdf_string *)obj; |
695 | |
|
696 | 0 | memcpy(fname, fobj->data, fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length); |
697 | 0 | fname[fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length] = '\0'; |
698 | |
|
699 | 0 | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading TrueType font file %s\n", fname); |
700 | 0 | } |
701 | 7.31k | else { |
702 | 7.31k | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading embedded TrueType font object %u\n", font_dict->object_num); |
703 | 7.31k | } |
704 | 7.31k | } |
705 | 0 | else { |
706 | 0 | pdfi_set_error(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading font\n"); |
707 | 0 | } |
708 | 7.31k | if (buf != NULL) |
709 | 0 | gs_free_object(ctx->memory, buf, "pdfi_read_truetype_font(buf)"); |
710 | 7.31k | pdfi_countdown(fontdesc); |
711 | 7.31k | pdfi_countdown(basefont); |
712 | 7.31k | pdfi_countdown(font); |
713 | 7.31k | return code; |
714 | 17.0k | } |
715 | | |
716 | | int |
717 | | pdfi_copy_truetype_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont) |
718 | 3.10k | { |
719 | 3.10k | int code = 0; |
720 | 3.10k | pdf_font_truetype *font = NULL; |
721 | 3.10k | gs_font_type42 *spfont1 = (gs_font_type42 *) spdffont->pfont; |
722 | 3.10k | gs_font_type42 *dpfont42; |
723 | 3.10k | gs_id t_id; |
724 | 3.10k | pdf_obj *tmp; |
725 | | |
726 | 3.10k | if (font_dict == NULL) |
727 | 0 | return_error(gs_error_invalidfont); |
728 | | |
729 | 3.10k | code = pdfi_alloc_tt_font(ctx, &font, font_dict->object_num); |
730 | 3.10k | if (code < 0) |
731 | 0 | return code; |
732 | 3.10k | dpfont42 = (gs_font_type42 *) font->pfont; |
733 | | |
734 | 3.10k | t_id = dpfont42->id; |
735 | 3.10k | memcpy(dpfont42, spfont1, sizeof(gs_font_type42)); |
736 | 3.10k | dpfont42->id = t_id; |
737 | 3.10k | dpfont42->FAPI = NULL; |
738 | 3.10k | dpfont42->FAPI_font_data = NULL; |
739 | 3.10k | dpfont42->notify_list.memory = NULL; |
740 | 3.10k | dpfont42->notify_list.first = NULL; |
741 | 3.10k | gs_notify_init(&dpfont42->notify_list, dpfont42->memory); |
742 | | |
743 | 3.10k | memcpy(font, spdffont, sizeof(pdf_font_truetype)); |
744 | 3.10k | font->refcnt = 1; |
745 | 3.10k | font->filename = NULL; |
746 | 3.10k | pdfi_countup(font->post); |
747 | | |
748 | 3.10k | if (dpfont42->data.len_glyphs != NULL) { |
749 | 3.10k | dpfont42->data.len_glyphs = (uint *)gs_alloc_byte_array(dpfont42->memory, dpfont42->data.numGlyphs + 1, sizeof(uint), "pdfi_copy_truetype_font"); |
750 | 3.10k | if (dpfont42->data.len_glyphs == NULL) { |
751 | 0 | pdfi_countdown(font); |
752 | 0 | return_error(gs_error_VMerror); |
753 | 0 | } |
754 | 3.10k | code = gs_font_notify_register((gs_font *)dpfont42, gs_len_glyphs_release, (void *)dpfont42); |
755 | 3.10k | if (code < 0) { |
756 | 0 | gs_free_object(dpfont42->memory, dpfont42->data.len_glyphs, "gs_len_glyphs_release"); |
757 | 0 | dpfont42->data.len_glyphs = NULL; |
758 | 0 | pdfi_countdown(font); |
759 | 0 | return code; |
760 | 0 | } |
761 | 3.10k | memcpy(dpfont42->data.len_glyphs, spfont1->data.len_glyphs, (dpfont42->data.numGlyphs + 1) * sizeof(uint)); |
762 | 3.10k | } |
763 | 3.10k | if (dpfont42->data.gsub != NULL) { |
764 | 0 | dpfont42->data.gsub_size = spfont1->data.gsub_size; |
765 | |
|
766 | 0 | dpfont42->data.gsub = gs_alloc_byte_array(dpfont42->memory, dpfont42->data.gsub_size, 1, "pdfi_copy_truetype_font"); |
767 | 0 | if (dpfont42->data.gsub == 0) { |
768 | 0 | pdfi_countdown(font); |
769 | 0 | return_error(gs_error_VMerror); |
770 | 0 | } |
771 | | |
772 | 0 | code = gs_font_notify_register((gs_font *)dpfont42, gs_gsub_release, (void *)dpfont42); |
773 | 0 | if (code < 0) { |
774 | 0 | gs_free_object(dpfont42->memory, dpfont42->data.gsub, "gs_len_glyphs_release"); |
775 | 0 | dpfont42->data.gsub = NULL; |
776 | 0 | pdfi_countdown(font); |
777 | 0 | return code; |
778 | 0 | } |
779 | 0 | memcpy(dpfont42->data.gsub, spfont1->data.gsub, dpfont42->data.gsub_size); |
780 | 0 | } |
781 | | |
782 | 3.10k | font->pfont = (gs_font_base *)dpfont42; |
783 | 3.10k | dpfont42->client_data = (void *)font; |
784 | | |
785 | 3.10k | font->PDF_font = font_dict; |
786 | 3.10k | font->object_num = font_dict->object_num; |
787 | 3.10k | font->generation_num = font_dict->generation_num; |
788 | 3.10k | pdfi_countup(font->PDF_font); |
789 | | |
790 | | /* We want basefont and descriptor, but we can live without them */ |
791 | 3.10k | font->BaseFont = NULL; |
792 | 3.10k | (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont); |
793 | 3.10k | font->FontDescriptor = NULL; |
794 | 3.10k | (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor); |
795 | | |
796 | 3.10k | pdfi_countup(font->sfnt); |
797 | 3.10k | pdfi_countup(font->copyright); |
798 | 3.10k | pdfi_countup(font->notice); |
799 | 3.10k | pdfi_countup(font->fullname); |
800 | 3.10k | pdfi_countup(font->familyname); |
801 | | |
802 | 3.10k | if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) { |
803 | 3.08k | memcpy(dpfont42->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
804 | 3.08k | dpfont42->key_name.size = ((pdf_name *)font->BaseFont)->length; |
805 | 3.08k | memcpy(dpfont42->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
806 | 3.08k | dpfont42->font_name.size = ((pdf_name *)font->BaseFont)->length; |
807 | 3.08k | } |
808 | | |
809 | 3.10k | font->Encoding = NULL; |
810 | 3.10k | font->ToUnicode = NULL; |
811 | 3.10k | font->Widths = NULL; |
812 | | |
813 | 3.10k | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font); |
814 | 3.10k | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)font, (double)0.001); |
815 | | |
816 | 3.10k | font->descflags = 0; |
817 | 3.10k | if (font->FontDescriptor != NULL) { |
818 | 3.10k | code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags); |
819 | 3.10k | if (code >= 0) { |
820 | | /* If both the symbolic and non-symbolic flag are set, |
821 | | believe that latter. |
822 | | */ |
823 | 3.10k | if ((font->descflags & 32) != 0) |
824 | 3.10k | font->descflags = (font->descflags & ~4); |
825 | 3.10k | } |
826 | 3.10k | } |
827 | | |
828 | 3.10k | tmp = NULL; |
829 | 3.10k | code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp); |
830 | 3.10k | if (code == 1) { |
831 | 3.09k | if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) { |
832 | 3.09k | code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, NULL, (pdf_obj **) & font->Encoding); |
833 | 3.09k | } |
834 | 0 | else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) { |
835 | 0 | code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding); |
836 | 0 | } |
837 | 0 | else { |
838 | 0 | code = gs_error_undefined; |
839 | 0 | } |
840 | 3.09k | pdfi_countdown(tmp); |
841 | 3.09k | tmp = NULL; |
842 | 3.09k | } |
843 | 1 | else { |
844 | 1 | pdfi_countdown(tmp); |
845 | 1 | tmp = NULL; |
846 | 1 | code = gs_error_undefined; |
847 | 1 | } |
848 | | |
849 | 3.10k | if (code < 0) { |
850 | 1 | font->Encoding = spdffont->Encoding; |
851 | 1 | pdfi_countup(font->Encoding); |
852 | 1 | } |
853 | | |
854 | 3.10k | code = uid_copy(&font->pfont->UID, font->pfont->memory, "pdfi_copy_cff_font"); |
855 | 3.10k | if (code < 0) { |
856 | 0 | uid_set_invalid(&font->pfont->UID); |
857 | 0 | } |
858 | 3.10k | if (spdffont->filename == NULL) { |
859 | 3.10k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
860 | 3.10k | if (code < 0) { |
861 | 0 | goto error; |
862 | 0 | } |
863 | 3.10k | } |
864 | 3.10k | if (ctx->args.ignoretounicode != true) { |
865 | 3.10k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp); |
866 | 3.10k | if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) { |
867 | 279 | pdf_cmap *tu = NULL; |
868 | 279 | code = pdfi_read_cmap(ctx, tmp, &tu); |
869 | 279 | pdfi_countdown(tmp); |
870 | 279 | tmp = (pdf_obj *)tu; |
871 | 279 | } |
872 | 3.10k | if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) { |
873 | 2.82k | pdfi_countdown(tmp); |
874 | 2.82k | tmp = NULL; |
875 | 2.82k | code = 0; |
876 | 2.82k | } |
877 | 3.10k | } |
878 | 0 | else { |
879 | 0 | tmp = NULL; |
880 | 0 | } |
881 | 3.10k | font->ToUnicode = tmp; |
882 | 3.10k | pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font); |
883 | | |
884 | 3.10k | code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont); |
885 | 3.10k | if (code < 0) { |
886 | 0 | goto error; |
887 | 0 | } |
888 | | |
889 | 3.10k | code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0); |
890 | 3.10k | if (code < 0) { |
891 | 0 | goto error; |
892 | 0 | } |
893 | | /* object_num can be zero if the dictionary was defined inline */ |
894 | 3.10k | if (font->object_num != 0) { |
895 | 347 | (void)replace_cache_entry(ctx, (pdf_obj *) font); |
896 | 347 | } |
897 | | |
898 | 3.10k | *tpdffont = (pdf_font *)font; |
899 | | |
900 | 3.10k | error: |
901 | 3.10k | if (code < 0) |
902 | 0 | pdfi_countdown(font); |
903 | 3.10k | return code; |
904 | 3.10k | } |
905 | | |
906 | | int pdfi_free_font_truetype(pdf_obj *font) |
907 | 26.4k | { |
908 | 26.4k | pdf_font_truetype *ttfont = (pdf_font_truetype *)font; |
909 | | |
910 | 26.4k | if (ttfont->pfont) |
911 | 26.4k | gs_free_object(OBJ_MEMORY(ttfont), ttfont->pfont, "Free TrueType gs_font"); |
912 | | |
913 | 26.4k | if (ttfont->Widths) |
914 | 25.0k | gs_free_object(OBJ_MEMORY(ttfont), ttfont->Widths, "Free TrueType font Widths array"); |
915 | | |
916 | 26.4k | pdfi_countdown(ttfont->sfnt); |
917 | 26.4k | pdfi_countdown(ttfont->FontDescriptor); |
918 | 26.4k | pdfi_countdown(ttfont->Encoding); |
919 | 26.4k | pdfi_countdown(ttfont->BaseFont); |
920 | 26.4k | pdfi_countdown(ttfont->PDF_font); |
921 | 26.4k | pdfi_countdown(ttfont->ToUnicode); |
922 | 26.4k | pdfi_countdown(ttfont->filename); |
923 | 26.4k | pdfi_countdown(ttfont->post); |
924 | 26.4k | pdfi_countdown(ttfont->copyright); |
925 | 26.4k | pdfi_countdown(ttfont->notice); |
926 | 26.4k | pdfi_countdown(ttfont->fullname); |
927 | 26.4k | pdfi_countdown(ttfont->familyname); |
928 | | |
929 | 26.4k | gs_free_object(OBJ_MEMORY(ttfont), ttfont, "Free TrueType font"); |
930 | | |
931 | 26.4k | return 0; |
932 | 26.4k | } |