/src/ghostpdl/pdf/pdf_font1.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 type 1 font handling */ |
17 | | #include "pdf_int.h" |
18 | | |
19 | | #include "gsgdata.h" |
20 | | #include "gstype1.h" |
21 | | #include "gscencs.h" |
22 | | |
23 | | #include "strmio.h" |
24 | | #include "strimpl.h" |
25 | | #include "stream.h" |
26 | | #include "sfilter.h" |
27 | | |
28 | | #include "pdf_deref.h" |
29 | | #include "pdf_types.h" |
30 | | #include "pdf_array.h" |
31 | | #include "pdf_dict.h" |
32 | | #include "pdf_file.h" |
33 | | #include "pdf_font_types.h" |
34 | | #include "pdf_font.h" |
35 | | #include "pdf_fmap.h" |
36 | | #include "pdf_font1.h" |
37 | | #include "pdf_font1C.h" |
38 | | #include "pdf_fontps.h" |
39 | | #include "pdf_fontTT.h" |
40 | | |
41 | | #include "gxtype1.h" /* for gs_type1_state_s */ |
42 | | #include "gsutil.h" /* For gs_next_ids() */ |
43 | | |
44 | | /* These are fonts for which we have to ignore "named" encodings */ |
45 | | typedef struct pdfi_t1_glyph_name_equivalents_s |
46 | | { |
47 | | const char *name; |
48 | | const char *altname; |
49 | | } pdfi_t1_glyph_name_equivalents_t; |
50 | | |
51 | | static const pdfi_t1_glyph_name_equivalents_t pdfi_t1_glyph_name_equivalents[] = |
52 | | { |
53 | | {"Ohungarumlaut", "Odblacute"}, |
54 | | {"Uhungarumlaut", "Udblacute"}, |
55 | | {"ohungarumlaut", "odblacute"}, |
56 | | {"uhungarumlaut", "udblacute"}, |
57 | | {NULL , NULL} |
58 | | }; |
59 | | |
60 | | /* The Postscript code trawls the AGL to find all the equivalents. |
61 | | let's hope we can avoid that... |
62 | | Since none of the following show be required for a remotely valid |
63 | | Type 1, we just ignore errors (at least for now). |
64 | | */ |
65 | | static void pdfi_patch_charstrings_dict(pdf_dict *cstrings) |
66 | 59.0k | { |
67 | 59.0k | int code = 0; |
68 | 59.0k | pdf_obj *o; |
69 | 59.0k | const pdfi_t1_glyph_name_equivalents_t *gne = pdfi_t1_glyph_name_equivalents; |
70 | 295k | while(gne->name != NULL && code >= 0) { |
71 | 236k | code = pdfi_dict_get(cstrings->ctx, cstrings, gne->name, &o); |
72 | 236k | if (code >= 0) { |
73 | 190k | code = pdfi_dict_put(cstrings->ctx, cstrings, gne->altname, o); |
74 | 190k | pdfi_countdown(o); |
75 | 190k | } |
76 | 236k | if (code == gs_error_undefined) |
77 | 45.8k | code = 0; |
78 | 236k | gne++; |
79 | 236k | } |
80 | | |
81 | 59.0k | if (code >= 0) { |
82 | 59.0k | bool key_known; |
83 | 59.0k | pdf_string *pstr; |
84 | 59.0k | byte notdefstr[] = { 0x9E, 0x35, 0xCE, 0xD7, 0xFF, 0xD3, 0x62, 0x2F, 0x09 }; |
85 | | |
86 | 59.0k | code = pdfi_dict_known(cstrings->ctx, cstrings, ".notdef", &key_known); |
87 | 59.0k | if (code >=0 && key_known != true) { |
88 | | /* Seems there are plently of invalid Type 1 fonts without a .notdef, |
89 | | so make a fake one - a valid font will end up replacing this. |
90 | | */ |
91 | 1.80k | code = pdfi_object_alloc(cstrings->ctx, PDF_STRING, sizeof(notdefstr), (pdf_obj **) &pstr); |
92 | 1.80k | if (code >= 0) { |
93 | 1.80k | memcpy(pstr->data, notdefstr, sizeof(notdefstr)); |
94 | 1.80k | (void)pdfi_dict_put(cstrings->ctx, cstrings, ".notdef", (pdf_obj *) pstr); |
95 | 1.80k | } |
96 | 1.80k | } |
97 | 59.0k | } |
98 | 59.0k | } |
99 | | |
100 | | /* CALLBACKS */ |
101 | | static int |
102 | | pdfi_t1_glyph_data(gs_font_type1 *pfont, gs_glyph glyph, gs_glyph_data_t *pgd) |
103 | 87.4M | { |
104 | 87.4M | int code = 0; |
105 | 87.4M | pdf_font_type1 *pdffont1 = (pdf_font_type1 *) pfont->client_data; |
106 | 87.4M | pdf_context *ctx = (pdf_context *) pdffont1->ctx; |
107 | 87.4M | pdf_name *glyphname = NULL; |
108 | 87.4M | pdf_string *charstring = NULL; |
109 | 87.4M | gs_const_string gname; |
110 | | |
111 | 87.4M | code = (*ctx->get_glyph_name)((gs_font *)pfont, glyph, &gname); |
112 | 87.4M | if (code >= 0) { |
113 | 87.4M | code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **)&glyphname); |
114 | 87.4M | if (code >= 0) |
115 | 87.4M | pdfi_countup(glyphname); |
116 | 87.4M | } |
117 | | |
118 | 87.4M | if (code >= 0) { |
119 | 87.4M | code = pdfi_dict_get_by_key(ctx, pdffont1->CharStrings, glyphname, (pdf_obj **)&charstring); |
120 | 87.4M | if (code < 0) { |
121 | 378k | code = pdfi_map_glyph_name_via_agl(pdffont1->CharStrings, glyphname, &charstring); |
122 | 378k | } |
123 | 87.4M | if (code >= 0) |
124 | 87.0M | gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); |
125 | 87.4M | } |
126 | 87.4M | pdfi_countdown(charstring); |
127 | 87.4M | pdfi_countdown(glyphname); |
128 | | |
129 | 87.4M | return code; |
130 | 87.4M | } |
131 | | |
132 | | static int |
133 | | pdfi_t1_subr_data(gs_font_type1 *pfont, int index, bool global, gs_glyph_data_t *pgd) |
134 | 40.4M | { |
135 | 40.4M | int code = 0; |
136 | 40.4M | pdf_font_type1 *pdffont1 = (pdf_font_type1 *) pfont->client_data; |
137 | | |
138 | 40.4M | if (global == true || index < 0 || index >= (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) { |
139 | 485k | code = gs_note_error(gs_error_rangecheck); |
140 | 485k | } |
141 | 39.9M | else { |
142 | 39.9M | pdf_string *subr_str = NULL; |
143 | 39.9M | code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str); |
144 | 39.9M | if (code >= 0) { |
145 | 39.9M | gs_glyph_data_from_bytes(pgd, subr_str->data, 0, subr_str->length, NULL); |
146 | 39.9M | } |
147 | | /* decrementing is safe here, because the reference in the pdffont1->Subrs will persist */ |
148 | 39.9M | pdfi_countdown(subr_str); |
149 | 39.9M | } |
150 | 40.4M | return code; |
151 | 40.4M | } |
152 | | |
153 | | static int |
154 | | pdfi_t1_seac_data(gs_font_type1 *pfont, int ccode, gs_glyph *pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd) |
155 | 5.81k | { |
156 | 5.81k | int code = 0; |
157 | 5.81k | pdf_font_type1 *pdffont1 = (pdf_font_type1 *) pfont->client_data; |
158 | 5.81k | pdf_context *ctx = (pdf_context *) pdffont1->ctx; |
159 | 5.81k | gs_glyph glyph = gs_c_known_encode((gs_char)ccode, ENCODING_INDEX_STANDARD); |
160 | | |
161 | 5.81k | if (glyph == GS_NO_GLYPH) |
162 | 40 | return_error(gs_error_rangecheck); |
163 | | |
164 | 5.77k | code = gs_c_glyph_name(glyph, gstr); |
165 | 5.77k | if (code >= 0) { |
166 | 5.77k | unsigned int nindex; |
167 | 5.77k | code = (*ctx->get_glyph_index)((gs_font *)pfont, (byte *)gstr->data, gstr->size, &nindex); |
168 | 5.77k | if (pglyph != NULL) |
169 | 5.77k | *pglyph = (gs_glyph)nindex; |
170 | 5.77k | } |
171 | | |
172 | 5.77k | if (code >= 0) { |
173 | 5.77k | pdf_name *glyphname = NULL; |
174 | 5.77k | pdf_string *charstring = NULL; |
175 | 5.77k | code = pdfi_name_alloc(ctx, (byte *) gstr->data, gstr->size, (pdf_obj **) &glyphname); |
176 | 5.77k | if (code >= 0) { |
177 | 5.77k | pdfi_countup(glyphname); |
178 | 5.77k | code = pdfi_dict_get_by_key(ctx, pdffont1->CharStrings, glyphname, (pdf_obj **)&charstring); |
179 | 5.77k | pdfi_countdown(glyphname); |
180 | 5.77k | if (code >= 0) { |
181 | 5.76k | if (pgd != NULL) { |
182 | 0 | gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); |
183 | 0 | } |
184 | 5.76k | pdfi_countdown(charstring); |
185 | 5.76k | } |
186 | 5.77k | } |
187 | 5.77k | } |
188 | | |
189 | 5.77k | return code; |
190 | 5.81k | } |
191 | | |
192 | | /* push/pop are null ops here */ |
193 | | static int |
194 | | pdfi_t1_push(void *callback_data, const fixed *pf, int count) |
195 | 0 | { |
196 | 0 | (void)callback_data; |
197 | 0 | (void)pf; |
198 | 0 | (void)count; |
199 | 0 | return 0; |
200 | 0 | } |
201 | | static int |
202 | | pdfi_t1_pop(void *callback_data, fixed *pf) |
203 | 0 | { |
204 | 0 | (void)callback_data; |
205 | 0 | (void)pf; |
206 | 0 | return 0; |
207 | 0 | } |
208 | | |
209 | | static int |
210 | | pdfi_t1_enumerate_glyph(gs_font *pfont, int *pindex, |
211 | | gs_glyph_space_t glyph_space, gs_glyph *pglyph) |
212 | 97.4M | { |
213 | 97.4M | int code; |
214 | 97.4M | pdf_font_type1 *t1font = (pdf_font_type1 *) pfont->client_data; |
215 | 97.4M | pdf_context *ctx = (pdf_context *) t1font->ctx; |
216 | 97.4M | pdf_name *key; |
217 | 97.4M | uint64_t i = (uint64_t) *pindex; |
218 | | |
219 | 97.4M | (void)glyph_space; |
220 | | |
221 | 97.4M | if (*pindex <= 0) |
222 | 564k | code = pdfi_dict_key_first(ctx, t1font->CharStrings, (pdf_obj **) & key, &i); |
223 | 96.9M | else |
224 | 96.9M | code = pdfi_dict_key_next(ctx, t1font->CharStrings, (pdf_obj **) & key, &i); |
225 | 97.4M | if (code < 0) { |
226 | 108k | *pindex = 0; |
227 | 108k | code = 0; |
228 | 108k | } |
229 | 97.3M | else { |
230 | 97.3M | uint dummy = GS_NO_GLYPH; |
231 | | |
232 | 97.3M | code = (*ctx->get_glyph_index)(pfont, key->data, key->length, &dummy); |
233 | 97.3M | if (code < 0) { |
234 | 0 | *pglyph = (gs_glyph) *pindex; |
235 | 0 | goto exit; |
236 | 0 | } |
237 | 97.3M | *pglyph = dummy; |
238 | 97.3M | if (*pglyph == GS_NO_GLYPH) |
239 | 0 | *pglyph = (gs_glyph) *pindex; |
240 | 97.3M | *pindex = (int)i; |
241 | 97.3M | } |
242 | 97.4M | exit: |
243 | 97.4M | pdfi_countdown(key); |
244 | 97.4M | return code; |
245 | 97.4M | } |
246 | | |
247 | | /* This *should* only get called for SEAC lookups, which have to come from StandardEncoding |
248 | | so just try to lookup the string in the standard encodings |
249 | | */ |
250 | | int |
251 | | pdfi_t1_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph) |
252 | 1 | { |
253 | 1 | *pglyph = gs_c_name_glyph(gstr->data, gstr->size); |
254 | 1 | return 0; |
255 | 1 | } |
256 | | |
257 | | static int |
258 | | pdfi_t1_glyph_outline(gs_font *pfont, int WMode, gs_glyph glyph, |
259 | | const gs_matrix *pmat, gx_path *ppath, double sbw[4]) |
260 | 1.51M | { |
261 | 1.51M | gs_glyph_data_t gd; |
262 | 1.51M | gs_glyph_data_t *pgd = &gd; |
263 | 1.51M | gs_font_type1 *pfont1 = (gs_font_type1 *) pfont; |
264 | 1.51M | int code = pdfi_t1_glyph_data(pfont1, glyph, pgd); |
265 | | |
266 | 1.51M | if (code >= 0) { |
267 | 1.50M | gs_type1_state cis = { 0 }; |
268 | 1.50M | gs_type1_state *pcis = &cis; |
269 | 1.50M | gs_gstate gs; |
270 | 1.50M | int value; |
271 | | |
272 | 1.50M | if (pmat) |
273 | 1.50M | gs_matrix_fixed_from_matrix(&gs.ctm, pmat); |
274 | 603 | else { |
275 | 603 | gs_matrix imat; |
276 | | |
277 | 603 | gs_make_identity(&imat); |
278 | 603 | gs_matrix_fixed_from_matrix(&gs.ctm, &imat); |
279 | 603 | } |
280 | 1.50M | gs.flatness = 0; |
281 | 1.50M | code = gs_type1_interp_init(pcis, &gs, ppath, NULL, NULL, true, 0, pfont1); |
282 | 1.50M | if (code < 0) |
283 | 0 | return code; |
284 | | |
285 | 1.50M | pcis->no_grid_fitting = true; |
286 | 1.50M | gs_type1_set_callback_data(pcis, NULL); |
287 | | /* Continue interpreting. */ |
288 | 3.00M | icont: |
289 | 3.00M | code = pfont1->data.interpret(pcis, pgd, &value); |
290 | 3.00M | switch (code) { |
291 | 1.50M | case 0: /* all done */ |
292 | | /* falls through */ |
293 | 1.50M | default: /* code < 0, error */ |
294 | 1.50M | return code; |
295 | 0 | case type1_result_callothersubr: /* unknown OtherSubr */ |
296 | 0 | return_error(gs_error_rangecheck); /* can't handle it */ |
297 | 1.50M | case type1_result_sbw: /* [h]sbw, just continue */ |
298 | 1.50M | type1_cis_get_metrics(pcis, sbw); |
299 | 1.50M | pgd = 0; |
300 | 1.50M | goto icont; |
301 | 3.00M | } |
302 | 3.00M | } |
303 | 9.57k | return code; |
304 | 1.51M | } |
305 | | |
306 | | static int |
307 | | pdfi_t1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, int members, gs_glyph_info_t *info) |
308 | 64.2M | { |
309 | 64.2M | if ((members & GLYPH_INFO_OUTLINE_WIDTHS) == 0) |
310 | 62.7M | return gs_type1_glyph_info(font, glyph, pmat, members, info); |
311 | | |
312 | 1.51M | return gs_default_glyph_info(font, glyph, pmat, members, info); |
313 | 64.2M | } |
314 | | |
315 | | /* END CALLBACKS */ |
316 | | |
317 | | static stream * |
318 | | push_pfb_filter(gs_memory_t *mem, byte *buf, byte *bufend) |
319 | 344 | { |
320 | 344 | stream *fs, *ffs = NULL; |
321 | 344 | stream *sstrm; |
322 | 344 | stream_PFBD_state *st; |
323 | 344 | byte *strbuf; |
324 | | |
325 | 344 | sstrm = file_alloc_stream(mem, "push_pfb_filter(buf stream)"); |
326 | 344 | if (sstrm == NULL) |
327 | 0 | return NULL; |
328 | | |
329 | 344 | sread_string(sstrm, buf, bufend - buf); |
330 | 344 | sstrm->close_at_eod = false; |
331 | | |
332 | 344 | fs = s_alloc(mem, "push_pfb_filter(fs)"); |
333 | 344 | strbuf = gs_alloc_bytes(mem, 4096, "push_pfb_filter(buf)"); |
334 | 344 | st = gs_alloc_struct(mem, stream_PFBD_state, s_PFBD_template.stype, "push_pfb_filter(st)"); |
335 | 344 | if (fs == NULL || st == NULL || strbuf == NULL) { |
336 | 0 | sclose(sstrm); |
337 | 0 | gs_free_object(mem, sstrm, "push_pfb_filter(buf stream)"); |
338 | 0 | gs_free_object(mem, fs, "push_pfb_filter(fs)"); |
339 | 0 | gs_free_object(mem, st, "push_pfb_filter(st)"); |
340 | 0 | goto done; |
341 | 0 | } |
342 | 344 | memset(st, 0x00, sizeof(stream_PFBD_state)); |
343 | 344 | (*s_PFBD_template.init)((stream_state *)st); |
344 | 344 | st->binary_to_hex = true; |
345 | 344 | s_std_init(fs, strbuf, 4096, &s_filter_read_procs, s_mode_read); |
346 | 344 | st->memory = mem; |
347 | 344 | st->templat = &s_PFBD_template; |
348 | 344 | fs->state = (stream_state *) st; |
349 | 344 | fs->procs.process = s_PFBD_template.process; |
350 | 344 | fs->strm = sstrm; |
351 | 344 | fs->close_at_eod = false; |
352 | 344 | ffs = fs; |
353 | 344 | done: |
354 | 344 | return ffs; |
355 | 344 | } |
356 | | |
357 | | static void |
358 | | pop_pfb_filter(gs_memory_t *mem, stream *s) |
359 | 344 | { |
360 | 344 | stream *src = s->strm; |
361 | 344 | byte *b = s->cbuf; |
362 | | |
363 | 344 | sclose(s); |
364 | 344 | gs_free_object(mem, s, "push_pfb_filter(s)"); |
365 | 344 | gs_free_object(mem, b, "push_pfb_filter(b)"); |
366 | 344 | if (src) |
367 | 344 | sclose(src); |
368 | 344 | gs_free_object(mem, src, "push_pfb_filter(strm)"); |
369 | 344 | } |
370 | | |
371 | | static int |
372 | | pdfi_t1_decode_pfb(pdf_context *ctx, byte *inbuf, int inlen, byte **outbuf, int *outlen) |
373 | 172 | { |
374 | 172 | stream *strm; |
375 | 172 | int c, code = 0; |
376 | 172 | int decodelen = 0; |
377 | 172 | byte *d, *decodebuf = NULL; |
378 | | |
379 | 172 | *outbuf = NULL; |
380 | 172 | *outlen = 0; |
381 | | |
382 | 172 | strm = push_pfb_filter(ctx->memory, inbuf, inbuf + inlen); |
383 | 172 | if (strm == NULL) { |
384 | 0 | code = gs_note_error(gs_error_VMerror); |
385 | 0 | } |
386 | 172 | else { |
387 | 4.17M | while (1) { |
388 | 4.17M | c = sgetc(strm); |
389 | 4.17M | if (c < 0) |
390 | 172 | break; |
391 | 4.17M | decodelen++; |
392 | 4.17M | } |
393 | 172 | pop_pfb_filter(ctx->memory, strm); |
394 | 172 | decodebuf = gs_alloc_bytes(ctx->memory, decodelen, "pdfi_t1_decode_pfb(decodebuf)"); |
395 | 172 | if (decodebuf == NULL) { |
396 | 0 | code = gs_note_error(gs_error_VMerror); |
397 | 0 | } |
398 | 172 | else { |
399 | 172 | d = decodebuf; |
400 | 172 | strm = push_pfb_filter(ctx->memory, inbuf, inbuf + inlen); |
401 | 4.17M | while (1) { |
402 | 4.17M | c = sgetc(strm); |
403 | 4.17M | if (c < 0) |
404 | 172 | break; |
405 | 4.17M | *d = c; |
406 | 4.17M | d++; |
407 | 4.17M | } |
408 | 172 | pop_pfb_filter(ctx->memory, strm); |
409 | 172 | *outbuf = decodebuf; |
410 | 172 | *outlen = decodelen; |
411 | 172 | } |
412 | 172 | } |
413 | 172 | return code; |
414 | 172 | } |
415 | | |
416 | | static int |
417 | | pdfi_alloc_t1_font(pdf_context *ctx, pdf_font_type1 **font, uint32_t obj_num) |
418 | 908k | { |
419 | 908k | pdf_font_type1 *t1font = NULL; |
420 | 908k | gs_font_type1 *pfont = NULL; |
421 | | |
422 | 908k | t1font = (pdf_font_type1 *) gs_alloc_bytes(ctx->memory, sizeof(pdf_font_type1), "pdfi (type 1 pdf_font)"); |
423 | 908k | if (t1font == NULL) |
424 | 0 | return_error(gs_error_VMerror); |
425 | | |
426 | 908k | memset(t1font, 0x00, sizeof(pdf_font_type1)); |
427 | 908k | t1font->ctx = ctx; |
428 | 908k | t1font->type = PDF_FONT; |
429 | 908k | t1font->ctx = ctx; |
430 | 908k | t1font->pdfi_font_type = e_pdf_font_type1; |
431 | | |
432 | | #if REFCNT_DEBUG |
433 | | t1font->UID = ctx->UID++; |
434 | | outprintf(ctx->memory, "Allocated object of type %c with UID %" PRIi64 "\n", t1font->type, t1font->UID); |
435 | | #endif |
436 | | |
437 | 908k | pdfi_countup(t1font); |
438 | | |
439 | 908k | pfont = (gs_font_type1 *) gs_alloc_struct(ctx->memory, gs_font_type1, &st_gs_font_type1, "pdfi (Type 1 pfont)"); |
440 | 908k | if (pfont == NULL) { |
441 | 0 | pdfi_countdown(t1font); |
442 | 0 | return_error(gs_error_VMerror); |
443 | 0 | } |
444 | 908k | memset(pfont, 0x00, sizeof(gs_font_type1)); |
445 | | |
446 | 908k | t1font->pfont = (gs_font_base *) pfont; |
447 | | |
448 | 908k | gs_make_identity(&pfont->orig_FontMatrix); |
449 | 908k | gs_make_identity(&pfont->FontMatrix); |
450 | 908k | pfont->next = pfont->prev = 0; |
451 | 908k | pfont->memory = ctx->memory; |
452 | 908k | pfont->dir = ctx->font_dir; |
453 | 908k | pfont->is_resource = false; |
454 | 908k | gs_notify_init(&pfont->notify_list, ctx->memory); |
455 | 908k | pfont->base = (gs_font *) t1font->pfont; |
456 | 908k | pfont->client_data = t1font; |
457 | 908k | pfont->WMode = 0; |
458 | 908k | pfont->PaintType = 0; |
459 | 908k | pfont->StrokeWidth = 0; |
460 | 908k | pfont->is_cached = 0; |
461 | 908k | pfont->FAPI = NULL; |
462 | 908k | pfont->FAPI_font_data = NULL; |
463 | 908k | pfont->procs.init_fstack = gs_default_init_fstack; |
464 | 908k | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
465 | 908k | pfont->FontType = ft_encrypted; |
466 | 908k | pfont->ExactSize = fbit_use_outlines; |
467 | 908k | pfont->InBetweenSize = fbit_use_outlines; |
468 | 908k | pfont->TransformedChar = fbit_use_outlines; |
469 | | /* We may want to do something clever with an XUID here */ |
470 | 908k | pfont->id = gs_next_ids(ctx->memory, 1); |
471 | 908k | uid_set_UniqueID(&pfont->UID, pfont->id); |
472 | | |
473 | 908k | pfont->encoding_index = ENCODING_INDEX_UNKNOWN; |
474 | 908k | pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN; |
475 | | |
476 | 908k | pfont->client_data = (void *)t1font; |
477 | | |
478 | 908k | *font = t1font; |
479 | 908k | return 0; |
480 | 908k | } |
481 | | |
482 | | static void |
483 | | pdfi_t1_font_set_procs(pdf_context *ctx, pdf_font_type1 *font) |
484 | 59.0k | { |
485 | 59.0k | gs_font_type1 *pfont = (gs_font_type1 *) font->pfont; |
486 | | |
487 | | /* The build_char proc will be filled in by FAPI - |
488 | | we won't worry about working without FAPI */ |
489 | 59.0k | pfont->procs.build_char = NULL; |
490 | | |
491 | 59.0k | pfont->procs.encode_char = pdfi_encode_char; |
492 | 59.0k | pfont->procs.glyph_name = ctx->get_glyph_name; |
493 | 59.0k | pfont->procs.decode_glyph = pdfi_decode_glyph; |
494 | 59.0k | pfont->procs.define_font = gs_no_define_font; |
495 | 59.0k | pfont->procs.make_font = gs_no_make_font; |
496 | | |
497 | 59.0k | font->default_font_info = gs_default_font_info; |
498 | 59.0k | pfont->procs.font_info = pdfi_default_font_info; |
499 | | |
500 | 59.0k | pfont->procs.glyph_info = pdfi_t1_glyph_info; |
501 | 59.0k | pfont->procs.glyph_outline = pdfi_t1_glyph_outline; |
502 | 59.0k | pfont->procs.same_font = gs_default_same_font; |
503 | 59.0k | pfont->procs.enumerate_glyph = pdfi_t1_enumerate_glyph; |
504 | | |
505 | 59.0k | pfont->data.procs.glyph_data = pdfi_t1_glyph_data; |
506 | 59.0k | pfont->data.procs.subr_data = pdfi_t1_subr_data; |
507 | 59.0k | pfont->data.procs.seac_data = pdfi_t1_seac_data; |
508 | 59.0k | pfont->data.procs.push_values = pdfi_t1_push; |
509 | 59.0k | pfont->data.procs.pop_value = pdfi_t1_pop; |
510 | 59.0k | pfont->data.interpret = gs_type1_interpret; |
511 | 59.0k | } |
512 | | |
513 | | static inline void |
514 | | pdfi_type1_font_priv_defaults(ps_font_interp_private *pfpriv) |
515 | 65.7k | { |
516 | 65.7k | pfpriv->gsu.gst1.data.lenIV = 4; |
517 | 65.7k | pfpriv->gsu.gst1.data.ExpansionFactor = 0.06; |
518 | 65.7k | pfpriv->gsu.gst1.data.BlueShift = 7; |
519 | 65.7k | pfpriv->gsu.gst1.data.BlueFuzz = 1; |
520 | 65.7k | pfpriv->gsu.gst1.data.BlueScale = 0.039625; |
521 | 65.7k | uid_set_invalid(&pfpriv->gsu.gst1.UID); |
522 | 65.7k | } |
523 | | |
524 | | int |
525 | | 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) |
526 | 65.7k | { |
527 | 65.7k | int code = 0; |
528 | 65.7k | double x_scale; |
529 | 65.7k | pdf_obj *fontdesc = NULL; |
530 | 65.7k | pdf_obj *basefont = NULL; |
531 | 65.7k | pdf_obj *mapname = NULL; |
532 | 65.7k | pdf_obj *tmp = NULL; |
533 | 65.7k | pdf_font_type1 *t1f = NULL; |
534 | 65.7k | pdf_obj *tounicode = NULL; |
535 | 65.7k | ps_font_interp_private fpriv = { 0 }; |
536 | 65.7k | bool key_known; |
537 | 65.7k | bool force_symbolic = false; |
538 | | |
539 | 65.7k | if (font_dict != NULL) |
540 | 17.0k | (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
541 | | |
542 | 65.7k | if (fbuf[0] == 128 && fbuf[1] == 1) { |
543 | 172 | byte *decodebuf = NULL; |
544 | 172 | int decodelen; |
545 | | |
546 | 172 | code = pdfi_t1_decode_pfb(ctx, fbuf, fbuflen, &decodebuf, &decodelen); |
547 | 172 | gs_free_object(ctx->memory, fbuf, "pdfi_read_type1_font"); |
548 | 172 | if (code < 0) { |
549 | 0 | gs_free_object(ctx->memory, decodebuf, "pdfi_read_type1_font"); |
550 | 0 | } |
551 | 172 | fbuf = decodebuf; |
552 | 172 | fbuflen = decodelen; |
553 | 172 | } |
554 | | |
555 | 65.7k | if (code >= 0) { |
556 | 65.7k | pdfi_type1_font_priv_defaults(&fpriv); |
557 | 65.7k | code = pdfi_read_ps_font(ctx, font_dict, fbuf, fbuflen, &fpriv); |
558 | 65.7k | gs_free_object(ctx->memory, fbuf, "pdfi_read_type1_font"); |
559 | | |
560 | | /* If we have a full CharStrings dictionary, we probably have enough to make a font */ |
561 | 65.7k | if (code < 0 || fpriv.u.t1.CharStrings == NULL || pdfi_type_of(fpriv.u.t1.CharStrings) != PDF_DICT |
562 | 65.7k | || fpriv.u.t1.CharStrings->entries == 0) { |
563 | 6.69k | code = gs_note_error(gs_error_invalidfont); |
564 | 6.69k | goto error; |
565 | 6.69k | } |
566 | 59.0k | code = pdfi_alloc_t1_font(ctx, &t1f, font_dict != NULL ? font_dict->object_num : 0); |
567 | 59.0k | if (code >= 0) { |
568 | 59.0k | gs_font_type1 *pfont1 = (gs_font_type1 *) t1f->pfont; |
569 | | |
570 | 59.0k | memcpy(&pfont1->data, &fpriv.gsu.gst1.data, sizeof(pfont1->data)); |
571 | | |
572 | 59.0k | pdfi_t1_font_set_procs(ctx, t1f); |
573 | | |
574 | 59.0k | memcpy(&pfont1->FontMatrix, &fpriv.gsu.gst1.FontMatrix, sizeof(pfont1->FontMatrix)); |
575 | 59.0k | memcpy(&pfont1->orig_FontMatrix, &fpriv.gsu.gst1.orig_FontMatrix, sizeof(pfont1->orig_FontMatrix)); |
576 | 59.0k | memcpy(&pfont1->FontBBox, &fpriv.gsu.gst1.FontBBox, sizeof(pfont1->FontBBox)); |
577 | 59.0k | memcpy(&pfont1->key_name, &fpriv.gsu.gst1.key_name, sizeof(pfont1->key_name)); |
578 | 59.0k | memcpy(&pfont1->font_name, &fpriv.gsu.gst1.font_name, sizeof(pfont1->font_name)); |
579 | 59.0k | if (fpriv.gsu.gst1.UID.id != 0) |
580 | 59.0k | memcpy(&pfont1->UID, &fpriv.gsu.gst1.UID, sizeof(pfont1->UID)); |
581 | 59.0k | fpriv.gsu.gst1.UID.xvalues = NULL; /* In case of error */ |
582 | 59.0k | if (fpriv.gsu.gst1.WMode != 0) { |
583 | 0 | if (fpriv.gsu.gst1.WMode != 1) |
584 | 0 | pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_WMODE, "pdfi_read_type1_font", NULL); |
585 | 0 | pfont1->WMode = 1; |
586 | 0 | } |
587 | 59.0k | else |
588 | 59.0k | pfont1->WMode = 0; |
589 | 59.0k | pfont1->PaintType = fpriv.gsu.gst1.PaintType; |
590 | 59.0k | pfont1->StrokeWidth = fpriv.gsu.gst1.StrokeWidth; |
591 | | |
592 | 59.0k | if (font_dict != NULL) { |
593 | 10.3k | t1f->object_num = font_dict->object_num; |
594 | 10.3k | t1f->generation_num = font_dict->generation_num; |
595 | 10.3k | t1f->indirect_num = font_dict->indirect_num; |
596 | 10.3k | t1f->indirect_gen = font_dict->indirect_gen; |
597 | 10.3k | } |
598 | | |
599 | 59.0k | t1f->PDF_font = font_dict; |
600 | 59.0k | pdfi_countup(font_dict); |
601 | 59.0k | t1f->FontDescriptor = (pdf_dict *) fontdesc; |
602 | 59.0k | pdfi_countup(fontdesc); |
603 | 59.0k | t1f->Name = mapname; |
604 | 59.0k | pdfi_countup(mapname); |
605 | | |
606 | | /* We want basefont, but we can live without it */ |
607 | 59.0k | if (font_dict != NULL) { |
608 | 10.3k | (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont); |
609 | 10.3k | t1f->BaseFont = basefont; |
610 | 10.3k | pdfi_countup(basefont); |
611 | 10.3k | } |
612 | | |
613 | 59.0k | if (t1f->FontDescriptor != NULL) { |
614 | 10.3k | code = pdfi_dict_get_int(ctx, t1f->FontDescriptor, "Flags", &t1f->descflags); |
615 | 10.3k | if (code >= 0) { |
616 | | /* If both the symbolic and non-symbolic flag are set, |
617 | | believe that latter. |
618 | | */ |
619 | 10.3k | if ((t1f->descflags & 32) != 0) |
620 | 2.66k | t1f->descflags = (t1f->descflags & ~4); |
621 | 10.3k | } |
622 | 10.3k | } |
623 | | |
624 | 59.0k | if (pdfi_font_known_symbolic(basefont)) { |
625 | 41 | force_symbolic = true; |
626 | 41 | t1f->descflags |= 4; |
627 | 41 | } |
628 | | |
629 | 59.0k | if (ctx->args.ignoretounicode != true && font_dict != NULL) { |
630 | 10.3k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode); |
631 | 10.3k | if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) { |
632 | 892 | pdf_cmap *tu = NULL; |
633 | 892 | code = pdfi_read_cmap(ctx, tounicode, &tu); |
634 | 892 | pdfi_countdown(tounicode); |
635 | 892 | tounicode = (pdf_obj *)tu; |
636 | 892 | } |
637 | 10.3k | if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) { |
638 | 9.47k | pdfi_countdown(tounicode); |
639 | 9.47k | tounicode = NULL; |
640 | 9.47k | code = 0; |
641 | 9.47k | } |
642 | 10.3k | } |
643 | 48.6k | else { |
644 | 48.6k | tounicode = NULL; |
645 | 48.6k | } |
646 | 59.0k | t1f->ToUnicode = tounicode; |
647 | 59.0k | tounicode = NULL; |
648 | | |
649 | 59.0k | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)t1f); |
650 | | |
651 | | /* Widths are defined assuming a 1000x1000 design grid, but we apply |
652 | | * them in font space - so undo the 1000x1000 scaling, and apply |
653 | | * the inverse of the font's x scaling |
654 | | */ |
655 | 59.0k | x_scale = 0.001 / hypot(pfont1->FontMatrix.xx, pfont1->FontMatrix.xy); |
656 | | |
657 | | /* ignore errors with widths... for now */ |
658 | 59.0k | if (font_dict != NULL) |
659 | 10.3k | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)t1f, x_scale); |
660 | | |
661 | 59.0k | if (font_dict != NULL) |
662 | 10.3k | code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp); |
663 | 48.6k | else |
664 | 48.6k | code = gs_error_undefined; |
665 | 59.0k | if (code == 1) { |
666 | 8.78k | if (pdfi_type_of(tmp) == PDF_NAME && force_symbolic == true) { |
667 | 0 | t1f->Encoding = fpriv.u.t1.Encoding; |
668 | 0 | pdfi_countup(t1f->Encoding); |
669 | 0 | } |
670 | 8.78k | else if (pdfi_type_of(tmp) == PDF_DICT && (t1f->descflags & 4) != 0) { |
671 | 6.36k | code = pdfi_create_Encoding(ctx, (pdf_font *)t1f, tmp, (pdf_obj *)fpriv.u.t1.Encoding, (pdf_obj **) & t1f->Encoding); |
672 | 6.36k | if (code >= 0) |
673 | 6.36k | code = 1; |
674 | 6.36k | } |
675 | 2.41k | else { |
676 | 2.41k | code = pdfi_create_Encoding(ctx, (pdf_font *)t1f, tmp, NULL, (pdf_obj **) & t1f->Encoding); |
677 | 2.41k | if (code >= 0) |
678 | 2.38k | code = 1; |
679 | 2.41k | } |
680 | 8.78k | pdfi_countdown(tmp); |
681 | 8.78k | tmp = NULL; |
682 | 8.78k | } |
683 | 50.2k | else { |
684 | 50.2k | pdfi_countdown(tmp); |
685 | 50.2k | tmp = NULL; |
686 | 50.2k | code = 0; |
687 | 50.2k | } |
688 | | |
689 | 59.0k | if (code <= 0) { |
690 | 50.2k | t1f->Encoding = fpriv.u.t1.Encoding; |
691 | 50.2k | pdfi_countup(t1f->Encoding); |
692 | 50.2k | } |
693 | | /* Since the underlying font stream can be shared between font descriptors, |
694 | | and the font descriptors can be shared between font objects, if we change |
695 | | the encoding, we can't share cached glyphs with other instances of this |
696 | | underlying font, so invalidate the UniqueID/XUID so the glyph cache won't |
697 | | try. |
698 | | */ |
699 | 59.0k | if (uid_is_XUID(&t1f->pfont->UID)) |
700 | 59.0k | uid_free(&t1f->pfont->UID, t1f->pfont->memory, "pdfi_read_type1_font"); |
701 | 59.0k | uid_set_invalid(&t1f->pfont->UID); |
702 | | |
703 | 59.0k | t1f->CharStrings = fpriv.u.t1.CharStrings; |
704 | 59.0k | pdfi_countup(t1f->CharStrings); |
705 | 59.0k | pdfi_patch_charstrings_dict(t1f->CharStrings); |
706 | | |
707 | 59.0k | t1f->Subrs = fpriv.u.t1.Subrs; |
708 | 59.0k | fpriv.u.t1.Subrs = NULL; |
709 | | |
710 | 59.0k | t1f->copyright = fpriv.u.t1.copyright; |
711 | 59.0k | t1f->notice = fpriv.u.t1.notice; |
712 | 59.0k | t1f->fullname = fpriv.u.t1.fullname; |
713 | 59.0k | t1f->familyname = fpriv.u.t1.familyname; |
714 | 59.0k | fpriv.u.t1.copyright = fpriv.u.t1.notice = fpriv.u.t1.fullname = fpriv.u.t1.familyname = NULL; |
715 | | |
716 | 59.0k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, t1f->pfont); |
717 | 59.0k | if (code < 0) { |
718 | 0 | goto error; |
719 | 0 | } |
720 | | |
721 | 59.0k | t1f->blenddesignpositions = fpriv.u.t1.blenddesignpositions; |
722 | 59.0k | pdfi_countup(t1f->blenddesignpositions); |
723 | 59.0k | t1f->blenddesignmap = fpriv.u.t1.blenddesignmap; |
724 | 59.0k | pdfi_countup(t1f->blenddesignmap); |
725 | 59.0k | t1f->blendfontbbox = fpriv.u.t1.blendfontbbox; |
726 | 59.0k | pdfi_countup(t1f->blendfontbbox); |
727 | 59.0k | t1f->blendaxistypes = fpriv.u.t1.blendaxistypes; |
728 | 59.0k | pdfi_countup(t1f->blendaxistypes); |
729 | | |
730 | 59.0k | key_known = false; |
731 | 59.0k | if (t1f->FontDescriptor != NULL) { |
732 | 10.3k | code = pdfi_dict_known(ctx, t1f->FontDescriptor, "FontFile", &key_known); |
733 | 10.3k | if (code < 0 || key_known == false) { |
734 | 257 | code = pdfi_dict_known(ctx, t1f->FontDescriptor, "FontFile2", &key_known); |
735 | 257 | if (code < 0 || key_known == false) { |
736 | 0 | code = pdfi_dict_known(ctx, t1f->FontDescriptor, "FontFile3", &key_known); |
737 | 0 | if (code < 0) { |
738 | 0 | key_known = false; |
739 | 0 | } |
740 | 0 | } |
741 | 257 | } |
742 | 10.3k | } |
743 | 59.0k | t1f->pfont->is_resource = (key_known == false); |
744 | | |
745 | 59.0k | pdfi_font_set_orig_fonttype(ctx, (pdf_font *)t1f); |
746 | 59.0k | code = gs_definefont(ctx->font_dir, (gs_font *) t1f->pfont); |
747 | 59.0k | if (code < 0) { |
748 | 0 | goto error; |
749 | 0 | } |
750 | | |
751 | 59.0k | code = pdfi_fapi_passfont((pdf_font *) t1f, 0, NULL, NULL, NULL, 0); |
752 | 59.0k | if (code < 0) { |
753 | 0 | goto error; |
754 | 0 | } |
755 | | /* object_num can be zero if the dictionary was defined inline */ |
756 | 59.0k | if (t1f->object_num != 0) { |
757 | 10.1k | (void)replace_cache_entry(ctx, (pdf_obj *) t1f); |
758 | 10.1k | } |
759 | 59.0k | *ppdffont = (pdf_font *) t1f; |
760 | 59.0k | } |
761 | 59.0k | } |
762 | | |
763 | 65.7k | error: |
764 | 65.7k | pdfi_countdown(fontdesc); |
765 | 65.7k | pdfi_countdown(basefont); |
766 | 65.7k | pdfi_countdown(tounicode); |
767 | 65.7k | pdfi_countdown(mapname); |
768 | 65.7k | pdfi_countdown(tmp); |
769 | 65.7k | pdfi_countdown(fpriv.u.t1.Encoding); |
770 | 65.7k | pdfi_countdown(fpriv.u.t1.CharStrings); |
771 | 65.7k | pdfi_countdown(fpriv.u.t1.blenddesignpositions); |
772 | 65.7k | pdfi_countdown(fpriv.u.t1.blenddesignmap); |
773 | 65.7k | pdfi_countdown(fpriv.u.t1.blendfontbbox); |
774 | 65.7k | pdfi_countdown(fpriv.u.t1.blendaxistypes); |
775 | 65.7k | pdfi_countdown(fpriv.u.t1.Subrs); |
776 | 65.7k | pdfi_countdown(fpriv.u.t1.copyright); |
777 | 65.7k | pdfi_countdown(fpriv.u.t1.notice); |
778 | 65.7k | pdfi_countdown(fpriv.u.t1.fullname); |
779 | 65.7k | pdfi_countdown(fpriv.u.t1.familyname); |
780 | 65.7k | if (fpriv.gsu.gst1.UID.xvalues != NULL) { |
781 | 0 | gs_free_object(ctx->memory, fpriv.gsu.gst1.UID.xvalues, "pdfi_read_type1_font(xuid)"); |
782 | 0 | } |
783 | | |
784 | 65.7k | if (code < 0) { |
785 | 6.69k | tmp = NULL; |
786 | 6.69k | if (font_dict != NULL) { |
787 | 6.69k | if (pdfi_dict_get(ctx, font_dict, ".Path", &tmp) >= 0) |
788 | 0 | { |
789 | 0 | char fname[gp_file_name_sizeof + 1]; |
790 | 0 | pdf_string *fobj = (pdf_string *)tmp; |
791 | |
|
792 | 0 | memcpy(fname, fobj->data, fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length); |
793 | 0 | fname[fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length] = '\0'; |
794 | |
|
795 | 0 | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_type1_font", "Error reading Type 1 font file %s\n", fname); |
796 | 0 | } |
797 | 6.69k | else { |
798 | 6.69k | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_type1_font", "Error reading embedded Type 1 font object %u\n", font_dict->object_num); |
799 | 6.69k | } |
800 | 6.69k | } |
801 | 0 | else { |
802 | 0 | pdfi_set_error(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_truetype_font", "Error reading font\n"); |
803 | 0 | } |
804 | 6.69k | pdfi_countdown(tmp); |
805 | 6.69k | pdfi_countdown(t1f); |
806 | 6.69k | } |
807 | 65.7k | return code; |
808 | 65.7k | } |
809 | | |
810 | | int |
811 | | pdfi_copy_type1_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont) |
812 | 849k | { |
813 | 849k | int code = 0; |
814 | 849k | pdf_font_type1 *font = NULL; |
815 | 849k | gs_font_type1 *spfont1 = (gs_font_type1 *) spdffont->pfont; |
816 | 849k | gs_font_type1 *dpfont1; |
817 | 849k | gs_id t_id; |
818 | 849k | pdf_obj *tmp; |
819 | 849k | bool force_symbolic = false; |
820 | | |
821 | 849k | if (font_dict == NULL) |
822 | 0 | return_error(gs_error_invalidfont); |
823 | | |
824 | 849k | code = pdfi_alloc_t1_font(ctx, &font, font_dict->object_num); |
825 | 849k | if (code < 0) |
826 | 0 | return code; |
827 | 849k | dpfont1 = (gs_font_type1 *) font->pfont; |
828 | | |
829 | 849k | t_id = dpfont1->id; |
830 | 849k | memcpy(dpfont1, spfont1, sizeof(gs_font_type1)); |
831 | 849k | dpfont1->id = t_id; |
832 | 849k | dpfont1->FAPI = NULL; |
833 | 849k | dpfont1->FAPI_font_data = NULL; |
834 | | |
835 | 849k | memcpy(font, spdffont, sizeof(pdf_font_type1)); |
836 | 849k | font->pfont = (gs_font_base *)dpfont1; |
837 | 849k | font->refcnt = 1; |
838 | 849k | dpfont1->client_data = (void *)font; |
839 | 849k | font->filename = NULL; |
840 | | |
841 | 849k | dpfont1->notify_list.memory = NULL; |
842 | 849k | dpfont1->notify_list.first = NULL; |
843 | 849k | gs_notify_init(&dpfont1->notify_list, dpfont1->memory); |
844 | | |
845 | 849k | font->PDF_font = font_dict; |
846 | 849k | font->object_num = font_dict->object_num; |
847 | 849k | font->generation_num = font_dict->generation_num; |
848 | 849k | pdfi_countup(font->PDF_font); |
849 | | |
850 | | /* We want basefont and descriptor, but we can live without them */ |
851 | 849k | font->BaseFont = NULL; |
852 | 849k | code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont); |
853 | 849k | if (code < 0) { |
854 | 194 | pdfi_countdown(font->BaseFont); |
855 | 194 | font->BaseFont = NULL; |
856 | 194 | } |
857 | 849k | font->FontDescriptor = NULL; |
858 | 849k | code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor); |
859 | 849k | if (code < 0) { |
860 | 5.82k | pdfi_countdown(font->FontDescriptor); |
861 | 5.82k | font->FontDescriptor = NULL; |
862 | 5.82k | } |
863 | | |
864 | 849k | pdfi_countup(font->Name); |
865 | 849k | pdfi_countup(font->CharStrings); |
866 | 849k | pdfi_countup(font->blenddesignpositions); |
867 | 849k | pdfi_countup(font->blenddesignmap); |
868 | 849k | pdfi_countup(font->blendfontbbox); |
869 | 849k | pdfi_countup(font->blendaxistypes); |
870 | 849k | pdfi_countup(font->Subrs); |
871 | 849k | pdfi_countup(font->copyright); |
872 | 849k | pdfi_countup(font->notice); |
873 | 849k | pdfi_countup(font->fullname); |
874 | 849k | pdfi_countup(font->familyname); |
875 | | |
876 | 849k | if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max - 1) { |
877 | 848k | memcpy(dpfont1->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
878 | 848k | dpfont1->key_name.size = ((pdf_name *)font->BaseFont)->length; |
879 | 848k | dpfont1->key_name.chars[dpfont1->key_name.size] = '\0'; |
880 | 848k | memcpy(dpfont1->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
881 | 848k | dpfont1->font_name.size = ((pdf_name *)font->BaseFont)->length; |
882 | 848k | dpfont1->font_name.chars[dpfont1->font_name.size] = '\0'; |
883 | 848k | } |
884 | | |
885 | 849k | font->Encoding = NULL; |
886 | 849k | font->ToUnicode = NULL; |
887 | 849k | font->Widths = NULL; |
888 | | |
889 | 849k | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font); |
890 | 849k | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font *)font, (double)(0.001 / hypot(dpfont1->FontMatrix.xx, dpfont1->FontMatrix.xy))); |
891 | | |
892 | 849k | font->descflags = 0; |
893 | 849k | if (font->FontDescriptor != NULL) { |
894 | 30.0k | code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags); |
895 | 30.0k | if (code >= 0) { |
896 | | /* If both the symbolic and non-symbolic flag are set, |
897 | | believe that latter. |
898 | | */ |
899 | 29.9k | if ((font->descflags & 32) != 0) |
900 | 20.8k | font->descflags = (font->descflags & ~4); |
901 | 29.9k | } |
902 | 30.0k | } |
903 | | |
904 | 849k | if (pdfi_font_known_symbolic(font->BaseFont)) { |
905 | 1.44k | force_symbolic = true; |
906 | 1.44k | font->descflags |= 4; |
907 | 1.44k | } |
908 | | |
909 | 849k | tmp = NULL; |
910 | 849k | code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp); |
911 | 849k | if (code == 1) { |
912 | 39.7k | if (pdfi_type_of(tmp) == PDF_NAME && force_symbolic == true) { |
913 | 0 | font->Encoding = spdffont->Encoding; |
914 | 0 | pdfi_countup(font->Encoding); |
915 | 0 | } |
916 | 39.7k | else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) { |
917 | 4.14k | code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding); |
918 | 4.14k | if (code >= 0) |
919 | 4.14k | code = 1; |
920 | 4.14k | } |
921 | 35.6k | else { |
922 | 35.6k | code = pdfi_create_Encoding(ctx, (pdf_font *)font, tmp, NULL, (pdf_obj **) & font->Encoding); |
923 | 35.6k | if (code >= 0) |
924 | 34.8k | code = 1; |
925 | 35.6k | } |
926 | 39.7k | pdfi_countdown(tmp); |
927 | 39.7k | tmp = NULL; |
928 | 39.7k | } |
929 | 809k | else { |
930 | 809k | pdfi_countdown(tmp); |
931 | 809k | tmp = NULL; |
932 | 809k | code = 0; |
933 | 809k | } |
934 | | |
935 | 849k | if (code <= 0) { |
936 | 810k | font->Encoding = spdffont->Encoding; |
937 | 810k | pdfi_countup(font->Encoding); |
938 | 810k | } |
939 | | |
940 | 849k | code = uid_copy(&font->pfont->UID, font->pfont->memory, "pdfi_copy_type1_font"); |
941 | 849k | if (code < 0) { |
942 | 0 | uid_set_invalid(&font->pfont->UID); |
943 | 0 | } |
944 | 849k | if (spdffont->filename == NULL) { |
945 | 126 | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
946 | 126 | if (code < 0) { |
947 | 0 | goto error; |
948 | 0 | } |
949 | 126 | } |
950 | | |
951 | 849k | if (ctx->args.ignoretounicode != true) { |
952 | 849k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp); |
953 | 849k | if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) { |
954 | 8.26k | pdf_cmap *tu = NULL; |
955 | 8.26k | code = pdfi_read_cmap(ctx, tmp, &tu); |
956 | 8.26k | pdfi_countdown(tmp); |
957 | 8.26k | tmp = (pdf_obj *)tu; |
958 | 8.26k | } |
959 | 849k | if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) { |
960 | 841k | pdfi_countdown(tmp); |
961 | 841k | tmp = NULL; |
962 | 841k | code = 0; |
963 | 841k | } |
964 | 849k | } |
965 | 0 | else { |
966 | 0 | tmp = NULL; |
967 | 0 | } |
968 | 849k | font->ToUnicode = tmp; |
969 | | |
970 | 849k | pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font); |
971 | 849k | code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont); |
972 | 849k | if (code < 0) { |
973 | 0 | goto error; |
974 | 0 | } |
975 | | |
976 | 849k | code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0); |
977 | 849k | if (code < 0) { |
978 | 0 | goto error; |
979 | 0 | } |
980 | | /* object_num can be zero if the dictionary was defined inline */ |
981 | 849k | if (font->object_num != 0) { |
982 | 47.7k | (void)replace_cache_entry(ctx, (pdf_obj *) font); |
983 | 47.7k | } |
984 | | |
985 | 849k | *tpdffont = (pdf_font *)font; |
986 | | |
987 | 849k | error: |
988 | 849k | if (code < 0) |
989 | 0 | pdfi_countdown(font); |
990 | | |
991 | 849k | return code; |
992 | 849k | } |
993 | | |
994 | | int |
995 | | pdfi_free_font_type1(pdf_obj *font) |
996 | 908k | { |
997 | 908k | pdf_font_type1 *t1f = (pdf_font_type1 *) font; |
998 | | |
999 | 908k | gs_free_object(OBJ_MEMORY(font), t1f->pfont, "Free Type 1 gs_font"); |
1000 | | |
1001 | 908k | pdfi_countdown(t1f->PDF_font); |
1002 | 908k | pdfi_countdown(t1f->BaseFont); |
1003 | 908k | pdfi_countdown(t1f->FontDescriptor); |
1004 | 908k | pdfi_countdown(t1f->Name); |
1005 | 908k | pdfi_countdown(t1f->Encoding); |
1006 | 908k | pdfi_countdown(t1f->ToUnicode); |
1007 | 908k | pdfi_countdown(t1f->CharStrings); |
1008 | 908k | pdfi_countdown(t1f->blenddesignpositions); |
1009 | 908k | pdfi_countdown(t1f->blenddesignmap); |
1010 | 908k | pdfi_countdown(t1f->blendfontbbox); |
1011 | 908k | pdfi_countdown(t1f->blendaxistypes); |
1012 | 908k | pdfi_countdown(t1f->Subrs); |
1013 | 908k | pdfi_countdown(t1f->filename); |
1014 | 908k | pdfi_countdown(t1f->copyright); |
1015 | 908k | pdfi_countdown(t1f->notice); |
1016 | 908k | pdfi_countdown(t1f->fullname); |
1017 | 908k | pdfi_countdown(t1f->familyname); |
1018 | | |
1019 | 908k | gs_free_object(OBJ_MEMORY(font), t1f->Widths, "Free Type 1 fontWidths"); |
1020 | 908k | gs_free_object(OBJ_MEMORY(font), t1f, "Free Type 1 font"); |
1021 | 908k | return 0; |
1022 | 908k | } |